remerge tls-sprint
authorsylvain.thenault@logilab.fr
Fri, 24 Apr 2009 19:46:47 +0200
branchtls-sprint
changeset 1484 183da3addf0e
parent 1483 1367efbcd6a5 (diff)
parent 1479 b7494ff85e16 (current diff)
child 1485 4d532f3c012e
remerge
web/controller.py
--- a/__init__.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/__init__.py	Fri Apr 24 19:46:47 2009 +0200
@@ -212,16 +212,29 @@
         
 
 # XXX 2.45 is allowing nicer entity type names, use this map for bw compat    
-ETYPE_NAME_MAP = {'Eetype': 'EEType',
-                  'Ertype': 'ERType',
-                  'Efrdef': 'EFRDef',
-                  'Enfrdef': 'ENFRDef',
-                  'Econstraint': 'EConstraint',
-                  'Econstrainttype': 'EConstraintType',
-                  'Epermission': 'EPermission',
-                  'Egroup': 'EGroup',
-                  'Euser': 'EUser',
-                  'Eproperty': 'EProperty',
+ETYPE_NAME_MAP = {# 3.2 migration
+                  'ECache': 'CWCache',
+                  'EUser': 'CWUser',
+                  'EGroup': 'CWGroup',
+                  'EProperty': 'CWProperty',
+                  'EFRDef': 'CWAttribute',
+                  'ENFRDef': 'CWRelation',
+                  'ERType': 'CWRType',
+                  'EEType': 'CWEType',
+                  'EConstraintType': 'CWConstraintType',
+                  'EConstraint': 'CWConstraint',
+                  'EPermission': 'CWPermission',
+                   # 2.45 migration
+                  'Eetype': 'CWEType',
+                  'Ertype': 'CWRType',
+                  'Efrdef': 'CWAttribute',
+                  'Enfrdef': 'CWRelation',
+                  'Econstraint': 'CWConstraint',
+                  'Econstrainttype': 'CWConstraintType',
+                  'Epermission': 'CWPermission',
+                  'Egroup': 'CWGroup',
+                  'Euser': 'CWUser',
+                  'Eproperty': 'CWProperty',
                   'Emailaddress': 'EmailAddress',
                   'Rqlexpression': 'RQLExpression',
                   'Trinfo': 'TrInfo',
@@ -269,11 +282,6 @@
                     'agueol': 'agueol',
                     'docaster': 'docaster',
                     'asteretud': 'asteretud',
-                    
-                    # XXX temp
-                    'keywords': 'keyword',
-                    'folders': 'folder',
-                    'tags': 'tag',
                     }
 
 def neg_role(role):
--- a/__pkginfo__.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/__pkginfo__.py	Fri Apr 24 19:46:47 2009 +0200
@@ -6,7 +6,7 @@
 distname = "cubicweb"
 modname = "cubicweb"
 
-numversion = (3, 1, 4)
+numversion = (3, 2, 0)
 version = '.'.join(str(num) for num in numversion)
 
 license = 'LGPL v2'
--- a/appobject.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/appobject.py	Fri Apr 24 19:46:47 2009 +0200
@@ -77,7 +77,7 @@
         return cls(*args, **kwargs)
 
     # Eproperties definition:
-    # key: id of the property (the actual EProperty key is build using
+    # key: id of the property (the actual CWProperty key is build using
     #      <registry name>.<obj id>.<property id>
     # value: tuple (property type, vocabfunc, default value, property description)
     #        possible types are those used by `logilab.common.configuration`
@@ -132,7 +132,7 @@
             CACHE_REGISTRY[cachename] = cache
         _now = datetime.now()
         if _now > cache.latest_cache_lookup + ONESECOND:
-            ecache = self.req.execute('Any C,T WHERE C is ECache, C name %(name)s, C timestamp T', 
+            ecache = self.req.execute('Any C,T WHERE C is CWCache, C name %(name)s, C timestamp T', 
                                       {'name':cachename}).get_entity(0,0)
             cache.latest_cache_lookup = _now
             if not ecache.valid(cache.cache_creation_date):
--- a/common/mixins.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/common/mixins.py	Fri Apr 24 19:46:47 2009 +0200
@@ -26,10 +26,10 @@
     # XXX misnamed
     parent_target = 'subject'
     children_target = 'object'
-    
+
     def different_type_children(self, entities=True):
         """return children entities of different type as this entity.
-        
+
         according to the `entities` parameter, return entity objects or the
         equivalent result set
         """
@@ -41,7 +41,7 @@
 
     def same_type_children(self, entities=True):
         """return children entities of the same type as this entity.
-        
+
         according to the `entities` parameter, return entity objects or the
         equivalent result set
         """
@@ -50,7 +50,7 @@
         if entities:
             return [e for e in res if e.e_schema == self.e_schema]
         return res.filtered_rset(lambda x: x.e_schema == self.e_schema, self.col)
-    
+
     def iterchildren(self, _done=None):
         if _done is None:
             _done = set()
@@ -74,7 +74,7 @@
                     yield entity
             except AttributeError:
                 pass
-    
+
     @cached
     def path(self):
         """returns the list of eids from the root object to this object"""
@@ -96,7 +96,7 @@
 
         path.reverse()
         return path
-    
+
     def iterparents(self):
         def _uptoroot(self):
             curr = self
@@ -110,7 +110,7 @@
     def notification_references(self, view):
         """used to control References field of email send on notification
         for this entity. `view` is the notification view.
-        
+
         Should return a list of eids which can be used to generate message ids
         of previously sent email
         """
@@ -142,7 +142,7 @@
 
     def children_rql(self):
         return self.related_rql(self.tree_attribute, self.children_target)
-    
+
     def __iter__(self):
         return self.iterchildren()
 
@@ -163,7 +163,7 @@
     relation (which implies supporting 'wf_info_for' as well)
     """
     __implements__ = (IWorkflowable,)
-    
+
     @property
     def state(self):
         try:
@@ -171,7 +171,7 @@
         except IndexError:
             self.warning('entity %s has no state', self)
             return None
-    
+
     @property
     def displayable_state(self):
         return self.req._(self.state)
@@ -182,7 +182,7 @@
         if rset:
             return rset.get_entity(0, 0)
         return None
-    
+
     def wf_transition(self, trname):
         rset = self.req.execute('Any T, TN WHERE T name TN, T name %(n)s, T transition_of E, E name %(e)s',
                                 {'n': trname, 'e': str(self.e_schema)})
@@ -201,7 +201,7 @@
             self.req.set_shared_data('trcommentformat', trcommentformat)
         self.req.execute('SET X in_state S WHERE X eid %(x)s, S eid %(s)s',
                          {'x': self.eid, 's': stateeid}, 'x')
-    
+
     def can_pass_transition(self, trname):
         """return the Transition instance if the current user can pass the
         transition with the given name, else None
@@ -215,13 +215,13 @@
         for tr in rset.entities():
             if tr.may_be_passed(self.eid, stateeid):
                 return tr
-    
+
     def latest_trinfo(self):
         """return the latest transition information for this entity"""
         return self.reverse_wf_info_for[-1]
-            
+
     # __method methods ########################################################
-    
+
     def set_state(self, params=None):
         """change the entity's state according to a state defined in given
         parameters, used to be called using __method controler facility
@@ -231,9 +231,9 @@
                           params.get('trcomment'),
                           params.get('trcommentformat'))
         self.req.set_message(self.req._('__msg state changed'))
-            
+
     # specific vocabulary methods #############################################
-    
+
     @obsolete('use EntityFieldsForm.subject_in_state_vocabulary')
     def subject_in_state_vocabulary(self, rschema, limit=None):
         from cubicweb.web.form import EntityFieldsForm
@@ -249,7 +249,7 @@
     primary_email / use_email scheme
     """
     __implements__ = (IEmailable,)
-    
+
     def get_email(self):
         if getattr(self, 'primary_email', None):
             return self.primary_email[0].address
@@ -271,14 +271,14 @@
     def as_email_context(self):
         """returns the dictionary as used by the sendmail controller to
         build email bodies.
-        
+
         NOTE: the dictionary keys should match the list returned by the
         `allowed_massmail_keys` method.
         """
         return dict( (attr, getattr(self, attr)) for attr in self.allowed_massmail_keys() )
 
 
-    
+
 MI_REL_TRIGGERS = {
     ('in_state',    'subject'): WorkflowableMixIn,
     ('primary_email',   'subject'): EmailableMixIn,
@@ -312,7 +312,7 @@
         if done is None:
             done = set()
         super(TreeViewMixIn, self).call(done=done, **kwargs)
-            
+
     def cell_call(self, row, col=0, vid=None, done=None, **kwargs):
         done, entity = _done_init(done, self, row, col)
         if done is None:
@@ -341,7 +341,7 @@
         self.w(u'<div class="pathbar">')
         super(TreePathMixIn, self).call(**kwargs)
         self.w(u'</div>')
-        
+
     def cell_call(self, row, col=0, vid=None, done=None, **kwargs):
         done, entity = _done_init(done, self, row, col)
         if done is None:
@@ -383,7 +383,7 @@
 
     def in_progress(self):
         raise NotImplementedError()
-    
+
     def progress(self):
         try:
             return 100. * self.done / self.revised_cost
--- a/common/registerers.py	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-"""This file contains some basic registerers required by application objects
-registry to handle registration at startup time.
-
-A registerer is responsible to tell if an object should be registered according
-to the application's schema or to already registered object
-
-:organization: Logilab
-:copyright: 2006-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-"""
-__docformat__ = "restructuredtext en"
-
-from cubicweb.vregistry import registerer, yes_registerer
-from cubicweb.cwvreg import use_interfaces
-
-class priority_registerer(registerer):
-    """systematically kick previous registered class and register the
-    wrapped class (based on the fact that directory containing vobjects
-    are loaded from the most generic to the most specific).
-
-    This is usually for templates or startup views where we want to
-    keep only the latest in the load path
-    """
-    def do_it_yourself(self, registered):
-        if registered:
-            if len(registered) > 1:
-                self.warning('priority_registerer found more than one registered objects '
-                             '(registerer monkey patch ?)')
-            for regobj in registered[:]:
-                self.kick(registered, regobj)
-        return self.vobject
-    
-    def remove_equivalents(self, registered):
-        for _obj in registered[:]:
-            if self.equivalent(_obj):
-                self.kick(registered, _obj)
-                break
-            
-    def remove_all_equivalents(self, registered):
-        for _obj in registered[:]:
-            if _obj is self.vobject:
-                continue
-            if self.equivalent(_obj):
-                self.kick(registered, _obj)
-
-    def equivalent(self, other):
-        raise NotImplementedError(self, self.vobject)
-    
-
-class accepts_registerer(priority_registerer):
-    """register according to the .accepts attribute of the wrapped
-    class, which should be a tuple refering some entity's types
-
-    * if no type is defined the application'schema, skip the wrapped
-      class
-    * if the class defines a requires attribute, each entity type defined
-      in the requires list must be in the schema
-    * if an object previously registered has equivalent .accepts
-      attribute, kick it out
-    * register
-    """
-    def do_it_yourself(self, registered):
-        # if object is accepting interface, we have register it now and
-        # remove it later if no object is implementing accepted interfaces
-        if use_interfaces(self.vobject):
-            return self.vobject
-        self.remove_equivalents(registered)
-        return self.vobject
-    
-    def equivalent(self, other):
-        if use_interfaces(self.vobject) != use_interfaces(other):
-            return False
-        if getattr(self.vobject, 'require_groups', ()) != getattr(other, 'require_groups', ()):
-            return False
-        try:
-            newaccepts = list(other.accepts)
-            for etype in self.vobject.accepts:
-                try:
-                    newaccepts.remove(etype)
-                except ValueError:
-                    continue
-            if newaccepts:
-                other.accepts = tuple(newaccepts)
-                return False
-            return True
-        except AttributeError:
-            return False
-
-
-__all__ = [cls.__name__ for cls in globals().values()
-           if isinstance(cls, type) and issubclass(cls, registerer)
-           and not cls is registerer]
--- a/common/test/unittest_mixins.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/common/test/unittest_mixins.py	Fri Apr 24 19:46:47 2009 +0200
@@ -7,14 +7,14 @@
         self.execute('SET X state_of ET WHERE ET name "Bookmark", X eid %(x)s',
                      {'x': s.eid})
         es = self.user().wf_state('activated')
-        self.assertEquals(es.state_of[0].name, 'EUser')
+        self.assertEquals(es.state_of[0].name, 'CWUser')
         
     def test_wf_transition(self):
         t = self.add_entity('Transition', name=u'deactivate')
         self.execute('SET X transition_of ET WHERE ET name "Bookmark", X eid %(x)s',
                      {'x': t.eid})
         et = self.user().wf_transition('deactivate')
-        self.assertEquals(et.transition_of[0].name, 'EUser')
+        self.assertEquals(et.transition_of[0].name, 'CWUser')
 
     def test_change_state(self):
         user = self.user()
--- a/common/test/unittest_rest.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/common/test/unittest_rest.py	Fri Apr 24 19:46:47 2009 +0200
@@ -5,7 +5,7 @@
         
 class RestTC(EnvBasedTC):
     def context(self):
-        return self.execute('EUser X WHERE X login "admin"').get_entity(0, 0)
+        return self.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
     
     def test_eid_role(self):
         context = self.context()
--- a/cwconfig.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/cwconfig.py	Fri Apr 24 19:46:47 2009 +0200
@@ -64,44 +64,44 @@
       'default': 'UTF-8',
       'help': _('user interface encoding'),
       'group': 'ui', 'sitewide': True,
-      }),    
+      }),
     ('language',
      {'type' : 'string',
       'default': 'en',
       'vocabulary': Method('available_languages'),
       'help': _('language of the user interface'),
-      'group': 'ui', 
+      'group': 'ui',
       }),
     ('date-format',
      {'type' : 'string',
       'default': '%Y/%m/%d',
       'help': _('how to format date in the ui ("man strftime" for format description)'),
-      'group': 'ui', 
+      'group': 'ui',
       }),
     ('datetime-format',
      {'type' : 'string',
       'default': '%Y/%m/%d %H:%M',
       'help': _('how to format date and time in the ui ("man strftime" for format description)'),
-      'group': 'ui', 
+      'group': 'ui',
       }),
     ('time-format',
      {'type' : 'string',
       'default': '%H:%M',
       'help': _('how to format time in the ui ("man strftime" for format description)'),
-      'group': 'ui', 
+      'group': 'ui',
       }),
     ('float-format',
      {'type' : 'string',
       'default': '%.3f',
       'help': _('how to format float numbers in the ui'),
-      'group': 'ui', 
+      'group': 'ui',
       }),
     ('default-text-format',
      {'type' : 'choice',
       'choices': ('text/plain', 'text/rest', 'text/html'),
       'default': 'text/html', # use fckeditor in the web ui
       'help': _('default text format for rich text fields.'),
-      'group': 'ui', 
+      'group': 'ui',
       }),
     ('short-line-size',
      {'type' : 'int',
@@ -114,7 +114,7 @@
 def register_persistent_options(options):
     global PERSISTENT_OPTIONS
     PERSISTENT_OPTIONS = merge_options(PERSISTENT_OPTIONS + options)
-                
+
 CFGTYPE2ETYPE_MAP = {
     'string': 'String',
     'choice': 'String',
@@ -122,7 +122,7 @@
     'int':    'Int',
     'float' : 'Float',
     }
-    
+
 class CubicWebNoAppConfiguration(ConfigurationMixIn):
     """base class for cubicweb configuration without a specific instance directory
     """
@@ -198,7 +198,7 @@
           }),
         )
     # static and class methods used to get application independant resources ##
-        
+
     @staticmethod
     def cubicweb_version():
         """return installed cubicweb version"""
@@ -207,7 +207,7 @@
         version = __pkginfo__.numversion
         assert len(version) == 3, version
         return Version(version)
-    
+
     @staticmethod
     def persistent_options_configuration():
         return Configuration(options=PERSISTENT_OPTIONS)
@@ -220,7 +220,7 @@
         if cls.mode in ('dev', 'test') and not os.environ.get('APYCOT_ROOT'):
             return join(CW_SOFTWARE_ROOT, 'web')
         return cls.cube_dir('shared')
-        
+
     @classmethod
     def i18n_lib_dir(cls):
         """return application's i18n directory"""
@@ -236,7 +236,7 @@
                 if isdir(join(directory, cube)) and not cube in ('CVS', '.svn', 'shared', '.hg'):
                     cubes.add(cube)
         return sorted(cubes)
-    
+
     @classmethod
     def cubes_search_path(cls):
         """return the path of directories where cubes should be searched"""
@@ -251,7 +251,7 @@
         if not cls.CUBES_DIR in path:
             path.append(cls.CUBES_DIR)
         return path
-    
+
     @classmethod
     def cube_dir(cls, cube):
         """return the cube directory for the given cube id,
@@ -267,7 +267,7 @@
     def cube_migration_scripts_dir(cls, cube):
         """cube migration scripts directory"""
         return join(cls.cube_dir(cube), 'migration')
-    
+
     @classmethod
     def cube_pkginfo(cls, cube):
         """return the information module for the given cube"""
@@ -280,7 +280,7 @@
 
     @classmethod
     def cube_version(cls, cube):
-        """return the version of the cube located in the given directory        
+        """return the version of the cube located in the given directory
         """
         from logilab.common.changelog import Version
         version = cls.cube_pkginfo(cube).numversion
@@ -343,7 +343,7 @@
                         except KeyError:
                             continue
         return tuple(reversed(cubes))
-    
+
     @classmethod
     def cls_adjust_sys_path(cls):
         """update python path if necessary"""
@@ -381,7 +381,7 @@
                 except:
                     cls.exception('while loading cube %s', cube)
             else:
-                cls.warning('no __init__ file in cube %s', cube) 
+                cls.warning('no __init__ file in cube %s', cube)
 
     @classmethod
     def init_available_cubes(cls):
@@ -393,7 +393,7 @@
                 __import__('cubes.%s' % cube)
             except Exception, ex:
                 cls.warning("can't init cube %s: %s", cube, ex)
-        
+
     cubicweb_vobject_path = set(['entities'])
     cube_vobject_path = set(['entities'])
 
@@ -441,17 +441,17 @@
                 elif exists(path + '.py'):
                     vregpath.append(path + '.py')
         return vregpath
-        
+
     def __init__(self):
         ConfigurationMixIn.__init__(self)
         self.adjust_sys_path()
         self.load_defaults()
-        self.translations = {} 
+        self.translations = {}
 
     def adjust_sys_path(self):
         self.cls_adjust_sys_path()
-        
-    def init_log(self, logthreshold=None, debug=False, 
+
+    def init_log(self, logthreshold=None, debug=False,
                  logfile=None, syslog=False):
         """init the log service"""
         if logthreshold is None:
@@ -468,7 +468,7 @@
         for application objects. By default return nothing in NoApp config.
         """
         return []
-    
+
     def eproperty_definitions(self):
         cfg = self.persistent_options_configuration()
         for section, options in cfg.options_by_section():
@@ -481,7 +481,7 @@
                         'help': optdict['help'],
                         'sitewide': optdict.get('sitewide', False)}
                 yield key, pdef
-                
+
     def map_option(self, optdict):
         try:
             vocab = optdict['choices']
@@ -491,10 +491,10 @@
                 vocab = getattr(self, vocab.method, ())
         return CFGTYPE2ETYPE_MAP[optdict['type']], vocab
 
-    
+
 class CubicWebConfiguration(CubicWebNoAppConfiguration):
     """base class for cubicweb server and web configurations"""
-    
+
     INSTANCE_DATA_DIR = None
     if CubicWebNoAppConfiguration.mode == 'test':
         root = os.environ['APYCOT_ROOT']
@@ -517,7 +517,7 @@
     set_language = True
     # set this to true to avoid false error message while creating an application
     creating = False
-    
+
     options = CubicWebNoAppConfiguration.options + (
         ('log-file',
          {'type' : 'string',
@@ -540,7 +540,7 @@
           }),
         ('sender-name',
          {'type' : 'string',
-          'default': Method('default_application_id'), 
+          'default': Method('default_application_id'),
           'help': 'name used as HELO name for outgoing emails from the \
 repository.',
           'group': 'email', 'inputlevel': 2,
@@ -558,7 +558,7 @@
     def runtime_dir(cls):
         """run time directory for pid file..."""
         return env_path('CW_RUNTIME', cls.RUNTIME_DIR, 'run time')
-    
+
     @classmethod
     def registry_dir(cls):
         """return the control directory"""
@@ -570,7 +570,7 @@
         return env_path('CW_INSTANCE_DATA',
                         cls.INSTANCE_DATA_DIR or cls.REGISTRY_DIR,
                         'additional data')
-        
+
     @classmethod
     def migration_scripts_dir(cls):
         """cubicweb migration scripts directory"""
@@ -583,7 +583,7 @@
         config = config or guess_configuration(cls.application_home(appid))
         configcls = configuration_cls(config)
         return configcls(appid)
-    
+
     @classmethod
     def possible_configurations(cls, appid):
         """return the name of possible configurations for the given
@@ -591,7 +591,7 @@
         """
         home = cls.application_home(appid)
         return possible_configurations(home)
-    
+
     @classmethod
     def application_home(cls, appid):
         """return the home directory of the application with the given
@@ -610,9 +610,9 @@
     def accept_mode(cls, mode):
         #assert mode in cls.MODES, mode
         return mode in cls.MCOMPAT[cls.name]
-            
+
     # default configuration methods ###########################################
-    
+
     def default_application_id(self):
         """return the application identifier, useful for option which need this
         as default value
@@ -634,13 +634,13 @@
                     i += 1
             return path
         return '/var/log/cubicweb/%s-%s.log' % (self.appid, self.name)
-    
+
     def default_pid_file(self):
         """return default path to the pid file of the application'server"""
         return join(self.runtime_dir(), '%s-%s.pid' % (self.appid, self.name))
-    
+
     # instance methods used to get application specific resources #############
-    
+
     def __init__(self, appid):
         self.appid = appid
         CubicWebNoAppConfiguration.__init__(self)
@@ -658,11 +658,11 @@
     @property
     def apphome(self):
         return join(self.registry_dir(), self.appid)
-    
+
     @property
     def appdatahome(self):
         return join(self.instance_data_dir(), self.appid)
-        
+
     def init_cubes(self, cubes):
         assert self._cubes is None
         self._cubes = self.reorder_cubes(cubes)
@@ -675,7 +675,7 @@
         self.load_file_configuration(self.main_config_file())
         # configuration initialization hook
         self.load_configuration()
-        
+
     def cubes(self):
         """return the list of cubes used by this instance
 
@@ -684,7 +684,7 @@
         """
         assert self._cubes is not None
         return self._cubes
-        
+
     def cubes_path(self):
         """return the list of path to cubes used by this instance, from outer
         most to inner most cubes
@@ -696,11 +696,11 @@
         if not isinstance(cubes, list):
             cubes = list(cubes)
         self._cubes = self.reorder_cubes(list(self._cubes) + cubes)
-        
+
     def main_config_file(self):
         """return application's control configuration file"""
         return join(self.apphome, '%s.conf' % self.name)
-            
+
     def save(self):
         """write down current configuration"""
         self.generate_config(open(self.main_config_file(), 'w'))
@@ -713,7 +713,7 @@
             version = self.cube_version(pkg)
             infos.append('%s-%s' % (pkg, version))
         return md5.new(';'.join(infos)).hexdigest()
-                
+
     def load_site_cubicweb(self):
         """load (web?) application's specific site_cubicweb file"""
         for path in reversed([self.apphome] + self.cubes_path()):
@@ -727,7 +727,7 @@
                     self._load_site_cubicweb(sitefile)
                     self._site_loaded.add(sitefile)
                     self.warning('site_erudi.py is deprecated, should be renamed to site_cubicweb.py')
-                
+
     def _load_site_cubicweb(self, sitefile):
         context = {}
         execfile(sitefile, context, context)
@@ -736,14 +736,14 @@
         if context.get('options'):
             self.register_options(context['options'])
             self.load_defaults()
-                
+
     def load_configuration(self):
         """load application's configuration files"""
         super(CubicWebConfiguration, self).load_configuration()
         if self.apphome and self.set_language:
             # init gettext
             self._set_language()
-            
+
     def init_log(self, logthreshold=None, debug=False, force=False):
         """init the log service"""
         if not force and hasattr(self, '_logging_initialized'):
@@ -769,7 +769,7 @@
             lang = path.split(os.sep)[-3]
             if lang != 'en':
                 yield lang
-        
+
     def _set_language(self):
         """set language for gettext"""
         from gettext import translation
@@ -781,8 +781,8 @@
                 self.translations[language] = tr.ugettext
             except (ImportError, AttributeError, IOError):
                 self.exception('localisation support error for language %s',
-                               language)            
-    
+                               language)
+
     def vregistry_path(self):
         """return a list of files or directories where the registry will look
         for application objects
@@ -796,7 +796,7 @@
         if not 'all' in sources:
             print 'warning: ignoring specified sources, requires a repository '\
                   'configuration'
-        
+
     def migration_handler(self):
         """return a migration handler instance"""
         from cubicweb.common.migration import MigrationHelper
@@ -814,7 +814,7 @@
         return i18n.compile_i18n_catalogs(sourcedirs, i18ndir, langs)
 
 set_log_methods(CubicWebConfiguration, logging.getLogger('cubicweb.configuration'))
-        
+
 # alias to get a configuration instance from an application id
-application_configuration = CubicWebConfiguration.config_for        
+application_configuration = CubicWebConfiguration.config_for
 
--- a/cwctl.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/cwctl.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,6 +1,6 @@
 """%%prog %s [options] %s
 
-CubicWeb main applications controller. 
+CubicWeb main applications controller.
 %s"""
 
 import sys
@@ -12,7 +12,7 @@
 from cubicweb import ConfigurationError, ExecutionError, BadCommandUsage
 from cubicweb.cwconfig import CubicWebConfiguration as cwcfg, CONFIGURATIONS
 from cubicweb.toolsutils import Command, main_run,  rm, create_dir, confirm
-    
+
 def wait_process_end(pid, maxtry=10, waittime=1):
     """wait for a process to actually die"""
     import signal
@@ -42,13 +42,13 @@
             modes.append('web ui')
             break
     return modes
-    
-    
+
+
 class ApplicationCommand(Command):
     """base class for command taking 0 to n application id as arguments
     (0 meaning all registered applications)
     """
-    arguments = '[<application>...]'    
+    arguments = '[<application>...]'
     options = (
         ("force",
          {'short': 'f', 'action' : 'store_true',
@@ -58,7 +58,7 @@
          ),
         )
     actionverb = None
-    
+
     def ordered_instances(self):
         """return instances in the order in which they should be started,
         considering $REGISTRY_DIR/startorder file if it exists (useful when
@@ -81,7 +81,7 @@
         else:
             allinstances = _allinstances
         return allinstances
-    
+
     def run(self, args):
         """run the <command>_method on each argument (a list of application
         identifiers)
@@ -96,7 +96,7 @@
         else:
             askconfirm = False
         self.run_args(args, askconfirm)
-        
+
     def run_args(self, args, askconfirm):
         for appid in args:
             if askconfirm:
@@ -104,7 +104,7 @@
                 if not confirm('%s application %r ?' % (self.name, appid)):
                     continue
             self.run_arg(appid)
-            
+
     def run_arg(self, appid):
         cmdmeth = getattr(self, '%s_application' % self.name)
         try:
@@ -143,7 +143,7 @@
                     sys.exit(status)
             else:
                 self.run_arg(appid)
-    
+
 # base commands ###############################################################
 
 class ListCommand(Command):
@@ -155,10 +155,10 @@
     name = 'list'
     options = (
         ('verbose',
-         {'short': 'v', 'action' : 'store_true', 
-          'help': "display more information."}),        
+         {'short': 'v', 'action' : 'store_true',
+          'help': "display more information."}),
         )
-    
+
     def run(self, args):
         """run the command with its specific arguments"""
         if args:
@@ -174,7 +174,7 @@
                 if not line:
                     continue
                 print '   ', line
-        print 
+        print
         try:
             cubesdir = pathsep.join(cwcfg.cubes_search_path())
             namesize = max(len(x) for x in cwcfg.available_cubes())
@@ -219,7 +219,7 @@
                 print '* %s (%s)' % (appid, ', '.join(modes))
                 try:
                     config = cwcfg.config_for(appid, modes[0])
-                except Exception, exc: 
+                except Exception, exc:
                     print '    (BROKEN application, %s)' % exc
                     continue
         else:
@@ -261,7 +261,7 @@
           }
          ),
         )
-    
+
     def run(self, args):
         """run the command with its specific arguments"""
         from logilab.common.textutils import get_csv
@@ -323,14 +323,14 @@
         print
         helper.postcreate()
 
-    
+
 class DeleteApplicationCommand(Command):
     """Delete an application. Will remove application's files and
     unregister it.
     """
     name = 'delete'
     arguments = '<application>'
-    
+
     options = ()
 
     def run(self, args):
@@ -361,7 +361,7 @@
 
 class StartApplicationCommand(ApplicationCommand):
     """Start the given applications. If no application is given, start them all.
-    
+
     <application>...
       identifiers of the applications to start. If no application is
       given, start them all.
@@ -414,19 +414,19 @@
 
 class StopApplicationCommand(ApplicationCommand):
     """Stop the given applications.
-    
+
     <application>...
       identifiers of the applications to stop. If no application is
       given, stop them all.
     """
     name = 'stop'
     actionverb = 'stopped'
-    
+
     def ordered_instances(self):
         instances = super(StopApplicationCommand, self).ordered_instances()
         instances.reverse()
         return instances
-    
+
     def stop_application(self, appid):
         """stop the application's server"""
         config = cwcfg.config_for(appid)
@@ -460,12 +460,12 @@
             # already removed by twistd
             pass
         print 'application %s stopped' % appid
-    
+
 
 class RestartApplicationCommand(StartApplicationCommand,
                                 StopApplicationCommand):
     """Restart the given applications.
-    
+
     <application>...
       identifiers of the applications to restart. If no application is
       given, restart them all.
@@ -497,30 +497,30 @@
             status = system('%s %s' % (forkcmd, appid))
             if status:
                 sys.exit(status)
-    
+
     def restart_application(self, appid):
         self.stop_application(appid)
         if self.start_application(appid):
             print 'application %s %s' % (appid, self.actionverb)
 
-        
+
 class ReloadConfigurationCommand(RestartApplicationCommand):
     """Reload the given applications. This command is equivalent to a
     restart for now.
-    
+
     <application>...
       identifiers of the applications to reload. If no application is
       given, reload them all.
     """
     name = 'reload'
-    
+
     def reload_application(self, appid):
         self.restart_application(appid)
-    
+
 
 class StatusCommand(ApplicationCommand):
     """Display status information about the given applications.
-    
+
     <application>...
       identifiers of the applications to status. If no application is
       given, get status information about all registered applications.
@@ -576,7 +576,7 @@
          {'short': 'e', 'type' : 'string', 'metavar': 'X.Y.Z',
           'default': None,
           'help': 'force migration from the indicated cubicweb version.'}),
-        
+
         ('fs-only',
          {'short': 's', 'action' : 'store_true',
           'default': False,
@@ -586,13 +586,13 @@
          {'short': 'n', 'action' : 'store_true',
           'default': False,
           'help': 'don\'t try to stop application before migration and to restart it after.'}),
-        
+
         ('verbosity',
          {'short': 'v', 'type' : 'int', 'metavar': '<0..2>',
           'default': 1,
           'help': "0: no confirmation, 1: only main commands confirmed, 2 ask \
 for everything."}),
-        
+
         ('backup-db',
          {'short': 'b', 'type' : 'yn', 'metavar': '<y or n>',
           'default': None,
@@ -613,11 +613,9 @@
     def ordered_instances(self):
         # need this since mro return StopApplicationCommand implementation
         return ApplicationCommand.ordered_instances(self)
-    
+
     def upgrade_application(self, appid):
         from logilab.common.changelog import Version
-        if not (cwcfg.mode == 'dev' or self.config.nostartstop):
-            self.stop_application(appid)
         config = cwcfg.config_for(appid)
         config.creating = True # notice we're not starting the server
         config.verbosity = self.config.verbosity
@@ -648,7 +646,7 @@
                 continue
             if installedversion > applversion:
                 toupgrade.append( (cube, applversion, installedversion) )
-        cubicwebversion = config.cubicweb_version()           
+        cubicwebversion = config.cubicweb_version()
         if self.config.force_cubicweb_version:
             applcubicwebversion = Version(self.config.force_cubicweb_version)
             vcconf['cubicweb'] = applcubicwebversion
@@ -661,6 +659,9 @@
             return
         for cube, fromversion, toversion in toupgrade:
             print '**** %s migration %s -> %s' % (cube, fromversion, toversion)
+        # only stop once we're sure we have something to do
+        if not (cwcfg.mode == 'dev' or self.config.nostartstop):
+            self.stop_application(appid)
         # run cubicweb/componants migration scripts
         mih.migrate(vcconf, reversed(toupgrade), self.config)
         # rewrite main configuration file
@@ -706,7 +707,7 @@
           'help': 'only connect to the system source when the instance is '
           'using multiple sources. You can\'t use this option and the '
           '--ext-sources option at the same time.'}),
-        
+
         ('ext-sources',
          {'short': 'E', 'type' : 'csv', 'metavar': '<sources>',
           'default': None,
@@ -715,7 +716,7 @@
 will connect to all defined sources. If 'migration' is given, appropriate \
 sources for migration will be automatically selected.",
           }),
-        
+
         )
     def run(self, args):
         appid = pop_arg(args, 99, msg="No application specified !")
@@ -733,12 +734,12 @@
             mih.scripts_session(args)
         else:
             mih.interactive_shell()
-        mih.shutdown() 
+        mih.shutdown()
 
 
 class RecompileApplicationCatalogsCommand(ApplicationCommand):
     """Recompile i18n catalogs for applications.
-    
+
     <application>...
       identifiers of the applications to consider. If no application is
       given, recompile for all registered applications.
@@ -772,7 +773,7 @@
     """list available instances, useful for bash completion."""
     name = 'listinstances'
     hidden = True
-    
+
     def run(self, args):
         """run the command with its specific arguments"""
         regdir = cwcfg.registry_dir()
@@ -784,7 +785,7 @@
     """list available componants, useful for bash completion."""
     name = 'listcubes'
     hidden = True
-    
+
     def run(self, args):
         """run the command with its specific arguments"""
         for cube in cwcfg.available_cubes():
@@ -804,7 +805,7 @@
                    ListInstancesCommand, ListCubesCommand,
                    ))
 
-                
+
 def run(args):
     """command line tool"""
     cwcfg.load_cwctl_plugins()
--- a/cwvreg.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/cwvreg.py	Fri Apr 24 19:46:47 2009 +0200
@@ -7,7 +7,6 @@
 __docformat__ = "restructuredtext en"
 
 from logilab.common.decorators import cached, clear_cache
-from logilab.common.interface import extend
 
 from rql import RQLHelper
 
@@ -23,7 +22,7 @@
     from cubicweb.selectors import implements
     try:
         # XXX deprecated
-        return sorted(obj.accepts_interfaces) 
+        return sorted(obj.accepts_interfaces)
     except AttributeError:
         try:
             impl = obj.__select__.search_selector(implements)
@@ -39,7 +38,7 @@
 
 class CubicWebRegistry(VRegistry):
     """extend the generic VRegistry with some cubicweb specific stuff"""
-    
+
     def __init__(self, config, debug=None, initlog=True):
         if initlog:
             # first init log service
@@ -48,7 +47,7 @@
         self.schema = None
         self.reset()
         self.initialized = False
-        
+
     def items(self):
         return [item for item in self._registries.items()
                 if not item[0] in ('propertydefs', 'propertyvalues')]
@@ -56,7 +55,7 @@
     def values(self):
         return [value for key, value in self._registries.items()
                 if not key in ('propertydefs', 'propertyvalues')]
-    
+
     def reset(self):
         self._registries = {}
         self._lastmodifs = {}
@@ -68,14 +67,14 @@
         self._registries['propertyvalues'] = self.eprop_values = {}
         for key, propdef in self.config.eproperty_definitions():
             self.register_property(key, **propdef)
-            
+
     def set_schema(self, schema):
         """set application'schema and load application objects"""
         self.schema = schema
         clear_cache(self, 'rqlhelper')
         # now we can load application's web objects
         self.register_objects(self.config.vregistry_path())
-        
+
     def update_schema(self, schema):
         """update .schema attribute on registered objects, necessary for some
         tests
@@ -110,7 +109,7 @@
         ifaces = use_interfaces(obj)
         if ifaces:
             self._needs_iface[obj] = ifaces
-        
+
     def register_objects(self, path, force_reload=None):
         """overriden to remove objects requiring a missing interface"""
         if super(CubicWebRegistry, self).register_objects(path, force_reload):
@@ -147,7 +146,7 @@
                 for appobjects in objects.itervalues():
                     for appobject in appobjects:
                         appobject.vreg_initialization_completed()
-    
+
     @cached
     def etype_class(self, etype):
         """return an entity class for the given entity type.
@@ -172,19 +171,14 @@
             # no entity class for any of the ancestors, fallback to the default
             # one
             cls = self.select(self.registry_objects('etypes', 'Any'), etype)
-        # add class itself to the list of implemented interfaces, as well as the
-        # Any entity class so we can select according to class using the
-        # `implements` selector
-        extend(cls, cls)
-        extend(cls, self.etype_class('Any'))
         return cls
-    
+
     def render(self, registry, oid, req, **context):
         """select an object in a given registry and render it
 
         - registry: the registry's name
         - oid : the view to call
-        - req : the HTTP request         
+        - req : the HTTP request
         """
         objclss = self.registry_objects(registry, oid)
         try:
@@ -193,7 +187,7 @@
             rset = None
         selected = self.select(objclss, req, rset, **context)
         return selected.dispatch(**context)
-        
+
     def main_template(self, req, oid='main-template', **context):
         """display query by calling the given template (default to main),
         and returning the output as a string instead of requiring the [w]rite
@@ -213,17 +207,17 @@
         return [x for x in sorted(self.possible_objects(registry, *args, **kwargs),
                                   key=lambda x: x.propval('order'))
                 if x.propval('visible')]
-        
+
     def possible_actions(self, req, rset, **kwargs):
         if rset is None:
-            actions = self.possible_vobjects('actions', req, rset)
+            actions = self.possible_vobjects('actions', req, rset, **kwargs)
         else:
-            actions = rset.possible_actions() # cached implementation
+            actions = rset.possible_actions(**kwargs) # cached implementation
         result = {}
         for action in actions:
             result.setdefault(action.category, []).append(action)
         return result
-        
+
     def possible_views(self, req, rset, **kwargs):
         """return an iterator on possible views for this result set
 
@@ -241,7 +235,7 @@
             except Exception:
                 self.exception('error while trying to list possible %s views for %s',
                                vid, rset)
-                
+
     def select_box(self, oid, *args, **kwargs):
         """return the most specific view according to the result set"""
         try:
@@ -255,7 +249,7 @@
             return self.select_object('actions', oid, *args, **kwargs)
         except NoSelectableObject:
             return
-    
+
     def select_component(self, cid, *args, **kwargs):
         """return the most specific component according to the result set"""
         try:
@@ -268,7 +262,7 @@
         views = self.registry_objects('views', __vid)
         return self.select(views, req, rset, **kwargs)
 
-    
+
     # properties handling #####################################################
 
     def user_property_keys(self, withsitewide=False):
@@ -282,7 +276,7 @@
         """register a given property"""
         properties = self._registries['propertydefs']
         assert type in YAMS_TO_PY
-        properties[key] = {'type': type, 'vocabulary': vocabulary, 
+        properties[key] = {'type': type, 'vocabulary': vocabulary,
                            'default': default, 'help': help,
                            'sitewide': sitewide}
 
@@ -300,7 +294,7 @@
                         'default': None, 'vocabulary': None,
                         'help': _('%s software version of the database') % soft}
             raise UnknownProperty('unregistered property %r' % key)
-            
+
     def property_value(self, key):
         try:
             return self._registries['propertyvalues'][key]
@@ -323,7 +317,7 @@
             if not value in vocab:
                 raise ValueError(_('unauthorized value'))
         return value
-    
+
     def init_properties(self, propvalues):
         """init the property values registry using the given set of couple (key, value)
         """
@@ -383,7 +377,7 @@
             vobject.schema = self.schema
             vobject.config = self.config
         return super(MulCnxCubicWebRegistry, self).select(vobjects, *args, **kwargs)
-    
+
 from datetime import datetime, date, time, timedelta
 
 YAMS_TO_PY = {
--- a/dbapi.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/dbapi.py	Fri Apr 24 19:46:47 2009 +0200
@@ -430,9 +430,9 @@
         eid, login, groups, properties = self._repo.user_info(self.sessionid, props)
         if req is None:
             req = self.request()
-        rset = req.eid_rset(eid, 'EUser')
-        user = self.vreg.etype_class('EUser')(req, rset, row=0, groups=groups,
-                                              properties=properties)
+        rset = req.eid_rset(eid, 'CWUser')
+        user = self.vreg.etype_class('CWUser')(req, rset, row=0, groups=groups,
+                                               properties=properties)
         user['login'] = login # cache login
         return user
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian.hardy/compat	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,1 @@
+5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian.hardy/control	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,131 @@
+Source: cubicweb
+Section: web
+Priority: optional
+Maintainer: Logilab S.A. <contact@logilab.fr>
+Uploaders: Sylvain Thenault <sylvain.thenault@logilab.fr>,
+           Julien Jehannet <julien.jehannet@logilab.fr>,
+           Aurélien Campéas <aurelien.campeas@logilab.fr>
+Build-Depends: debhelper (>= 5), python-dev (>=2.4), python-central (>= 0.5)
+Standards-Version: 3.8.0
+Homepage: http://www.cubicweb.org
+XS-Python-Version: >= 2.4, << 2.6
+
+
+Package: cubicweb
+Architecture: all
+XB-Python-Version: ${python:Versions}
+Depends: ${python:Depends}, cubicweb-server (= ${source:Version}), cubicweb-twisted (= ${source:Version}), cubicweb-client (= ${source:Version})
+XB-Recommends: (postgresql, postgresql-plpython, postgresql-contrib) | mysql | sqlite3
+Recommends: postgresql | mysql | sqlite3
+Description: the complete CubicWeb framework
+ CubicWeb is a semantic web application framework.
+ .
+ This package will install all the components you need to run cubicweb on
+ a single machine. You can also deploy cubicweb by running the different
+ process on different computers, in which case you need to install the
+ corresponding packages on the different hosts.
+
+
+Package: cubicweb-server
+Architecture: all
+XB-Python-Version: ${python:Versions}
+Conflicts: cubicweb-multisources
+Replaces: cubicweb-multisources
+Provides: cubicweb-multisources
+Depends: ${python:Depends}, cubicweb-common (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-indexer (>= 0.6.1), python-psycopg2 | python-mysqldb | python-pysqlite2
+Recommends: pyro, cubicweb-documentation (= ${source:Version})
+Description: server part of the CubicWeb framework
+ CubicWeb is a semantic web application framework.
+ .
+ This package provides the repository server part of the system.
+ .
+ This package provides the repository server part of the library and
+ necessary shared data files such as the schema library.
+
+
+Package: cubicweb-twisted
+Architecture: all
+XB-Python-Version: ${python:Versions}
+Provides: cubicweb-web-frontend
+Depends: ${python:Depends}, cubicweb-web (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-twisted-web2
+Recommends: pyro, cubicweb-documentation (= ${source:Version})
+Description: twisted-based web interface for the CubicWeb framework
+ CubicWeb is a semantic web application framework.
+ .
+ This package provides a twisted based HTTP server to serve
+ the adaptative web interface (see cubicweb-web package).
+ .
+ This package provides only the twisted server part of the library.
+
+
+Package: cubicweb-web
+Architecture: all
+XB-Python-Version: ${python:Versions}
+Depends: ${python:Depends}, cubicweb-common (= ${source:Version}), python-docutils, python-vobject, python-elementtree
+Recommends: fckeditor
+Description: web interface library for the CubicWeb framework
+ CubicWeb is a semantic web application framework.
+ .
+ This package provides an adaptative web interface to the CubicWeb server.
+ Install the cubicweb-twisted package to serve this interface via HTTP.
+ .
+ This package provides the web interface part of the library and
+ necessary shared data files such as defaut views, images...
+
+
+Package: cubicweb-common
+Architecture: all
+XB-Python-Version: ${python:Versions}
+Depends: ${python:Depends}, python-logilab-mtconverter (>= 0.6.0), python-simpletal (>= 4.0), graphviz, gettext, python-lxml, python-logilab-common (>= 0.38.1), python-yams (>= 0.20.2), python-rql (>= 0.20.2), python-simplejson (>= 1.3)
+Recommends: python-psyco
+Conflicts: cubicweb-core
+Replaces: cubicweb-core
+Description: common library for the CubicWeb framework
+ CubicWeb is a semantic web application framework.
+ .
+ This package provides the common parts of the library used by both server
+ code and web application code.
+
+
+Package: cubicweb-ctl
+Architecture: all
+XB-Python-Version: ${python:Versions}
+Depends: ${python:Depends}, cubicweb-common (= ${source:Version})
+Description: tool to manage the CubicWeb framework
+ CubicWeb is a semantic web application framework.
+ .
+ This package provides a control script to manage (create, upgrade, start,
+ stop, etc) CubicWeb applications. It also include the init.d script
+ to automatically start and stop CubicWeb applications on boot or shutdown.
+
+
+Package: cubicweb-client
+Architecture: all
+XB-Python-Version: ${python:Versions}
+Depends: ${python:Depends}, cubicweb-ctl (= ${source:Version}), pyro
+Description: RQL command line client for the CubicWeb framework
+ CubicWeb is a semantic web application framework.
+ .
+ This package provides a RQL (Relation Query Language) command line client using
+ pyro to connect to a repository server.
+
+
+Package: cubicweb-dev
+Architecture: all
+XB-Python-Version: ${python:Versions}
+Depends: ${python:Depends}, cubicweb-server (= ${source:Version}), cubicweb-web (= ${source:Version}), python-pysqlite2
+Suggests: w3c-dtd-xhtml
+Description: tests suite and development tools for the CubicWeb framework
+ CubicWeb is a semantic web application framework.
+ .
+ This package provides the CubicWeb tests suite and some development tools
+ helping in the creation of application.
+
+
+Package: cubicweb-documentation
+Architecture: all
+Recommends: doc-base
+Description: documentation for the CubicWeb framework
+ CubicWeb is a semantic web application framework.
+ .
+ This package provides the system's documentation.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian.hardy/rules	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,78 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+PY_VERSION:=$(shell pyversions -d)
+
+build: build-stamp
+build-stamp: 
+	dh_testdir
+	# XXX doesn't work if logilab-doctools, logilab-xml are not in build depends
+	# and I can't get pbuilder find them in its chroot :(
+	# cd doc && make
+	# FIXME cleanup and use sphinx-build as build-depends ?
+	python setup.py build
+	touch build-stamp
+
+clean: 
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp configure-stamp
+	rm -rf build
+	#rm -rf debian/cubicweb-*/
+	find . -name "*.pyc" -delete
+	rm -f $(basename $(wildcard debian/*.in))
+	dh_clean
+
+install: build $(basename $(wildcard debian/*.in))
+	dh_testdir
+	dh_testroot
+	dh_clean
+	dh_installdirs
+
+	#python setup.py install_lib --no-compile --install-dir=debian/cubicweb-common/usr/lib/python2.4/site-packages/
+	python setup.py -q install --no-compile --prefix=debian/tmp/usr
+
+	# Put all the python library and data in cubicweb-common
+	# and scripts in cubicweb-server
+	dh_install -vi
+	#dh_lintian XXX not before debhelper 7
+
+	# Remove unittests directory (should be available in cubicweb-dev only)
+	rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/site-packages/cubicweb/server/test
+	rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/site-packages/cubicweb/sobjects/test
+	rm -rf debian/cubicweb-web/usr/lib/${PY_VERSION}/site-packages/cubicweb/web/test
+	rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/common/test
+
+	# cubes directory must be managed as a valid python module
+	touch debian/cubicweb-common/usr/share/cubicweb/cubes/__init__.py
+
+%: %.in
+	sed "s/PY_VERSION/${PY_VERSION}/g" < $< > $@
+
+# Build architecture-independent files here.
+binary-indep: build install
+	dh_testdir
+	dh_testroot -i
+	dh_pycentral -i
+	dh_installinit -i -n --name cubicweb -u"defaults 99"
+	dh_installlogrotate -i
+	dh_installdocs -i -A README
+	dh_installman -i
+	dh_installchangelogs -i
+	dh_link -i
+	dh_compress -i -X.py -X.ini -X.xml
+	dh_fixperms -i
+	dh_installdeb -i
+	dh_gencontrol  -i
+	dh_md5sums -i
+	dh_builddeb -i
+
+binary-arch:
+
+binary: binary-indep 
+.PHONY: build clean binary binary-indep binary-arch
+
--- a/debian/cubicweb-ctl.postinst	Wed Apr 22 09:45:54 2009 +0200
+++ b/debian/cubicweb-ctl.postinst	Fri Apr 24 19:46:47 2009 +0200
@@ -13,25 +13,29 @@
 if [ "$1" = configure ]; then
     # XXX bw compat: erudi -> cubicweb migration
     if [ -e "/etc/erudi.d/" ]; then
-      mv /etc/erudi.d/* /etc/cubicweb.d/
-      echo 'moved /etc/erudi.d/* to /etc/cubicweb.d/'
-      sed -i s/ginco/cubicweb/g /etc/*/*.py
-      sed -i s/erudi/cubicweb/ */*.conf
+      mv /etc/erudi.d/* /etc/cubicweb.d/ && (
+	  echo 'moved /etc/erudi.d/* to /etc/cubicweb.d/'
+	  sed -i s/ginco/cubicweb/g /etc/*/*.py
+	  sed -i s/erudi/cubicweb/ */*.conf
+	  ) || true # empty dir
     fi
     if [ -e "/var/log/erudi/" ]; then
-      mv /var/log/erudi/* /var/log/cubicweb/
-      echo 'moved /var/log/erudi/* to /var/log/cubicweb/'
+      mv /var/log/erudi/* /var/log/cubicweb/ && (
+	  echo 'moved /var/log/erudi/* to /var/log/cubicweb/'
+	  ) || true # empty dir
     fi
     if [ -e "/var/lib/erudi/backup" ]; then
-      mv /var/lib/erudi/backup/* /var/lib/cubicweb/backup/
-      echo 'moved /var/lib/erudi/backup/* to /var/lib/cubicweb/backup/'
+      mv /var/lib/erudi/backup/* /var/lib/cubicweb/backup/ && (
+	  echo 'moved /var/lib/erudi/backup/* to /var/lib/cubicweb/backup/'
+	  ) || true # empty dir
     fi
     if [ -e "/var/lib/erudi/instances" ]; then
-      mv /var/lib/erudi/instances/* /var/lib/cubicweb/instances/
-      echo 'moved /var/lib/erudi/instances/* to /var/lib/cubicweb/instances/'
+      mv /var/lib/erudi/instances/* /var/lib/cubicweb/instances/ && (
+	  echo 'moved /var/lib/erudi/instances/* to /var/lib/cubicweb/instances/'
+	  ) || true # empty dir
     fi
 fi
-  
+
 #DEBHELPER#
- 
+
 exit 0
--- a/devtools/_apptest.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/devtools/_apptest.py	Fri Apr 24 19:46:47 2009 +0200
@@ -21,10 +21,10 @@
 from cubicweb.devtools import ApptestConfiguration, init_test_database
 from cubicweb.devtools.fake import FakeRequest
     
-SYSTEM_ENTITIES = ('EGroup', 'EUser',
-                   'EFRDef', 'ENFRDef',
-                   'EConstraint', 'EConstraintType', 'EProperty',
-                   'EEType', 'ERType',
+SYSTEM_ENTITIES = ('CWGroup', 'CWUser',
+                   'CWAttribute', 'CWRelation',
+                   'CWConstraint', 'CWConstraintType', 'CWProperty',
+                   'CWEType', 'CWRType',
                    'State', 'Transition', 'TrInfo',
                    'RQLExpression',
                    )
@@ -50,7 +50,7 @@
                     )
 
 def unprotected_entities(app_schema, strict=False):
-    """returned a Set of each non final entity type, excluding EGroup, and EUser...
+    """returned a Set of each non final entity type, excluding CWGroup, and CWUser...
     """
     if strict:
         protected_entities = yams.schema.BASE_TYPES
@@ -90,7 +90,7 @@
         schema = self.vreg.schema
         # else we may run into problems since email address are ususally share in app tests
         # XXX should not be necessary anymore
-        schema.rschema('primary_email').set_rproperty('EUser', 'EmailAddress', 'composite', False)
+        schema.rschema('primary_email').set_rproperty('CWUser', 'EmailAddress', 'composite', False)
         self.deletable_entities = unprotected_entities(schema)
 
     def restore_database(self):
@@ -119,7 +119,7 @@
     def create_user(self, login, groups=('users',), req=None):
         req = req or self.create_request()
         cursor = self._orig_cnx.cursor(req)
-        rset = cursor.execute('INSERT EUser X: X login %(login)s, X upassword %(passwd)s,'
+        rset = cursor.execute('INSERT CWUser X: X login %(login)s, X upassword %(passwd)s,'
                               'X in_state S WHERE S name "activated"',
                               {'login': unicode(login), 'passwd': login.encode('utf8')})
         user = rset.get_entity(0, 0)
--- a/devtools/apptest.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/devtools/apptest.py	Fri Apr 24 19:46:47 2009 +0200
@@ -14,6 +14,8 @@
 from logilab.common.pytest import nocoverage
 from logilab.common.umessage import message_from_string
 
+from logilab.common.deprecation import deprecated_function
+
 from cubicweb.devtools import init_test_database, TestServerConfiguration, ApptestConfiguration
 from cubicweb.devtools._apptest import TestEnvironment
 from cubicweb.devtools.fake import FakeRequest
@@ -218,6 +220,13 @@
     def pactions(self, req, rset, skipcategories=('addrelated', 'siteactions', 'useractions')):
         return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset)
                 if a.category not in skipcategories]
+
+    def pactions_by_cats(self, req, rset, categories=('addrelated',)):
+        return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset)
+                if a.category in categories]
+    
+    paddrelactions = deprecated_function(pactions_by_cats)
+
     def pactionsdict(self, req, rset, skipcategories=('addrelated', 'siteactions', 'useractions')):
         res = {}
         for a in self.vreg.possible_vobjects('actions', req, rset):
@@ -225,10 +234,7 @@
                 res.setdefault(a.category, []).append(a.__class__)
         return res
 
-    def paddrelactions(self, req, rset):
-        return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset)
-                if a.category == 'addrelated']
-               
+    
     def remote_call(self, fname, *args):
         """remote call simulation"""
         dump = simplejson.dumps
@@ -355,7 +361,7 @@
     def create_user(self, user, groups=('users',), password=None, commit=True):
         if password is None:
             password = user
-        eid = self.execute('INSERT EUser X: X login %(x)s, X upassword %(p)s,'
+        eid = self.execute('INSERT CWUser X: X login %(x)s, X upassword %(p)s,'
                             'X in_state S WHERE S name "activated"',
                             {'x': unicode(user), 'p': password})[0][0]
         groups = ','.join(repr(group) for group in groups)
--- a/devtools/devctl.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/devtools/devctl.py	Fri Apr 24 19:46:47 2009 +0200
@@ -9,7 +9,7 @@
 
 import sys
 from datetime import datetime
-from os import mkdir, chdir, listdir
+from os import mkdir, chdir
 from os.path import join, exists, abspath, basename, normpath, split, isdir
 
 
@@ -40,7 +40,7 @@
 
     def my_cubes(self, cube):
         return (cube,) + self.cube_dependencies(cube) + self.cube_recommends(cube)
-    
+
     @property
     def apphome(self):
         return None
@@ -77,7 +77,7 @@
             if mod.__file__.startswith(path):
                 del sys.modules[name]
                 break
-    
+
 def generate_schema_pot(w, cubedir=None):
     """generate a pot file with schema specific i18n messages
 
@@ -86,29 +86,31 @@
     """
     from cubicweb.cwvreg import CubicWebRegistry
     cube = cubedir and split(cubedir)[-1]
-    config = DevDepConfiguration(cube)
-    cleanup_sys_modules(config)
+    libconfig = DevDepConfiguration(cube)
+    libconfig.cleanup_interface_sobjects = False
+    cleanup_sys_modules(libconfig)
     if cubedir:
-        libschema = config.load_schema()
         config = DevCubeConfiguration(cube)
         schema = config.load_schema()
     else:
         schema = config.load_schema()
-        libschema = None
-        config.cleanup_interface_sobjects = False
+        config = libconfig
+        libconfig = None
     vreg = CubicWebRegistry(config)
     # set_schema triggers objects registrations
     vreg.set_schema(schema)
     w(DEFAULT_POT_HEAD)
-    _generate_schema_pot(w, vreg, schema, libschema=libschema, cube=cube)
-                
-def _generate_schema_pot(w, vreg, schema, libschema=None, cube=None):
+    _generate_schema_pot(w, vreg, schema, libconfig=libconfig, cube=cube)
+
+
+def _generate_schema_pot(w, vreg, schema, libconfig=None, cube=None):
     from cubicweb.common.i18n import add_msg
     w('# schema pot file, generated on %s\n' % datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
     w('# \n')
     w('# singular and plural forms for each entity type\n')
     w('\n')
-    if libschema is not None:
+    if libconfig is not None:
+        libschema = libconfig.load_schema()
         entities = [e for e in schema.entities() if not e in libschema]
     else:
         entities = schema.entities()
@@ -143,46 +145,64 @@
             add_msg(w, rschema.description)
     w('# add related box generated message\n')
     w('\n')
-    actionbox = self.vreg['actions']['edit_box'][0]
+    actionbox = vreg['boxes']['edit_box'][0]
     for eschema in schema.entities():
         if eschema.is_final():
             continue
-        for x, rschemas in (('subject', eschema.subject_relations()),
+        for role, rschemas in (('subject', eschema.subject_relations()),
                             ('object', eschema.object_relations())):
             for rschema in rschemas:
                 if rschema.is_final():
                     continue
-                for teschema in rschema.targets(eschema, x):
-                    if defined_in_library(libschema, eschema, rschema, teschema, x):
+                for teschema in rschema.targets(eschema, role):
+                    if defined_in_library(libschema, eschema, rschema,
+                                          teschema, role):
                         continue
-                    if actionbox.relation_mode(rschema.type, teschema.type, x) == 'create':
-                        if x == 'subject':
-                            label = 'add %s %s %s %s' % (eschema, rschema, teschema, x)
-                            label2 = "creating %s (%s %%(linkto)s %s %s)" % (teschema, eschema, rschema, teschema)
+                    if actionbox.relation_mode(rschema, eschema, teschema, role) == 'create':
+                        if role == 'subject':
+                            label = 'add %s %s %s %s' % (eschema, rschema,
+                                                         teschema, role)
+                            label2 = "creating %s (%s %%(linkto)s %s %s)" % (
+                                teschema, eschema, rschema, teschema)
                         else:
-                            label = 'add %s %s %s %s' % (teschema, rschema, eschema, x)
-                            label2 = "creating %s (%s %s %s %%(linkto)s)" % (teschema, teschema, rschema, eschema)
+                            label = 'add %s %s %s %s' % (teschema, rschema,
+                                                         eschema, role)
+                            label2 = "creating %s (%s %s %s %%(linkto)s)" % (
+                                teschema, teschema, rschema, eschema)
                         add_msg(w, label)
                         add_msg(w, label2)
-    cube = (cube and 'cubes.%s.' % cube or 'cubicweb.')
+    #cube = (cube and 'cubes.%s.' % cube or 'cubicweb.')
     done = set()
+    if libconfig is not None:
+        from cubicweb.cwvreg import CubicWebRegistry
+        libvreg = CubicWebRegistry(libconfig)
+        libvreg.set_schema(libschema) # trigger objects registration
+        # prefill done set
+        list(_iter_vreg_objids(libvreg, done))
+    print 'done', done
+    for objid in _iter_vreg_objids(vreg, done):
+        add_msg(w, '%s_description' % objid)
+        add_msg(w, objid)
+
+def _iter_vreg_objids(vreg, done, prefix=None):
     for reg, objdict in vreg.items():
         for objects in objdict.values():
             for obj in objects:
                 objid = '%s_%s' % (reg, obj.id)
                 if objid in done:
-                    continue
-                if obj.__module__.startswith(cube) and obj.property_defs:
-                    add_msg(w, '%s_description' % objid)
-                    add_msg(w, objid)
+                    break
+                if obj.property_defs:
+                    yield objid
                     done.add(objid)
+                    break
 
-                    
-def defined_in_library(libschema, etype, rtype, tetype, x):
-    """return true if the given relation definition exists in cubicweb's library"""
+
+def defined_in_library(libschema, etype, rtype, tetype, role):
+    """return true if the given relation definition exists in cubicweb's library
+    """
     if libschema is None:
         return False
-    if x == 'subject':
+    if role == 'subject':
         subjtype, objtype = etype, tetype
     else:
         subjtype, objtype = tetype, etype
@@ -211,7 +231,7 @@
 
 class UpdateCubicWebCatalogCommand(Command):
     """Update i18n catalogs for cubicweb library.
-    
+
     It will regenerate cubicweb/i18n/xx.po files. You'll have then to edit those
     files to add translations of newly added messages.
     """
@@ -281,7 +301,7 @@
     """
     name = 'i18nupdate'
     arguments = '[<cube>...]'
-    
+
     def run(self, args):
         """run the command with its specific arguments"""
         if args:
@@ -328,7 +348,7 @@
             execute('xgettext --no-location --omit-header -k_ -L java --from-code=utf-8 -o %s %s'
                     % (tmppotfile, ' '.join(jsfiles)))
             # no pot file created if there are no string to translate
-            if exists(tmppotfile): 
+            if exists(tmppotfile):
                 potfiles.append(tmppotfile)
         print '******** create cube specific catalog'
         tmppotfile = join(tempdir, 'generated.pot')
@@ -367,7 +387,7 @@
     name = 'live-server'
     arguments = ''
     options = ()
-    
+
     def run(self, args):
         """run the command with its specific arguments"""
         from cubicweb.devtools.livetest import runserver
@@ -415,7 +435,7 @@
          ),
         )
 
-    
+
     def run(self, args):
         if len(args) != 1:
             raise BadCommandUsage("exactly one argument (cube name) is expected")
@@ -449,7 +469,7 @@
                     distname = 'cubicweb-' + distname
         else:
             distname = 'cubicweb-%s' % cubename.lower()
-        
+
         longdesc = shortdesc = raw_input('Enter a short description for your cube: ')
         if verbose:
             longdesc = raw_input('Enter a long description (or nothing if you want to reuse the short one): ')
@@ -487,7 +507,7 @@
             elif ans == 's':
                 break
         return includes
-    
+
 
 class ExamineLogCommand(Command):
     """Examine a rql log file.
@@ -506,7 +526,7 @@
     name = 'exlog'
     options = (
         )
-    
+
     def run(self, args):
         if args:
             raise BadCommandUsage("no argument expected")
@@ -540,7 +560,7 @@
         print 'Percentage;Cumulative Time;Occurences;Query'
         for time, occ, rql in stat:
             print '%.2f;%.2f;%s;%s' % (time/total_time, time, occ, rql)
-        
+
 register_commands((UpdateCubicWebCatalogCommand,
                    UpdateTemplateCatalogCommand,
                    LiveServerCommand,
--- a/devtools/fake.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/devtools/fake.py	Fri Apr 24 19:46:47 2009 +0200
@@ -24,13 +24,13 @@
         self.apphome = apphome
         self._cubes = cubes
         self['auth-mode'] = 'cookie'
-        self['uid'] = None 
+        self['uid'] = None
         self['base-url'] = BASE_URL
         self['rql-cache-size'] = 100
-       
+
     def cubes(self, expand=False):
         return self._cubes
-    
+
     def sources(self):
         return {}
 
@@ -41,7 +41,7 @@
         self.properties = {'ui.encoding': 'UTF8',
                            'ui.language': 'en',
                            }
-        
+
     def property_value(self, key):
         return self.properties[key]
 
@@ -51,10 +51,10 @@
         'views' : [Mock(id='primary'), Mock(id='secondary'),
                          Mock(id='oneline'), Mock(id='list')],
         }
-    
+
     def registry_objects(self, name, oid=None):
         return self._registries[name]
-    
+
     def etype_class(self, etype):
         class Entity(dict):
             e_schema = self.schema[etype]
@@ -112,15 +112,15 @@
     def set_header(self, header, value):
         """set an output HTTP header"""
         pass
-    
+
     def add_header(self, header, value):
         """set an output HTTP header"""
         pass
-    
+
     def remove_header(self, header):
         """remove an output HTTP header"""
         pass
-    
+
     def get_header(self, header, default=None):
         """return the value associated with the given input header,
         raise KeyError if the header is not set
@@ -169,7 +169,7 @@
         self.is_internal_session = False
         self.is_super_session = self.user.eid == -1
         self._query_data = {}
-        
+
     def execute(self, *args):
         pass
     def commit(self, *args):
@@ -186,7 +186,7 @@
 
     def set_entity_cache(self, entity):
         pass
-    
+
 class FakeRepo(object):
     querier = None
     def __init__(self, schema, vreg=None, config=None):
@@ -199,8 +199,9 @@
 
     def internal_session(self):
         return FakeSession(self)
-    
-    def extid2eid(self, source, extid, etype, session, insert=True):
+
+    def extid2eid(self, source, extid, etype, session, insert=True,
+                  recreate=False):
         try:
             return self.extids[extid]
         except KeyError:
@@ -213,7 +214,7 @@
             self.eids[eid] = extid
             source.after_entity_insertion(session, extid, entity)
             return eid
-        
+
     def eid2extid(self, source, eid, session=None):
         return self.eids[eid]
 
@@ -228,7 +229,7 @@
     def __init__(self, uri):
         self.uri = uri
 
-        
+
 class FakePool(object):
     def source(self, uri):
         return FakeSource(uri)
--- a/devtools/fill.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/devtools/fill.py	Fri Apr 24 19:46:47 2009 +0200
@@ -236,7 +236,7 @@
                         returns acceptable values for this attribute
     """
     # XXX HACK, remove or fix asap
-    if etype in (('String', 'Int', 'Float', 'Boolean', 'Date', 'EGroup', 'EUser')):
+    if etype in (('String', 'Int', 'Float', 'Boolean', 'Date', 'CWGroup', 'CWUser')):
         return []
     queries = []
     for index in xrange(entity_num):
--- a/devtools/htmlparser.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/devtools/htmlparser.py	Fri Apr 24 19:46:47 2009 +0200
@@ -4,10 +4,7 @@
 
 from lxml import etree
 
-from cubicweb.view import STRICT_DOCTYPE, TRANSITIONAL_DOCTYPE, CW_XHTML_EXTENSIONS
-
-STRICT_DOCTYPE = str(STRICT_DOCTYPE % CW_XHTML_EXTENSIONS).strip()
-TRANSITIONAL_DOCTYPE = str(TRANSITIONAL_DOCTYPE % CW_XHTML_EXTENSIONS).strip()
+from cubicweb.view import STRICT_DOCTYPE, TRANSITIONAL_DOCTYPE
 
 ERR_COUNT = 0
 
@@ -35,10 +32,10 @@
 
     def preprocess_data(self, data):
         """used to fix potential blockquote mess generated by docutils"""
-        if STRICT_DOCTYPE not in data:
+        if str(STRICT_DOCTYPE) not in data:
             return data
         # parse using transitional DTD
-        data = data.replace(STRICT_DOCTYPE, TRANSITIONAL_DOCTYPE)
+        data = data.replace(str(STRICT_DOCTYPE), str(TRANSITIONAL_DOCTYPE))
         tree = etree.fromstring(data, self.parser)
         namespace = tree.nsmap.get(None)
         # this is the list of authorized child tags for <blockquote> nodes
@@ -54,7 +51,7 @@
             parent = blockquote.getparent()
             parent.remove(blockquote)
         data = etree.tostring(tree)
-        return '<?xml version="1.0" encoding="UTF-8"?>%s\n%s' % (STRICT_DOCTYPE, data)
+        return '<?xml version="1.0" encoding="UTF-8"?>%s\n%s' % (str(STRICT_DOCTYPE), data)
 
    
 class SaxOnlyValidator(Validator):
--- a/devtools/test/data/schema/relations.rel	Wed Apr 22 09:45:54 2009 +0200
+++ b/devtools/test/data/schema/relations.rel	Fri Apr 24 19:46:47 2009 +0200
@@ -23,11 +23,11 @@
 Project uses Project
 
 Version version_of Project inline
-Version todo_by EUser
+Version todo_by CWUser
 
 Comment about Bug inline
 Comment about Story inline
 Comment about Comment inline
 
-EUser interested_in Project
+CWUser interested_in Project
 
--- a/devtools/test/unittest_testlib.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/devtools/test/unittest_testlib.py	Fri Apr 24 19:46:47 2009 +0200
@@ -24,7 +24,7 @@
                 self.view('raising', self.execute('Bug B'), template=None)
             
             def test_correct_view(self):
-                self.view('primary', self.execute('EUser U'), template=None)
+                self.view('primary', self.execute('CWUser U'), template=None)
             
         tests = [MyWebTest('test_error_view'), MyWebTest('test_correct_view')]
         result = self.runner.run(TestSuite(tests))
--- a/doc/book/en/A020-tutorial.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/A020-tutorial.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -1,9 +1,9 @@
 .. -*- coding: utf-8 -*-
 
-.. _Overview:
+.. _Tutorial:
 
-Quick overview of `CubicWeb`
-============================
+Tutorial
+========
 
 `CubicWeb` is a semantic web application framework that favors reuse and
 object-oriented design.
@@ -17,6 +17,7 @@
 An `instance` is a specific installation of an application and includes
 configuration files.
 
+
 This tutorial will show how to create a `cube` and how to use it as an
 application to run an `instance`.
 
--- a/doc/book/en/A02a-create-cube.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/A02a-create-cube.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -24,8 +24,6 @@
 
 ::
 
-  from cubicweb.schema import format_constraint
-  
   class Blog(EntityType):
     title = String(maxsize=50, required=True)
     description = String()
@@ -63,9 +61,7 @@
   cubicweb-ctl create blog blogdemo
 
 
-This command will create a directory ``~/etc/cubicweb.d/blogdemo``
-which will contain all the configuration files required to start
-you web application.
+This command will create the corresponding database and initialize it.
 
 Welcome to your web application
 -------------------------------
--- a/doc/book/en/A02b-components.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/A02b-components.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -68,7 +68,7 @@
 
 Once you modified your data model, you need to synchronize the
 database with your model. For this purpose, `CubicWeb` provides
-a very usefull command ``cubicweb-ctl shell blogdemo`` which
+a very useful command ``cubicweb-ctl shell blogdemo`` which
 launches an interactive migration Python shell. (see 
 :ref:`cubicweb-ctl-shell` for more details))
 As you modified a relation from the `BlogEntry` schema,
--- a/doc/book/en/A03a-concepts.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/A03a-concepts.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -267,7 +267,7 @@
   * `set_header(header, value)`, adds an arbitrary header in the response
   * `cursor()` returns a RQL cursor on the session
   * `execute(*args, **kwargs)`, shortcut to ``.cursor().execute()``
-  * `property_value(key)`, properties management (`EProperty`)
+  * `property_value(key)`, properties management (`CWProperty`)
   * dictionary `data` to store data to share informations between components
     *while a request is executed*
 
--- a/doc/book/en/B0011-schema-stdlib.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/B0011-schema-stdlib.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -12,10 +12,10 @@
 ``````````````
 The available system entities are:
 
-* `EUser`, system users
-* `EGroup`, users groups
-* `EEType`, entity type
-* `ERType`, relation type
+* `CWUser`, system users
+* `CWGroup`, users groups
+* `CWEType`, entity type
+* `CWRType`, relation type
 
 * `State`, workflow state
 * `Transition`, workflow transition
@@ -24,8 +24,8 @@
 * `EmailAddress`, email address, used by the system to send notifications
   to the users and also used by others optionnals schemas
 
-* `EProperty`, used to configure the application
-* `EPermission`, used to configure the security of the application
+* `CWProperty`, used to configure the application
+* `CWPermission`, used to configure the security of the application
 
 * `Card`, generic documenting card
 * `Bookmark`, an entity type used to allow a user to customize his links within
--- a/doc/book/en/B0012-schema-definition.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/B0012-schema-definition.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -6,7 +6,9 @@
 An entity type is defined by a Python class which inherits from `EntityType`.
 The class definition contains the description of attributes and relations
 for the defined entity type.
-The class name corresponds to the entity type name.
+The class name corresponds to the entity type name. It is exepected to be
+defined in the module ``mycube.schema``.
+
 
 For example ::
 
@@ -21,14 +23,36 @@
     works_for = SubjectRelation('Company', cardinality='?*')
 
 
-* the name of the Python attribute corresponds to the name of the attribute
-  or the relation in `CubicWeb` application.
+The entity described above defines three attributes of type String,
+last_name, first_name and title, an attribute of type Date for the date of
+birth and a relation that connects a `Person` to another entity of type
+`Company` through the semantic `works_for`.
+
+The name of the Python attribute corresponds to the name of the attribute
+or the relation in `CubicWeb` application.
+
+Built-in types for attributes
+`````````````````````````````
 
-* all `CubicWeb` built-in types are available : `String`, `Int`, `Float`,
-  `Boolean`, `Date`, `Datetime`, `Time`, `Byte`; they are and implicitely
-  imported (as well as the special the function "_").
+All `CubicWeb` built-in types are available : `String`, `Int`, `Float`,
+`Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte` 
+and `Password`.
+They are implicitely imported (as well as the special the function "_"
+for translation :ref:`internationalization`).
+
+An attribute is defined in the schema as follows::
+    
+    attr_name = attr_type(properties*)
 
-* each entity type has at least the following meta-relations :
+where `attr_type` is one of the type listed above and `properties` is
+a list of  the attribute needs to statisfy (see :ref:`properties`
+for more details). 
+
+
+Meta-data
+`````````
+
+Each entity type has at least the following meta-relations :
 
   - `eid` (`Int`)
   
@@ -36,12 +60,12 @@
   
   - `modification_date` (`Datetime`)
   
-  - `created_by` (`EUser`) (which user created the entity)
+  - `created_by` (`CWUser`) (which user created the entity)
   
-  - `owned_by` (`EUser`) (to whom the entity belongs; by default the 
+  - `owned_by` (`CWUser`) (to whom the entity belongs; by default the 
      creator but not necessary, and it could have multiple owners)
      
-  - `is` (`EEType`)
+  - `is` (`CWEType`) (of which type the entity is)
 
 
 * relations can be defined by using `ObjectRelation` or `SubjectRelation`.
@@ -62,6 +86,11 @@
 * it is possible to use the attribute `meta` to flag an entity type as a `meta`
   (e.g. used to describe/categorize other entities)
 
+Optionnal properties
+````````````````````
+.. _properties:
+
+
 * optional properties for attributes and relations : 
 
   - `description` : a string describing an attribute or a relation. By default
@@ -95,7 +124,7 @@
     or not within all entities of the same type (false by default)
 
   - `indexed` : boolean indicating if an index needs to be created for this 
-    attribute in the database (false by default). This is usefull only if
+    attribute in the database (false by default). This is useful only if
     you know that you will have to run numerous searches on the value of this
     attribute.
 
@@ -165,7 +194,7 @@
     inlined = True
     cardinality = '?*'
     subject = '*'
-    object = 'EUser'
+    object = 'CWUser'
 
 In addition to the permissions, the properties of the relation types
 (shared also by all definition of relation of this type) are :
@@ -290,15 +319,15 @@
   - the permissions `add` and `delete` are equivalent. Only `add`/`read`
     are actually taken in consideration.
 
-In addition to that the entity type `EPermission` from the standard library
+In addition to that the entity type `CWPermission` from the standard library
 allow to build very complex and dynamic security architecture. The schema of
 this entity type is as follow : ::
 
-    class EPermission(MetaEntityType):
+    class CWPermission(MetaEntityType):
 	"""entity type that may be used to construct some advanced security configuration
 	"""
 	name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
-	require_group = SubjectRelation('EGroup', cardinality='+*',
+	require_group = SubjectRelation('CWGroup', cardinality='+*',
 					description=_('groups to which the permission is granted'))
 	require_state = SubjectRelation('State',
 				    description=_("entity'state in which the permission is applyable"))
@@ -338,14 +367,14 @@
 		       }
 	inlined = True
 
-This configuration indicates that an entity `EPermission` named
+This configuration indicates that an entity `CWPermission` named
 "add_version" can be associated to a project and provides rights to create
 new versions on this project to specific groups. It is important to notice that :
 
 * in such case, we have to protect both the entity type "Version" and the relation
   associating a version to a project ("version_of")
 
-* because of the genricity of the entity type `EPermission`, we have to execute
+* because of the genricity of the entity type `CWPermission`, we have to execute
   a unification with the groups and/or the states if necessary in the expression
   ("U in_group G, P require_group G" in the above example)
 
--- a/doc/book/en/B0020-define-workflows.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/B0020-define-workflows.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -69,7 +69,7 @@
   
   _ = unicode
 
-  moderators = add_entity('EGroup', name=u"moderators")
+  moderators = add_entity('CWGroup', name=u"moderators")
 
 This adds the `moderators` user group.
 
--- a/doc/book/en/B0030-data-as-objects.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/B0030-data-as-objects.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -7,12 +7,12 @@
 In this chapter, we will introduce the objects that are used to handle
 the data stored in the database.
 
-Classes `Entity` and `AnyEntity`
---------------------------------
+Class `Entity` and `AnyEntity`
+------------------------------
 
 To provide a specific behavior for each entity, we have to define
 a class inheriting from `cubicweb.entities.AnyEntity`. In general, we
-define this class in a module of `entities` package of an application
+define this class in a module of `mycube.entities` package of an application
 so that it will be available on both server and client side.
 
 The class `AnyEntity` is loaded dynamically from the class `Entity` 
@@ -114,6 +114,105 @@
   * `relation_vocabulary(rtype, targettype, x, limit=None)`, called
     internally by `subject_relation_vocabulary` and `object_relation_vocabulary`
 
+Class `TreeMixIn`
+-----------------
+
+This class provides a tree interface. This mixin has to be inherited 
+explicitly and configured using the tree_attribute, parent_target and 
+children_target class attribute to benefit from this default implementation.
+
+This class provides the following methods:
+
+  * `different_type_children(entities=True)`, returns children entities
+    of different type as this entity. According to the `entities` parameter, 
+    returns entity objects (if entity=True) or the equivalent result set.
+
+  * `same_type_children(entities=True)`, returns children entities of 
+    the same type as this entity. According to the `entities` parameter, 
+    return entity objects (if entity=True) or the equivalent result set.
+  
+  * `iterchildren( _done=None)`, iters on the children of the entity.
+  
+  * `prefixiter( _done=None)`
+  
+  * `path()`, returns the list of eids from the root object to this object.
+  
+  * `iterparents()`, iters on the parents of the entity.
+  
+  * `notification_references(view)`, used to control References field 
+    of email send on notification for this entity. `view` is the notification view.
+    Should return a list of eids which can be used to generate message ids
+    of previously sent email.
+
+`TreeMixIn` implements also the ITree interface (``cubicweb.interfaces``):
+
+  * `parent()`, returns the parent entity if any, else None (e.g. if we are on the
+    root)
+
+  * `children(entities=True, sametype=False)`, returns children entities
+    according to the `entities` parameter, return entity objects or the
+    equivalent result set.
+
+  * `children_rql()`, returns the RQL query corresponding to the children
+    of the entity.
+
+  * `is_leaf()`, returns True if the entity does not have any children.
+
+  * `is_root()`, returns True if the entity does not have any parent.
+
+  * `root()`, returns the root object of the tree representation of
+    the entity and its related entities.
+
+Example of use
+``````````````
+
+Imagine you defined three types of entities in your schema, and they
+relates to each others as follows in ``schema.py``::
+
+  class Entity1(EntityType):
+      title = String()
+      is_related_to = SubjectRelation('Entity2', 'subject')
+
+  class Entity2(EntityType):
+      title = String()
+      belongs_to = SubjectRelation('Entity3', 'subject')
+
+  class Entity3(EntityType):
+      name = String()
+
+You would like to create a view that applies to both entity types
+`Entity1` and `Entity2` and which lists the entities they are related to.
+That means when you view `Entity1` you want to list all `Entity2`, and
+when you view `Entity2` you want to list all `Entity3`.
+
+In ``entities.py``::
+
+  class Entity1(TreeMixIn, AnyEntity):
+      id = 'Entity1'
+      __implements__ = AnyEntity.__implements__ + (ITree,)
+      __rtags__ = {('is_related_to', 'Entity2', 'object'): 'link'}
+      tree_attribute = 'is_related_to'
+
+      def children(self, entities=True):
+          return self.different_type_children(entities)
+
+  class Entity2(TreeMixIn, AnyEntity):
+      id = 'Entity2'
+      __implements__ = AnyEntity.__implements__ + (ITree,)
+      __rtags__ = {('belongs_to', 'Entity3', 'object'): 'link'}
+      tree_attribute = 'belongs_to'
+
+      def children(self, entities=True):
+          return self.different_type_children(entities)
+
+Once this is done, you can define your common view as follows::
+
+  class E1E2CommonView(baseviews.PrimaryView):
+      accepts = ('Entity11, 'Entity2')
+      
+      def render_entity_relations(self, entity, siderelations):
+          self.wview('list', entity.children(entities=False))
+
 
 *rtags*
 -------
--- a/doc/book/en/B0031-define-entities.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/B0031-define-entities.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -133,7 +133,7 @@
 The method ``filterform_vocabulary(rtype, x, var, rqlst, args, cachekey)`` takes 
 the name of a relation and the target as parameters,
 [XXX what does it mean ?]
- which indicates of the
+which indicates of the
 entity on which we apply the method is subject or object of the relation. It
 has to return:
 
--- a/doc/book/en/B0040-migration.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/B0040-migration.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -208,3 +208,6 @@
 * `add_entity_type_table(etype, commit=True)`
 * `add_relation_type_table(rtype, commit=True)`
 * `uninline_relation(rtype, commit=True)`
+
+
+[FIXME] Add explanation on how to use cubicweb-ctl shell
--- a/doc/book/en/B1020-define-views.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/B1020-define-views.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -13,6 +13,8 @@
 understanding of the classes and methods available, then detail the view
 selection principle which makes `CubicWeb` web interface very flexible.
 
+A `View` is an object applied to another object such as an entity.
+
 Basic class for views
 ---------------------
 
@@ -72,6 +74,7 @@
 * `AnyRsetView`, view applied to any result set 
 * `EmptyRsetView`, view applied to an empty result set
 
+
 The selection view principle
 ----------------------------
 
@@ -96,6 +99,9 @@
 
 Registerer
 ``````````
+[Registerers are deprecated: they will soon disappear for explicite 
+registration...] 
+
 A view is also customizable through its attribute ``__registerer__``.
 This is used at the time the application is launched to manage how
 objects (views, graphic components, actions, etc.) 
@@ -110,9 +116,6 @@
 when they are selected for display.
 
 
-`CubicWeb` provides a lot of standard views for the default class
-`EntityType`. You can find them in ``cubicweb/web/views/``.
-
 .. include:: B1022-views-stdlib.en.txt
 
 
@@ -150,12 +153,122 @@
         search_states = ('linksearch',)
 
     
+Rendering methods and attributes for ``PrimaryView``
+----------------------------------------------------
 
+By default, `CubicWeb` provides a primary view for each new entity type
+you create. The first view you might be interested in modifying.
 
+Let's have a quick look at the EntityView ``PrimaryView`` as well as
+its rendering method::
+    
+    class PrimaryView(EntityView):
+    """the full view of an non final entity"""
+        id = 'primary'
+        title = _('primary')
+        show_attr_label = True
+        show_rel_label = True
+        skip_none = True
+        skip_attrs = ('eid', 'creation_date', 'modification_date')
+        skip_rels = ()
+        main_related_section = True
+
+        ...
+
+    def cell_call(self, row, col):
+        self.row = row
+        self.render_entity(self.complete_entity(row, col))
+
+    def render_entity(self, entity):
+        """return html to display the given entity"""
+        siderelations = []
+        self.render_entity_title(entity)
+        self.render_entity_metadata(entity)
+        # entity's attributes and relations, excluding meta data
+        # if the entity isn't meta itself
+        self.w(u'<div>')
+        self.w(u'<div class="mainInfo">')
+        self.render_entity_attributes(entity, siderelations)
+        self.w(u'</div>')
+        self.content_navigation_components('navcontenttop')
+        if self.main_related_section:
+            self.render_entity_relations(entity, siderelations)
+        self.w(u'</div>')
+        # side boxes
+        self.w(u'<div class="primaryRight">')
+        self.render_side_related(entity, siderelations)
+        self.w(u'</div>')
+        self.w(u'<div class="clear"></div>')
+        self.content_navigation_components('navcontentbottom')
+
+    ...
+
+``cell_call`` is executed for each entity of a result set and apply ``render_entity``.
+
+The methods you want to modify while customizing a ``PrimaryView`` are:
+
+*render_entity_title(self, entity)* 
+    Renders the entity title based on the assumption that the method 
+    ``def content_title(self)`` is implemented for the given entity type.
+
+*render_entity_metadata(self, entity)*
+    Renders the entity metadata based on the assumption that the method
+    ``def summary(self)`` is implemented for the given entity type.
+
+*render_entity_attributes(self, entity, siderelations)*
+    Renders all the attribute of an entity with the exception of attribute
+    of type `Password` and `Bytes`.
+
+*content_navigation_components(self, context)*
+    This method is applicable only for entity type implementing the interface 
+    `IPrevNext`. This interface is for entities which can be linked to a previous
+    and/or next entity. This methods will render the navigation links between
+    entities of this type, either at the top or at the bottom of the page
+    given the context (navcontent{top|bottom}).
+
+*render_entity_relations(self, entity, siderelations)*
+    Renders all the relations of the entity in the main section of the page.
+        
+*render_side_related(self, entity, siderelations)*
+    Renders all the relations of the entity in a side box. This is equivalent
+    to *render_entity_relations* in addition to render the relations
+    in a box.
+
+Also, please note that by setting the following attributes in you class,
+you can already customize some of the rendering:
+
+*show_attr_label*
+    Renders the attribute label next to the attribute value if set to True.
+    Otherwise, does only display the attribute value.
+
+*show_rel_label* 
+    Renders the relation label next to the relation value if set to True.
+    Otherwise, does only display the relation value.
+
+*skip_none*
+    Does not render an attribute value that is None if set to True.
+
+*skip_attrs*
+    Given a list of attributes name, does not render the value of the attributes listed.
+
+*skip_rels*
+    Given a list of relations name, does not render the relations listed.
+
+*main_related_section*
+    Renders the relations of the entity if set to True.
+
+A good practice is for you to identify the content of your entity type for which
+the default rendering does not answer your need so that you can focus on the specific
+method (from the list above) that needs to be modified. We do not recommand you to
+overwrite ``render_entity`` as you might potentially loose the benefits of the side
+boxes handling.
 
 Example of a view customization
 -------------------------------
 
+[FIXME] XXX Example needs to be rewritten as it shows how to modify cell_call which
+contredicts our advise of not modifying it.
+
 We'll show you now an example of a ``primary`` view and how to customize it.
 
 If you want to change the way a ``BlogEntry`` is displayed, just override 
--- a/doc/book/en/B1022-views-stdlib.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/B1022-views-stdlib.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -2,6 +2,10 @@
 
 Predefined views in the library
 ```````````````````````````````
+
+`CubicWeb` provides a lot of standard views. You can find them in
+``cubicweb/web/views/``.
+
 A certain number of views are used to build the web interface, which apply
 to one or more entities. Their identifier is what distinguish them from
 each others and the main ones are:
@@ -56,7 +60,8 @@
   This view displays usually a side box of some related entities 
   in a primary view.
 
-Start view:
+  
+Start view (e.g. views that don't apply to a result set):
 
 *index*
     This view defines the home page of your application. It does not require
--- a/doc/book/en/B1070-ui-components.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/B1070-ui-components.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -9,6 +9,6 @@
 ---------------------
 XXXFILLME
 
-EProperty
+CWProperty
 ---------
 XXXFILLME
--- a/doc/book/en/B1090-internationalization.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/B1090-internationalization.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -1,9 +1,9 @@
 .. -*- coding: utf-8 -*-
 
-.. _internationalization:
+.. _internationalisation:
 
 
-Internationalization
+Internationalisation
 ====================
 
 Cubicweb fully supports the internalization of it's content and interface.
--- a/doc/book/en/C000-administration.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/C000-administration.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -13,7 +13,8 @@
    :maxdepth: 1
 
    C010-setup.en.txt
-   C020-site-config.en.txt
-   C030-instance-config.en.txt
-   C040-rql.en.txt
+   C020-create-instance.en.txt
+   C030-site-config.en.txt
+   C040-instance-config.en.txt
+   C050-rql.en.txt
 
--- a/doc/book/en/C010-setup.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/C010-setup.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -6,7 +6,202 @@
 Installation and set-up of a `CubicWeb` environment
 ===================================================
 
-.. include:: C011-installation.en.txt
-.. include:: C012-create-instance.en.txt
-.. include:: C013-cubicweb-ctl.en.txt
+Installation of `Cubicweb` and its dependencies
+-----------------------------------------------
+
+`CubicWeb` is packaged for Debian and Ubuntu, but can be installed from source
+using a tarball or the Mercurial version control system.
+
+.. _DebianInstallation:
+
+Debian and Ubuntu packages
+```````````````````````````
+
+Depending on the distribution you are using, add the appropriate line to your list
+of sources (for example by editing ``/etc/apt/sources.list``).
+
+For Debian Lenny::
+
+  deb http://ftp.logilab.org/dists/ lenny/
+
+For Debian Sid::
+
+  deb http://ftp.logilab.org/dists/ sid/
+
+For Ubuntu Hardy::
+
+  deb http://ftp.logilab.org/dists/ hardy/
+
+
+You can now install the required packages with the following command::
+
+  apt-get update 
+  apt-get install cubicweb cubicweb-dev
+
+`cubicweb` installs the framework itself, allowing you to create
+new applications.
+
+`cubicweb-dev` installs the development environment allowing you to
+develop new cubes.
+
+There is also a wide variety of cubes listed on http://www.cubicweb.org/Project available as debian packages and tarball.
+
+
+Install from source
+```````````````````
+
+You can download the archive containing the sources from our `ftp site`_ at::
+
+  http://ftp.logilab.org/pub/cubicweb/
+
+.. _`ftp site`: http://ftp.logilab.org/pub/cubicweb/
+
+or keep up to date with on-going development by using Mercurial and its forest
+extension::
+
+  hg fclone http://www.logilab.org/hg/forests/cubicweb
+
+See :ref:`MercurialPresentation` for more details about Mercurial.
+
+Postgres installation
+`````````````````````
+
+Please refer to the `Postgresql project online documentation`_.
+
+.. _`Postgresql project online documentation`: http://www.postgresql.org/
+
+You need to install the three following packages: `postgres-8.3`,
+`postgres-contrib-8.3` and `postgresql-plpython-8.3`.
+
+
+Then you can install:
+
+* `pyro` if you wish the repository to be accessible through Pyro
+  or if the client and the server are not running on the same machine
+  (in which case the packages will have to be installed on both
+  machines)
+
+* `python-ldap` if you plan to use a LDAP source on the server
+
+.. _ConfigurationEnv:
+
+Environment configuration
+-------------------------
+
+If you installed `CubicWeb` by cloning the Mercurial forest, then you
+will need to update the environment variable PYTHONPATH by adding  
+the path to the forest ``cubicweb``:
+
+Add the following lines to either `.bashrc` or `.bash_profile` to configure
+your development environment ::
+  
+  export PYTHONPATH=/full/path/to/cubicweb-forest
+
+If you installed the debian packages, no configuration is required.
+Your new cubes will be placed in `/usr/share/cubicweb/cubes` and
+your applications will be placed in `/etc/cubicweb.d`.
+
+To use others directories then you will have to configure the
+following environment variables as follows::
 
+    export CW_CUBES_PATH=~/lib/cubes
+    export CW_REGISTRY=~/etc/cubicweb.d/
+    export CW_INSTANCE_DATA=$CW_REGISTRY
+    export CW_RUNTIME=/tmp
+
+.. note::
+    The values given above are our suggestions but of course
+    can be different.
+
+
+Databases configuration
+-----------------------
+
+
+
+.. _ConfigurationPostgres:
+
+Postgres configuration
+``````````````````````
+
+.. note::
+    If you already have an existing cluster and postgres server
+    running, you do not need to execute the initilization step
+    of your Postgres database.
+
+* First, initialize the database Postgres with the command ``initdb``.
+  ::
+
+    $ initdb -D /path/to/pgsql
+
+  Once initialized, start the database server Postgres 
+  with the command::
+  
+    $ postgres -D /path/to/psql
+
+  If you cannot execute this command due to permission issues, please
+  make sure that your username has write access on the database.
+  ::
+ 
+    $ chown username /path/to/pgsql
+
+* The database authentication can be either set to `ident sameuser`
+  or `md5`. 
+  If set to `md5`, make sure to use an existing user
+  of your database.
+  If set to `ident sameuser`, make sure that your
+  client's operating system user name has a matching user in
+  the database. If not, please do as follow to create a user::
+    
+    $ su
+    $ su - postgres
+    $ createuser -s -P username
+
+  The option `-P` (for password prompt), will encrypt the password with
+  the method set in the configuration file ``pg_hba.conf``. 
+  If you do not use this option `-P`, then the default value will be null
+  and you will need to set it with::
+    
+    $ su postgres -c "echo ALTER USER username WITH PASSWORD 'userpasswd' | psql"
+
+  This login/password will be requested when you will create an
+  instance with `cubicweb-ctl create` to initialize the database of
+  your application.
+
+.. note::
+    The authentication method can be configured in ``pg_hba.conf``.
+
+
+.. FIXME Are these steps really necessary? It seemed to work without.
+
+* Installation of plain-text index extension ::
+
+    cat /usr/share/postgresql/8.3/contrib/tsearch2.sql | psql -U username template1
+
+* Installation of plpythonu language by default ::
+
+    createlang -U pgadmin plpythonu template1
+
+MySql configuration
+```````````````````
+Yout must add the following lines in /etc/mysql/my.cnf file::
+
+    transaction-isolation = READ-COMMITTED
+    default-storage-engine=INNODB
+    default-character-set=utf8
+    max_allowed_packet = 128M
+
+Pyro configuration
+------------------
+
+If you use Pyro, it is required to have a name server Pyro running on your
+network (by default it is detected by a broadcast request).
+
+To do so, you need to :
+
+* launch the server manually before starting cubicweb as a server with
+  `pyro-nsd start`
+
+* edit the file ``/etc/default/pyro-nsd`` so that the name server pyro
+  will be launched automatically when the machine fire up
+
--- a/doc/book/en/C011-installation.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _CubicWebInstallation:
-
-Installation
-============
-
-Installation of `Cubicweb` and its dependencies
------------------------------------------------
-
-`CubicWeb` is packaged for Debian and Ubuntu, but can be installed from source
-using a tarball or the Mercurial version control system.
-
-Debian and Ubuntu packages
-```````````````````````````
-Depending on the distribution you are using, add the appropriate line to your list
-of sources (for example by editing ``/etc/apt/sources.list``).
-
-For Debian Lenny::
-
-  deb http://ftp.logilab.org/dists/ lenny/
-
-For Debian Sid::
-
-  deb http://ftp.logilab.org/dists/ sid/
-
-For Ubuntu Hardy::
-
-  deb http://ftp.logilab.org/dists/ hardy/
-
-
-You can now install the required packages with the following command::
-
-  apt-get update 
-  apt-get install cubicweb
-  apt-get install cubicweb-dev
-
-`cubicweb` installs the framework itself, allowing you to create
-new applications.
-
-`cubicweb-dev` installs the development environment allowing you to
-develop new cubes.
-
-There is also a wide variety of cubes listed on http://www.cubicweb.org/Project available as debian packages and tarball.
-
-
-Install from source
-```````````````````
-
-You can download the archive containing the sources from our `ftp site`_ at::
-
-  http://ftp.logilab.org/pub/cubicweb/
-
-.. _`ftp site`: http://ftp.logilab.org/pub/cubicweb/
-
-or keep up to date with on-going development by using Mercurial and its forest
-extension::
-
-  hg fclone http://www.logilab.org/hg/forests/cubicweb
-
-See :ref:`MercurialPresentation` for more details about Mercurial.
-
-Postgres installation
-`````````````````````
-
-Please refer to the `Postgresql project online documentation`_.
-
-.. _`Postgresql project online documentation`: http://www.postgresql.org/
-
-You need to install the three following packages: `postgres-8.3`,
-`postgres-contrib-8.3` and `postgresql-plpython-8.3`.
-
-
-Then you can install:
-
-* `pyro` if you wish the repository to be accessible through Pyro
-  or if the client and the server are not running on the same machine
-  (in which case the packages will have to be installed on both
-  machines)
-
-* `python-ldap` if you plan to use a LDAP source on the server
-
-.. _ConfigurationEnv:
-
-Environment configuration
--------------------------
-
-If you installed `CubicWeb` by cloning the Mercurial forest, then you
-will need to update the environment variable PYTHONPATH by adding  
-the path to the forest ``cubicweb``:
-
-Add the following lines to either `.bashrc` or `.bash_profile` to configure
-your development environment ::
-  
-  export PYTHONPATH=/full/path/to/cubicweb-forest
-
-If you installed the debian packages, no configuration is required.
-Your new cubes will be placed in `/usr/share/cubicweb/cubes` and
-your applications will be placed in `/etc/cubicweb.d`.
-
-To use others directories then you will have to configure the
-following environment variables as follows::
-
-    export CW_CUBES_PATH=~/lib/cubes
-    export CW_REGISTRY=~/etc/cubicweb.d/
-    export CW_INSTANCE_DATA=$CW_REGISTRY
-    export CW_RUNTIME=/tmp
-
-.. note::
-    The values given above are our suggestions but of course
-    can be different.
-
-.. _ConfigurationPostgres:
-
-Postgres configuration
-----------------------
-
-.. note::
-    If you already have an existing cluster and postgres server
-    running, you do not require to execute the initilization step
-    of your Postgres database.
-
-* First you have to initialize the database Postgres with the command ``initdb``.
-  ::
-
-    $ initdb -D /path/to/pgsql
-
-  Once initialized, you can launch the database server Postgres 
-  with the command::
-  
-    $ postgres -D /path/to/psql
-
-  If you cannot execute this command due to permission issues, please
-  make sure that your username has write access on the database.
-  ::
- 
-    $ chown username /path/to/pgsql
-
-* The database authentication can be either set to `ident sameuser`
-  or `md5`. 
-  If set to `md5`, make sure to use an existing user
-  of your database.
-  If set to `ident sameuser`, make sure that your
-  client's operating system user name has a matching user in
-  the database. If not, please do as follow to create a user::
-    
-    $ su
-    $ su - postgres
-    $ createuser -s username
-
-  If created with the options -P (for password prompt, 
-  ``createuser -s -P username``), the password will be encrypted with
-  the method set in the configuration file ``pg_hba.conf``. 
-  If you do not use this option, then the default value will be null
-  and this require to set the password in the database itself.
-  To do so: ::
-    
-    $ su 
-    $ su - postgres
-    $ psql
-
-  And then execute de following query::
-    
-    ALTER USER username WITH PASSWORD `password`
-
-  This login/password will be requested when you will create an
-  instance with `cubicweb-ctl create` to initialize the database of
-  your application.
-
-.. note::
-    The authentication method can be configured in ``pg_hba.conf``.
-
-
-.. FIXME Are these steps really necessary? It seemed to work without.
-
-* Installation of plain-text index extension ::
-
-    cat /usr/share/postgresql/8.3/contrib/tsearch2.sql | psql -U username template1
-
-* Installation of plpythonu language by default ::
-
-    createlang -U pgadmin plpythonu template1
-
-
-Pyro configuration
-------------------
-
-If you use Pyro, it is required to have a name server Pyro running on your
-network (by default it is identified by a broadcast request).
-
-To do so, you need to :
-
-* launch the server manually before starting cubicweb with `pyro-ns`
-
-* launch the server manually before starting cubicweb as a server with
-  `pyro-nsd start`
-
-* edit the file ``/etc/default/pyro-nsd`` so that the name server pyro
-  will be launched automatically when the machine fire up
-
-
--- a/doc/book/en/C012-create-instance.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Creation of your first instance
-===============================
-
-What is an instance?
---------------------
-
-A `CubicWeb` instance is a directory in ``~/etc/cubicweb.d``
-which enables us to run a web application. An instance is based on
-one or more cubes.
-
-An instance is a container that refers to cubes and configuration 
-parameters for your web application.
-
-We recommand not to define schema, entities or views in the instance
-file system itself but in the cube, in order to maintain re-usability of
-entities and their views. We strongly recommand to develop cubes which
-could be used in other instances (modular approach).
-
-
-What is a cube?
----------------
-
-A cube defines entities, their views, their schemas and workflows
-in an independant directory located in ``/path/to/forest/cubicweb/cubes/``
-for a Mercurial installation or in ``/usr/share/cubicweb/cubes`` for
-a debian package installation.
-
-When an instance is created, you list one or more cubes that your instance
-will use. Using a cube means having the entities defined in your cube's schema
-available in your instance as well as their views and workflows.
-
-.. note::
-   The commands used below are more detailled in the section dedicated to 
-   :ref:`cubicweb-ctl`.
-
-
-Create a cube
--------------
-
-Let's start by creating the cube environment in which we will develop ::
-
-  cd ~/hg
-
-  cubicweb-ctl newcube mycube
-
-  # answer questions 
-  hg init moncube
-  cd mycube
-  hg add .
-  hg ci
-
-If all went well, you should see the cube you just create in the list
-returned by `cubicweb-ctl list` in the section *Available components*,
-and if it is not the case please refer to :ref:`ConfigurationEnv`.
-
-To use a cube, you have to list it in the variable ``__use__``
-of the file ``__pkginfo__.py`` of the instance.
-This variable is used for the instance packaging (dependencies
-handled by system utility tools such as APT) and the usable cubes
-at the time the base is created (import_erschema('MyCube') will
-not properly work otherwise).
-
-.. note::
-    Please note that if you do not wish to use default directory
-    for your cubes library, then you want to use the option
-    --directory to specify where you would like to place
-    the source code of your cube:
-    ``cubicweb-ctl newcube --directory=/path/to/cubes/library cube_name``
-
-Instance creation
------------------
-
-Now that we created our cube, we can create an instance to view our
-application in a web browser. To do so we will use a `all-in-on` 
-configuration to simplify things ::
-
-  cubicweb-ctl create -c all-in-one mycube myinstance
-
-.. note::
-  Please note that we created a new cube for a demo purpose but
-  you could have use an existing cube available in our standard library
-  such as blog or person for example.
-
-A serie of questions will be prompted to you, the default answer is usually
-sufficient. You can anyway modify the configuration later on by editing
-configuration files. When a user/psswd is requested to access the database
-please use the login you create at the time you configured the database
-(:ref:`ConfigurationPostgres`).
-
-It is important to distinguish here the user used to access the database and
-the user used to login to the cubicweb application. When a `CubicWeb` application
-starts, it uses the login/psswd for the database to get the schema and handle
-low level transaction. But, when ``cubicweb-ctl create`` asks for
-a manager login/psswd of `CubicWeb`, it refers to an application user you will
-use during the development to administrate your web application. It will be 
-possible, later on, to create others users for your final web application.
-
-When this command is completed, the definition of your instance is
-located in *~/etc/cubicweb.d/myinstance/*. To launch it, you just type ::
-
-  cubicweb-ctl start -D myinstance
-
-The option `-D` specify the *debug mode* : the instance is not running in
-server mode and does not disconnect from the termnial, which simplifies debugging
-in case the instance is not properly launched. You can see how it looks by
-visiting the URL `http://localhost:8080` (the port number depends of your 
-configuration). To login, please use the cubicweb administrator login/psswd you 
-defined when you created the instance.
-
-To shutdown the instance, Crtl-C in the terminal window is enough.
-If you did not use the option `-D`, then type ::
-
-  cubicweb-ctl stop myinstance
-
-This is it! All is settled down to start developping your data model...
-
-
-Usage of `cubicweb-liveserver`
-``````````````````````````````
-
-To quickly test a new cube, you can also use the script `cubicweb-liveserver`
-which allows to create an application in memory (use of SQLite database by 
-default) and make it accessible through a web server ::
-
-  cubicweb-ctl live-server mycube
-
-or by using an existing database (SQLite or Postgres)::
-
-  cubicweb-ctl live-server -s myfile_sources mycube
-
--- a/doc/book/en/C013-cubicweb-ctl.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _cubicweb-ctl:
-
-``cubicweb-ctl`` tool
-=====================
-
-`cubicweb-ctl` is the swiss knife to manage `CubicWeb` instances.
-The general syntax is ::
-
-  cubicweb-ctl <command> [options command] <arguments commands>
-
-To view available commands ::
-
-  cubicweb-ctl
-  cubicweb-ctl --help
-
-Please note that the commands available depends on the `CubicWeb` packages
-and cubes that have been installed.
-
-To view the help menu on specific command ::
-
-  cubicweb-ctl <command> --help
-
-Command to create a cube
-------------------------
-
-* ``newcube``, create a new cube on the file system based on the name
-  given in the parameters. This command create a cube from an application
-  skeleton that includes default files required for debian packaging.
-  
-
-Command to create an instance
------------------------------
-* ``create``, creates the files for the instance configuration
-* ``db-create``, creates the system database of an instance (tables and
-  extensions only)
-* ``db-init``, initializes the system database of an instance
-  (schema, groups, users, workflows...)
-
-By default, those three commandes are encapsulated in ``create`` so
-that they can be executed consecutively.
-
-Command to create an instance for Google AppEngine datastore source
--------------------------------------------------------------------
-* ``newgapp``, creates the configuration files for an instance
-
-This command needs to be followed by the commands responsible for
-the database initialization. As those are specific to the `datastore`,
-specific Google AppEgine database, they are not available for now
-in cubicweb-ctl, but they are available in the instance created.
-
-For more details, please see :ref:`gaecontents` .
-
-Commands to launch instance
----------------------------
-* ``start``, starts one or more or all instances
-* ``stop``, stops one or more or all instances
-* ``restart``, restarts one or more or all instances
-* ``status``, returns the status of the instance
-
-Commands to maintain instances
-------------------------------
-* ``upgrade``, launches the existing instances migration when a new version
-  of `CubicWeb` or the cubes installed is available
-* ``shell``, opens a migration shell for manual maintenance of the instance
-  (see :ref:`cubicweb-ctl-shell` for more details)
-* ``db-dump``, creates a dump of the system database
-* ``db-restore``, restores a dump of the system database
-* ``db-check``, checks data integrity of an instance. If the automatic correction
-  is activated, it is recommanded to create a dump before this operation.
-* ``schema-sync``, synchronizes the persistent schema of an instance with
-  the application schema. It is recommanded to create a dump before this operation.
-
-Commands to maintain i18n catalogs
-----------------------------------
-* ``i18nlibupdate``, regenerates messages catalogs of the `CubicWeb` library
-* ``i18nupdate``, regenerates the messages catalogs of a cube
-* ``i18ncompile``, recompiles the messages catalogs of an instance. 
-  This is automatically done while upgrading.
-
-Cf :ref:`Internationalisation`.
-
-Other commands
---------------
-* ``list``, provides a list of the available configuration, cubes
-  and instances.
-* ``delete``, deletes an instance (configuration files and database)
-
-
-.. _cubicweb-ctl-shell:
-
-``cubicweb-ctl shell`` addon
-----------------------------
-
-This migration shell provides an interactive interface to all
-the migrations functions described in the chapter :ref:`migration`.
-
-Usage
-`````
-::
-  
-  ``cubicweb-ctl shell myapp``
-
-Examples
---------
-
-Create an instance from an existing cube
-````````````````````````````````````````
-
-To create an instance from an existing cube, execute the following
-command ::
-
-   cubicweb-ctl create <cube_name> <instance_name>
-
-This command will create the configuration files of an instance in
-``~/etc/cubicweb.d/<instance_name>``.
-The tool ``cubicweb-ctl`` allows you to execute the command ``db-create``
-and ``db-init`` when you run ``create`` so that you can complete an
-instance creation in a single command.
-
-If you decide not to execut those commands while ``cubicweb-ctl create``,
-then you will have to execute them seperately(``cubicweb-ctl db-create``,
-``cubicweb-ctl db-init`` ) otherwise your installation will not be complete
-and you will not be able to launch your instance.
-
-
-Creation of an instance from a new cube
-```````````````````````````````````````
-
-Create first your new cube cube ::
-
-   cubicweb-ctl newcube <mycube>
-
-This will create a new cube in ``/path/to/forest/cubicweb/cubes/<mycube>``
-for a Mercurial forest installation, or in ``/usr/share/cubicweb/cubes``
-for a debian packages installation, and then create an instance as 
-explained just above.
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C020-create-instance.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,132 @@
+.. -*- coding: utf-8 -*-
+
+Creation of your first instance
+===============================
+
+What is an instance?
+--------------------
+
+A `CubicWeb` instance is a directory in ``~/etc/cubicweb.d``
+which enables us to run a web application. An instance is based on
+a cube.
+
+An instance is a container that refers to cubes and configuration 
+parameters for your web application.
+
+We recommand not to define schema, entities or views in the instance
+file system itself but in the cube, in order to maintain re-usability of
+entities and their views. We strongly recommand to develop cubes which
+could be used in other instances (modular approach).
+
+
+What is a cube?
+---------------
+
+A cube defines entities, their views, their schemas and workflows
+in an independant directory located in ``/path/to/forest/cubicweb/cubes/``
+for a Mercurial installation or in ``/usr/share/cubicweb/cubes`` for
+a debian package installation.
+
+When an instance is created, you list one or more cubes that your instance
+will use. Using a cube means having the entities defined in your cube's schema
+available in your instance as well as their views and workflows.
+
+.. note::
+   The commands used below are more detailled in the section dedicated to 
+   :ref:`cubicweb-ctl`.
+
+
+Create a cube
+-------------
+
+Let's start by creating the cube environment in which we will develop ::
+
+  cd ~/hg
+
+  cubicweb-ctl newcube mycube
+
+  # answer questions 
+  hg init moncube
+  cd mycube
+  hg add .
+  hg ci
+
+If all went well, you should see the cube you just create in the list
+returned by `cubicweb-ctl list` in the section *Available components*,
+and if it is not the case please refer to :ref:`ConfigurationEnv`.
+
+To use a cube, you have to list it in the variable ``__use__``
+of the file ``__pkginfo__.py`` of the instance.
+This variable is used for the instance packaging (dependencies
+handled by system utility tools such as APT) and the usable cubes
+at the time the base is created (import_erschema('MyCube') will
+not properly work otherwise).
+
+.. note::
+    Please note that if you do not wish to use default directory
+    for your cubes library, then you want to use the option
+    --directory to specify where you would like to place
+    the source code of your cube:
+    ``cubicweb-ctl newcube --directory=/path/to/cubes/library cube_name``
+
+Instance creation
+-----------------
+
+Now that we created our cube, we can create an instance to view our
+application in a web browser. To do so we will use a `all-in-on` 
+configuration to simplify things ::
+
+  cubicweb-ctl create -c all-in-one mycube myinstance
+
+.. note::
+  Please note that we created a new cube for a demo purpose but
+  you could have use an existing cube available in our standard library
+  such as blog or person for example.
+
+A serie of questions will be prompted to you, the default answer is usually
+sufficient. You can anyway modify the configuration later on by editing
+configuration files. When a user/psswd is requested to access the database
+please use the login you create at the time you configured the database
+(:ref:`ConfigurationPostgres`).
+
+It is important to distinguish here the user used to access the database and
+the user used to login to the cubicweb application. When a `CubicWeb` application
+starts, it uses the login/psswd for the database to get the schema and handle
+low level transaction. But, when ``cubicweb-ctl create`` asks for
+a manager login/psswd of `CubicWeb`, it refers to an application user you will
+use during the development to administrate your web application. It will be 
+possible, later on, to create others users for your final web application.
+
+When this command is completed, the definition of your instance is
+located in *~/etc/cubicweb.d/myinstance/*. To launch it, you just type ::
+
+  cubicweb-ctl start -D myinstance
+
+The option `-D` specify the *debug mode* : the instance is not running in
+server mode and does not disconnect from the termnial, which simplifies debugging
+in case the instance is not properly launched. You can see how it looks by
+visiting the URL `http://localhost:8080` (the port number depends of your 
+configuration). To login, please use the cubicweb administrator login/psswd you 
+defined when you created the instance.
+
+To shutdown the instance, Crtl-C in the terminal window is enough.
+If you did not use the option `-D`, then type ::
+
+  cubicweb-ctl stop myinstance
+
+This is it! All is settled down to start developping your data model...
+
+
+Usage of `cubicweb-liveserver`
+``````````````````````````````
+
+To quickly test a new cube, you can also use the script `cubicweb-liveserver`
+which allows to create an application in memory (use of SQLite database by 
+default) and make it accessible through a web server ::
+
+  cubicweb-ctl live-server mycube
+
+or by using an existing database (SQLite or Postgres)::
+
+  cubicweb-ctl live-server -s myfile_sources mycube
+
--- a/doc/book/en/C020-site-config.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-User interface for web site configuration
-=========================================
-
-.. image:: images/lax-book.03-site-config-panel.en.png
-
-This panel allows you to configure the appearance of your application site.
-Six menus are available and we will go through each of them to explain how
-to use them.
-
-Navigation
-~~~~~~~~~~
-This menu provides you a way to adjust some navigation options depending on
-your needs, such as the number of entities to display by page of results.
-Follows the detailled list of available options :
-  
-* navigation.combobox-limit : maximum number of entities to display in related
-  combo box (sample format: 23)
-* navigation.page-size : maximum number of objects displayed by page of results 
-  (sample format: 23)
-* navigation.related-limit : maximum number of related entities to display in 
-  the primary view (sample format: 23)
-* navigation.short-line-size : maximum number of characters in short description
-  (sample format: 23)
-
-UI
-~~
-This menu provides you a way to customize the user interface settings such as
-date format or encoding in the produced html.
-Follows the detailled list of available options :
-
-* ui.date-format : how to format date in the ui ("man strftime" for format description)
-* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
-  description)
-* ui.default-text-format : default text format for rich text fields.
-* ui.encoding : user interface encoding
-* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor).
-  You should also select text/html as default text format to actually get fckeditor.
-* ui.float-format : how to format float numbers in the ui
-* ui.language : language of the user interface
-* ui.main-template : id of main template used to render pages
-* ui.site-title	: site title, which is displayed right next to the logo in the header
-* ui.time-format : how to format time in the ui ("man strftime" for format description)
-
-
-Actions
-~~~~~~~
-This menu provides a way to configure the context in which you expect the actions
-to be displayed to the user and if you want the action to be visible or not. 
-You must have notice that when you view a list of entities, an action box is 
-available on the left column which display some actions as well as a drop-down 
-menu for more actions. 
-
-The context available are :
-
-* mainactions : actions listed in the left box
-* moreactions : actions listed in the `more` menu of the left box
-* addrelated : add actions listed in the left box
-* useractions : actions listed in the first section of drop-down menu 
-  accessible from the right corner user login link
-* siteactions : actions listed in the second section of drop-down menu
-  accessible from the right corner user login link
-* hidden : select this to hide the specific action
-
-Boxes
-~~~~~
-The application has already a pre-defined set of boxes you can use right away. 
-This configuration section allows you to place those boxes where you want in the
-application interface to customize it. 
-
-The available boxes are :
-
-* actions box : box listing the applicable actions on the displayed data
-
-* boxes_blog_archives_box : box listing the blog archives 
-
-* possible views box : box listing the possible views for the displayed data
-
-* rss box : RSS icon to get displayed data as a RSS thread
-
-* search box : search box
-
-* startup views box : box listing the configuration options available for 
-  the application site, such as `Preferences` and `Site Configuration`
-
-Components
-~~~~~~~~~~
-[WRITE ME]
-
-Contextual components
-~~~~~~~~~~~~~~~~~~~~~
-[WRITE ME]
-
--- a/doc/book/en/C030-instance-config.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Configure an instance
-=====================
-
-While creating an instance, a configuration file is generated in::
-
-    $ (CW_REGISTRY) / <instance> / <configuration name>.conf
-
-For example::
-
-    /etc/cubicweb.d/JPL/all-in-one.conf
-
-It is a simple text file format INI. In the following description,
-each option name is prefixed with its own section and followed by its
-default value if necessary, e.g. "`<section>.<option>` [value]."
-
-
-Configuring the Web server
---------------------------
-:`web.auth-model` [cookie]:
-    authentication mode, cookie or http
-:`web.realm`:
-    realm of the application in http authentication mode
-:`web.http-session-time` [0]:
-    period of inactivity of an HTTP session before it closes automatically.
-    Duration in seconds, 0 meaning no expiration (or more exactly at the
-    closing of the browser client)
-
-:`main.anonymous-user`, `main.anonymous-password`:
-    login and password to use to connect to the RQL server with
-    HTTP anonymous connection. EUser account should exist.
-
-:`main.base-url`:
-    url base site to be used to generate the urls of web pages
-
-Https configuration
-```````````````````
-It is possible to make a site accessible for anonymous http connections
-and https for authenticated users. This requires to
-use apache (for example) for redirection and the variable `main.https-url`
-of configuration file.
-
-:Example:
-
-   For an apache redirection of a site accessible via `http://localhost/demo`
-   and `https://localhost/demo` and actually running on port 8080, it
-   takes to the http:::
-
-     RewriteCond %(REQUEST_URI) ^/demo
-     RewriteRule ^/demo$/demo/
-     RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
-  
-   and for the https:::
-
-     RewriteCond %(REQUEST_URI) ^/ demo
-     RewriteRule ^/demo$/demo/
-     RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
-
-
-   and we will file in the all-in-one.conf of the instance:::
-
-     base-url = http://localhost/demo
-     https-url = `https://localhost/demo`
-
-Setting up the web
---------------------------------
-:`web.embed-allowed`:
-    regular expression matching sites which could be "embedded" in
-    the site (controllers 'embed')
-:`web.submit-url`:
-    url where the bugs encountered in the application can be mailed to
-
-
-RQL server configuration
-------------------------
-:`main.host`:
-    host name if it can not be detected correctly
-:`main.pid-file`:
-    file where will be written the server pid
-:`main.uid`:
-    user account to use for launching the server when it is
-    root launched by init
-:`main.session-time [30*60]`:
-    timeout of a RQL session
-:`main.query-log-file`:
-    file where all requests RQL executed by the server are written
-
-
-Pyro configuration for the instance
------------------------------------
-Web server side:
-
-:`pyro-client.pyro-application-id`:
-    pyro identifier of RQL server (e.g. the instance name)
-
-RQL server side:
-
-:`pyro-server.pyro-port`:
-    pyro port number. If none is specified, a port is assigned
-    automatically.
-
-RQL and web servers side:
-
-:`pyro-name-server.pyro-ns-host`:
-    hostname hosting pyro server name. If no value is
-    specified, it is located by a request from broadcast
-:`pyro-name-server.pyro-ns-group` [cubicweb]:
-    pyro group in which to save the application
-
-
-Configuring e-mail
-------------------
-RQL and web server side:
-
-:`email.mangle-mails [no]`:
-    indicates whether the email addresses must be displayed as is or
-    transformed
-
-RQL server side:
-
-:`email.smtp-host [mail]`:
-    hostname hosting the SMTP server to use for outgoing mail
-:`email.smtp-port [25]`:
-    SMTP server port to use for outgoing mail
-:`email.sender-name`:
-    name to use for outgoing mail of the application
-:`email.sender-addr`:
-    address for outgoing mail of the application
-:`email.default dest-addrs`:
-    destination addresses by default, if used by the configuration of the
-    dissemination of the model (separated by commas)
-:`email.supervising-addrs`:
-    destination addresses of e-mails of supervision (separated by
-    commas)
-
-
-Configuring logging
--------------------
-:`main.log-threshold`:
-    level of filtering messages (DEBUG, INFO, WARNING, ERROR)
-:`main.log-file`:
-    file to write messages
-
-
-Configuring Eproperties
------------------------
-Other configuration settings are in the form of entities `EProperty`
-in the database. It must be edited via the web interface or by
-RQL queries.
-
-:`ui.encoding`:
-    Character encoding to use for the web
-:`navigation.short-line-size`: # XXX should be in ui
-    number of characters for "short" display
-:`navigation.page-size`:
-    maximum number of entities to show per results page
-:`navigation.related-limit`:
-    number of related entities to show up on primary entity view
-:`navigation.combobox-limit`:
-    number of entities unrelated to show up on the drop-down lists of
-    the sight on an editing entity view
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C030-site-config.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,94 @@
+.. -*- coding: utf-8 -*-
+
+User interface for web site configuration
+=========================================
+
+.. image:: images/lax-book.03-site-config-panel.en.png
+
+This panel allows you to configure the appearance of your application site.
+Six menus are available and we will go through each of them to explain how
+to use them.
+
+Navigation
+~~~~~~~~~~
+This menu provides you a way to adjust some navigation options depending on
+your needs, such as the number of entities to display by page of results.
+Follows the detailled list of available options :
+  
+* navigation.combobox-limit : maximum number of entities to display in related
+  combo box (sample format: 23)
+* navigation.page-size : maximum number of objects displayed by page of results 
+  (sample format: 23)
+* navigation.related-limit : maximum number of related entities to display in 
+  the primary view (sample format: 23)
+* navigation.short-line-size : maximum number of characters in short description
+  (sample format: 23)
+
+UI
+~~
+This menu provides you a way to customize the user interface settings such as
+date format or encoding in the produced html.
+Follows the detailled list of available options :
+
+* ui.date-format : how to format date in the ui ("man strftime" for format description)
+* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
+  description)
+* ui.default-text-format : default text format for rich text fields.
+* ui.encoding : user interface encoding
+* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor).
+  You should also select text/html as default text format to actually get fckeditor.
+* ui.float-format : how to format float numbers in the ui
+* ui.language : language of the user interface
+* ui.main-template : id of main template used to render pages
+* ui.site-title	: site title, which is displayed right next to the logo in the header
+* ui.time-format : how to format time in the ui ("man strftime" for format description)
+
+
+Actions
+~~~~~~~
+This menu provides a way to configure the context in which you expect the actions
+to be displayed to the user and if you want the action to be visible or not. 
+You must have notice that when you view a list of entities, an action box is 
+available on the left column which display some actions as well as a drop-down 
+menu for more actions. 
+
+The context available are :
+
+* mainactions : actions listed in the left box
+* moreactions : actions listed in the `more` menu of the left box
+* addrelated : add actions listed in the left box
+* useractions : actions listed in the first section of drop-down menu 
+  accessible from the right corner user login link
+* siteactions : actions listed in the second section of drop-down menu
+  accessible from the right corner user login link
+* hidden : select this to hide the specific action
+
+Boxes
+~~~~~
+The application has already a pre-defined set of boxes you can use right away. 
+This configuration section allows you to place those boxes where you want in the
+application interface to customize it. 
+
+The available boxes are :
+
+* actions box : box listing the applicable actions on the displayed data
+
+* boxes_blog_archives_box : box listing the blog archives 
+
+* possible views box : box listing the possible views for the displayed data
+
+* rss box : RSS icon to get displayed data as a RSS thread
+
+* search box : search box
+
+* startup views box : box listing the configuration options available for 
+  the application site, such as `Preferences` and `Site Configuration`
+
+Components
+~~~~~~~~~~
+[WRITE ME]
+
+Contextual components
+~~~~~~~~~~~~~~~~~~~~~
+[WRITE ME]
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C040-instance-config.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,163 @@
+.. -*- coding: utf-8 -*-
+
+
+Configure an instance
+=====================
+
+While creating an instance, a configuration file is generated in::
+
+    $ (CW_REGISTRY) / <instance> / <configuration name>.conf
+
+For example::
+
+    /etc/cubicweb.d/JPL/all-in-one.conf
+
+It is a simple text file format INI. In the following description,
+each option name is prefixed with its own section and followed by its
+default value if necessary, e.g. "`<section>.<option>` [value]."
+
+
+Configuring the Web server
+--------------------------
+:`web.auth-model` [cookie]:
+    authentication mode, cookie or http
+:`web.realm`:
+    realm of the application in http authentication mode
+:`web.http-session-time` [0]:
+    period of inactivity of an HTTP session before it closes automatically.
+    Duration in seconds, 0 meaning no expiration (or more exactly at the
+    closing of the browser client)
+
+:`main.anonymous-user`, `main.anonymous-password`:
+    login and password to use to connect to the RQL server with
+    HTTP anonymous connection. CWUser account should exist.
+
+:`main.base-url`:
+    url base site to be used to generate the urls of web pages
+
+Https configuration
+```````````````````
+It is possible to make a site accessible for anonymous http connections
+and https for authenticated users. This requires to
+use apache (for example) for redirection and the variable `main.https-url`
+of configuration file.
+
+:Example:
+
+   For an apache redirection of a site accessible via `http://localhost/demo`
+   and `https://localhost/demo` and actually running on port 8080, it
+   takes to the http:::
+
+     RewriteCond %(REQUEST_URI) ^/demo
+     RewriteRule ^/demo$ /demo/
+     RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
+  
+   and for the https:::
+
+     RewriteCond %(REQUEST_URI) ^/ demo
+     RewriteRule ^/demo$/demo/
+     RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
+
+
+   and we will file in the all-in-one.conf of the instance:::
+
+     base-url = http://localhost/demo
+     https-url = `https://localhost/demo`
+
+Setting up the web
+--------------------------------
+:`web.embed-allowed`:
+    regular expression matching sites which could be "embedded" in
+    the site (controllers 'embed')
+:`web.submit-url`:
+    url where the bugs encountered in the application can be mailed to
+
+
+RQL server configuration
+------------------------
+:`main.host`:
+    host name if it can not be detected correctly
+:`main.pid-file`:
+    file where will be written the server pid
+:`main.uid`:
+    user account to use for launching the server when it is
+    root launched by init
+:`main.session-time [30*60]`:
+    timeout of a RQL session
+:`main.query-log-file`:
+    file where all requests RQL executed by the server are written
+
+
+Pyro configuration for the instance
+-----------------------------------
+Web server side:
+
+:`pyro-client.pyro-application-id`:
+    pyro identifier of RQL server (e.g. the instance name)
+
+RQL server side:
+
+:`pyro-server.pyro-port`:
+    pyro port number. If none is specified, a port is assigned
+    automatically.
+
+RQL and web servers side:
+
+:`pyro-name-server.pyro-ns-host`:
+    hostname hosting pyro server name. If no value is
+    specified, it is located by a request from broadcast
+:`pyro-name-server.pyro-ns-group` [cubicweb]:
+    pyro group in which to save the application
+
+
+Configuring e-mail
+------------------
+RQL and web server side:
+
+:`email.mangle-mails [no]`:
+    indicates whether the email addresses must be displayed as is or
+    transformed
+
+RQL server side:
+
+:`email.smtp-host [mail]`:
+    hostname hosting the SMTP server to use for outgoing mail
+:`email.smtp-port [25]`:
+    SMTP server port to use for outgoing mail
+:`email.sender-name`:
+    name to use for outgoing mail of the application
+:`email.sender-addr`:
+    address for outgoing mail of the application
+:`email.default dest-addrs`:
+    destination addresses by default, if used by the configuration of the
+    dissemination of the model (separated by commas)
+:`email.supervising-addrs`:
+    destination addresses of e-mails of supervision (separated by
+    commas)
+
+
+Configuring logging
+-------------------
+:`main.log-threshold`:
+    level of filtering messages (DEBUG, INFO, WARNING, ERROR)
+:`main.log-file`:
+    file to write messages
+
+
+Configuring Eproperties
+-----------------------
+Other configuration settings are in the form of entities `CWProperty`
+in the database. It must be edited via the web interface or by
+RQL queries.
+
+:`ui.encoding`:
+    Character encoding to use for the web
+:`navigation.short-line-size`: # XXX should be in ui
+    number of characters for "short" display
+:`navigation.page-size`:
+    maximum number of entities to show per results page
+:`navigation.related-limit`:
+    number of related entities to show up on primary entity view
+:`navigation.combobox-limit`:
+    number of entities unrelated to show up on the drop-down lists of
+    the sight on an editing entity view
--- a/doc/book/en/C040-rql.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,655 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _RQL:
-
-======================================
-RQL language (Relation Query Language)
-======================================
-
-Introduction
-============
-
-Goals of RQL
-------------
-
-The goal is to have a language emphasizing the way of browsing
-relations. As such, attributes will be regarded as cases of
-special relations (in terms of implementation, the language
-user should see virtually no difference between an attribute and a
-relation).
-
-RQL is inspired by SQL but is the highest level. A knowledge of the 
-`CubicWeb` schema defining the application is necessary.
-
-Comparison with existing languages
-----------------------------------
-
-SQL
-```
-RQL builds on the features of SQL but is at a higher level
-(the current implementation of RQL generates SQL). For that it is limited
-to the way of browsing relations and introduces variables. 
-The user does not need to know the model underlying SQL, but the `CubicWeb` 
-schema defining the application.
-
-Versa
-`````
-We should look in more detail, but here are already some ideas for
-the moment ... Versa_ is the language most similar to what we wanted
-to do, but the model underlying data being RDF, there is some
-number of things such as namespaces or handling of the RDF types which 
-does not interest us. On the functionality level, Versa_ is very comprehensive
-including through many functions of conversion and basic types manipulation,
-which may need to be guided at one time or another. 
-Finally, the syntax is a little esoteric.
-
-Sparql
-``````
-
-The query language most similar to RQL is SPARQL_, defined by the W3C to serve
-for the semantic web. 
-
-
-The different types of queries
-------------------------------
-
-Search (`Any`)
-   Extract entities and attributes of entities.
-
-Insert entities (`INSERT`)
-   Insert new entities or relations in the database.
-   It can also directly create relationships for the newly created entities.
-
-Update entities, create relations (`SET`)
-   Update existing entities in the database,
-   or create relations between existing entities.
-
-Delete entities or relationship (`DELETE`)
-   Remove entities or relations existing in the database.
-
-Search Query
-------------
-
-   [ `DISTINCT`] <entity type> V1 (V2) \ *
-   [ `GROUPBY` V1 (V2) \*] [ `ORDERBY` <orderterms>]
-   [ `WHERE` <restriction>]
-   [ `LIMIT` <value>] [ `OFFSET` <value>]
-
-:entity type:
-   Type of selected variables.
-   The special type `Any` is equivalent to not specify a type.
-:restriction:
-   list of conditions to test successively 
-     `V1 relation V2 | <static value>`
-:orderterms:
-   Definition of the selection order: variable or column number followed by
-   sorting method ( `ASC`, `DESC`), ASC is the default.
-:note for grouped queries:
-   For grouped queries (e.g., a clause `GROUPBY`), all
-   selected variables must be aggregated or grouped.
-
-
-
-- *Search for the object of identifier 53*
-  ::
-
-        Any WHERE X
-        X eid 53
-
-- *Search material such as comics, owned by syt and available*
-  ::
-
-        WHERE X Document
-        X occurence_of F, F class C, C name 'Comics'
-        X owned_by U, U login 'syt'
-        X available true
-
-- *Looking for people working for eurocopter interested in training*
-  ::
-
-        Any P WHERE
-        P is Person, P work_for S, S name 'Eurocopter'
-        P interested_by T, T name 'training'
-
-- *Search note less than 10 days old written by jphc or ocy*
-  ::
-
-        Any N WHERE
-        N is Note, N written_on D, D day> (today -10),
-        N written_by P, P name 'jphc' or P name 'ocy'
-
-- *Looking for people interested in training or living in Paris*
-  ::
-
-        Any P WHERE
-        P is Person, (P interested_by T, T name 'training') OR
-        (P city 'Paris')
-
-- *The name and surname of all people*
-  ::
-
-        Any N, P WHERE
-        X is Person, X name N, X first_name P
-
-  Note that the selection of several entities generally force
-  the use of "Any" because the type specification applies otherwise
-  to all the selected variables. We could write here
-  ::
-
-        String N, P WHERE
-        X is Person, X name N, X first_name P
-
-
-  Note: You can not specify several types with * ... where X is FirstType or X is SecondType*.
-  To specify several types explicitely, you have to do
-
-  ::
-
-        Any X where X is in (FirstType, SecondType)
-
-
-Insertion query
----------------
-
-    `INSERT` <entity type> V1 (, <entity type> V2) \ * `:` <assignments>
-    [ `WHERE` <restriction>]
-
-:assignments:
-   list of relations to assign in the form `V1 relationship V2 | <static value>`
-
-The restriction can define variables used in assignments.
-
-Caution, if a restriction is specified, the insertion is done for 
-*each line result returned by the restriction*.
-
-- *Insert a new person named 'foo'*
-  ::
-
-        INSERT Person X: X name 'foo'
-
-- *Insert a new person named 'foo', another called 'nice' and a 'friend' relation
-  between them*
-  ::
-
-        INSERT Person X, Person Y: X name 'foo', Y name 'nice', X friend Y
-
-- *Insert a new person named 'foo' and a 'friend' relation with an existing 
-  person called 'nice'*
-  ::
-
-        INSERT Person X: X name 'foo', X friend  Y WHERE name 'nice'
-
-Update and relation creation queries
-------------------------------------
-    `SET` <assignements>
-    [ `WHERE` <restriction>]
-
-Caution, if a restriction is specified, the update is done *for
-each result line returned by the restriction*.
-
-- *Renaming of the person named 'foo' to 'bar' with the first name changed*
-  ::
-
-        SET X name 'bar', X first_name 'original' WHERE X is Person, X name 'foo'
-
-- *Insert a relation of type 'know' between objects linked by 
-  the relation of type 'friend'*
-  ::
-
-        SET X know Y  WHERE X friend Y
-
-
-Deletion query
---------------
-    `DELETE` (<entity type> V) | (V1 relation v2 ),...
-    [ `WHERE` <restriction>]
-
-Caution, if a restriction is specified, the deletion is made *for
-each line result returned by the restriction*.
-
-- *Deletion of the person named 'foo'*
-  ::
-
-        DELETE Person X WHERE X name 'foo'
-
-- *Removal of all relations of type 'friend' from the person named 'foo'*
-  ::
-
-        DELETE X friend Y WHERE X is Person, X name 'foo'
-
-
-(yet) Undocumented types of queries
------------------------------------
-
-**Limit / offset**
-::
-    
-    Any P ORDERBY N LIMIT 5 OFFSET 10 WHERE P is Person, P firstname N
-
-**Function calls**
-::
-    
-    Any UPPER(N) WHERE P firstname N
-
-**Exists**
-::
-    
-    Any X ORDERBY PN,N
-    WHERE X num N, X version_of P, P name PN, 
-          EXISTS(X in_state S, S name IN ("dev", "ready"))
-          OR EXISTS(T tags X, T name "priority")
-
-**Left outer join**
-::
-
-    Any T,P,V WHERE T is Ticket, T concerns P, T done_in V?
-    
-    
-**Having**
-::
-    
-    Any X GROUPBY X WHERE X knows Y HAVING COUNT(Y) > 10
-
-**Simple union**
-::
-
-    (Any X WHERE X is Person) UNION (Any X WHERE X is Company)
-    
-**Complex union**
-::
-
-     DISTINCT Any W, REF
-        WITH W, REF BEING 
-            (
-	      (Any W, REF WHERE W is Workcase, W ref REF, 
-                                 W concerned_by D, D name "Logilab")
-               UNION 
-              (Any W, REF WHERE W is Workcase, W ref REF, '
-                                W split_into WP, WP name "WP1")
-            )
-
-
-Language definition
-===================
-
-Reserved keywords
------------------
-The keywords are not case sensitive.
-
-::
-
-     DISTINCT, INSERT, SET, DELETE,
-     WHERE, AND, OR, NOT, EXISTS,
-     IN, LIKE, UNION, WITH, BEING,
-     TRUE, FALSE, NULL, TODAY, NOW,
-     LIMIT, OFFSET,
-     HAVING, GROUPBY, ORDERBY, ASC, DESC
-
-
-Variables and Typing
---------------------
-
-With RQL, we do not distinguish between entities and attributes. The
-value of an attribute is considered an entity of a particular type (see
-below), linked to one (real) entity by a relation called the name of
-the attribute.
-
-Entities and values to browse and/or select are represented in
-the query by *variables* that must be written in capital letters.
-
-There is a special type **Any**, referring to a non specific type.
-
-We can restrict the possible types for a variable using the
-special relation **is**.
-The possible type(s) for each variable is derived from the schema
-according to the constraints expressed above and thanks to the relations between
-each variable.
-
-Built-in types
-``````````````
-
-The base types supported are string (between double or single quotes),
-integers or floats (the separator is '.'), dates and
-boolean. We expect to receive a schema in which types String,
-Int, Float, Date and Boolean are defined.
-
-* `String` (literal: between double or single quotes).
-* `Int`, `Float` (separator being'.').
-* `Date`, `Datetime`, `Time` (literal: string YYYY/MM/DD [hh:mm] or keywords
-  `TODAY` and `NOW`).
-* `Boolean` (keywords `TRUE` and `FALSE`).
-* `Keyword` NULL.
-
-
-Operators
----------
-
-Logical Operators
-`````````````````
-::
-
-     AND, OR, NOT, ','
-
-',' is equivalent to 'AND' but with the smallest among the priority
-of logical operators (see :ref:`PriorityOperators`).
-
-Mathematical Operators
-``````````````````````
-::
-
-     +, -, *, /
-
-Comparison operators
-````````````````````
-::
-
-     =, <, <=, >=, >, ~=, IN, LIKE
-
-* The operator `=` is the default operator.
-
-* The operator `LIKE` equivalent to `~=` can be used with the
-  special character `%` in a string to indicate that the chain 
-  must start or finish by a prefix/suffix:
-  ::
-
-     Any X WHERE X name ~= 'Th%'
-     Any X WHERE X name LIKE '%lt'
-
-* The operator `IN` provides a list of possible values:
-  ::
-  
-    Any X WHERE X name IN ( 'chauvat', 'fayolle', 'di mascio', 'thenault')
-
-
-XXX nico: "A trick <> 'bar'" wouldn't it be more convenient than 
-"NOT A trick 'bar'" ?
-
-.. _PriorityOperators:
-
-Operator priority
-`````````````````
-
-1. '*', '/'
-
-2. '+', '-'
-
-3. 'not'
-
-4 'and'
-
-5 'or'
-
-6 ','
-
-
-Advanced Features
------------------
-
-Aggregate Functions
-```````````````````
-::
-
-     COUNT, MIN, MAX, AVG, SUM
-
-Functions on string
-```````````````````
-::
-
-     UPPER, LOWER
-
-Optional relations
-``````````````````
-
-* They allow you to select entities related or not to another.
-
-* You must use the `?` behind the variable to specify that the relation
-  toward it is optional:
-
-   - Anomalies of a project attached or not to a version ::
-
-       Any X, V WHERE X concerns P, P eid 42, X corrected_in V?
-
-   - All cards and the project they document if necessary ::
-
-       Any C, P WHERE C is Card, P? documented_by C
-
-
-
-BNF grammar
------------
-
-The terminal elements are in capital letters, non-terminal in lowercase.
-The value of the terminal elements (between quotes) is a Python regular
-expression.
-::
-
-     statement:: = (select | delete | insert | update) ';'
-
-
-     # select specific rules
-     select      ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort?
-
-     selected_terms ::= expression ( ',' expression)*
-
-     group       ::= 'GROUPBY' VARIABLE ( ',' VARIABLE)*
-
-     sort        ::= 'ORDERBY' sort_term ( ',' sort_term)*
-
-     sort_term   ::=  VARIABLE sort_method =?
-
-     sort_method ::= 'ASC' | 'DESC'
-
-
-     # delete specific rules
-     delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction?
-
-
-     # insert specific rules
-     insert ::= 'INSERT' variables_declaration ( ':' relations_declaration)? restriction?
-
-
-     # update specific rules
-     update ::= 'SET' relations_declaration restriction
-
-
-     # common rules
-     variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)*
-
-     relations_declaration ::= simple_relation (',' simple_relation)*
-
-     simple_relation ::= VARIABLE R_TYPE expression
-
-     restriction ::= 'WHERE' relations
-
-     relations   ::= relation (LOGIC_OP relation)*
-                   | '(' relations')'
-
-     relation    ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression
-                   | 'NOT'? R_TYPE VARIABLE 'IN' '(' expression (',' expression)* ')'
-                   
-     expression  ::= var_or_func_or_const (MATH_OP var_or_func_or_const) *
-                   | '(' expression ')'
-
-     var_or_func_or_const ::= VARIABLE | function | constant
-
-     function    ::= FUNCTION '(' expression ( ',' expression) * ')'
-
-     constant    ::= KEYWORD | STRING | FLOAT | INT
-
-     # tokens
-     LOGIC_OP ::= ',' | 'OR' | 'AND'
-     MATH_OP  ::= '+' | '-' | '/' | '*'
-     COMP_OP  ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE'
-
-     FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'UPPER' | 'LOWER'
-
-     VARIABLE ::= '[A-Z][A-Z0-9]*'
-     E_TYPE   ::= '[A-Z]\w*'
-     R_TYPE   ::= '[a-z_]+'
-
-     KEYWORD  ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW'
-     STRING   ::= "'([^'\]|\\.)*'" |'"([^\"]|\\.)*\"'
-     FLOAT    ::= '\d+\.\d*'
-     INT      ::= '\d+'
-
-
-Remarks
--------
-
-Sorting and groups
-``````````````````
-
-- For grouped queries (e.g. with a GROUPBY clause), all
-  selected variables should be grouped.
-
-- To group and/or sort by attributes, we can do: "X,L user U, U
-  login L GROUPBY L, X ORDERBY L"
-
-- If the sorting method (SORT_METHOD) is not specified, then the sorting is
-  ascendant.
-
-Negation
-````````
-
-* A query such as `Document X WHERE NOT X owned_by U` means "the
-  documents have no relation `owned_by`".
-* But the query `Document X WHERE NOT X owned_by U, U login "syt"`
-  means "the documents have no relation `owned_by` with the user
-  syt". They may have a relation "owned_by" with another user.
-
-Identity
-````````
-
-You can use the special relation `identity` in a query to 
-add an identity constraint between two variables. This is equivalent
-to ``is`` in python::
-
-   Any A WHERE A comments B, A identity B
-
-return all objects that comment themselves. The relation
-`identity` is especially useful when defining the rules for securities
-with `RQLExpressions`.
-
-Implementation
-==============
-
-Internal representation (syntactic tree)
-----------------------------------------
-
-The tree research does not contain the selected variables 
-(e.g. there is only what follows "WHERE").
-
-The insertion tree does not contain the variables inserted or relations
-defined on these variables (e.g. there is only what follows "WHERE").
-
-The removal tree does not contain the deleted variables and relations
-(e.g. there is only what follows the "WHERE").
-
-The update tree does not contain the variables and relations updated
-(e.g. there is only what follows the "WHERE").
-
-::
-
-     Select         ((Relationship | And | Or)?, Group?, Sort?)
-     Insert         (Relations | And | Or)?
-     Delete         (Relationship | And | Or)?
-     Update         (Relations | And | Or)?
-
-     And            ((Relationship | And | Or), (Relationship | And | Or))
-     Or             ((Relationship | And | Or), (Relationship | And | Or))
-
-     Relationship   ((VariableRef, Comparison))
-
-     Comparison     ((Function | MathExpression | Keyword | Constant | VariableRef) +)
-
-     Function       (())
-     MathExpression ((MathExpression | Keyword | Constant | VariableRef), (MathExpression | Keyword | Constant | VariableRef))
-
-     Group          (VariableRef +)
-     Sort           (SortTerm +)
-     SortTerm       (VariableRef +)
-
-     VariableRef    ()
-     Variable       ()
-     Keyword        ()
-     Constant       ()
-
-
-Remarks
--------
-
-- The current implementation does not support linking two relations of type
-  'is' with a OR. I do not think that the negation is  supported on this type 
-  of relation (XXX FIXME to be confirmed).
-
-- Relations defining the variables must be left to those using them. 
-  For example::
-
-     Point P where P abs X, P ord Y, P value X+Y
-
-  is valid, but::
-
-     Point P where P abs X, P value X+Y, P ord Y
-
-  is not.
-
-RQL logs
---------
-
-You can configure the `CubicWeb` application to keep a log
-of the queries executed against your database. To do so, 
-edit the configuration file of your application 
-``.../etc/cubicweb.d/myapp/all-in-one.conf`` and uncomment the
-variable ``query-log-file``::
-
-  # web application query log file
-  query-log-file=/tmp/rql-myapp.log
-
-
-Conclusion
-==========
-
-Limitations
------------
-
-It lacks at the moment:
-
-- COALESCE
-
-- restrictions on groups (HAVING)
-
-and certainly other things ...
-
-A disadvantage is that to use this language we must know the
-format used (with real relation names and entities, not those viewing
-in the user interface). On the other hand, we can not really bypass
-that, and it is the job of a user interface to hide the RQL.
-
-
-Topics
-------
-
-It would be convenient to express the schema matching
-relations (non-recursive rules)::
-
-     Document class Type <-> Document occurence_of Fiche class Type
-     Sheet class Type    <-> Form collection Collection class Type
-    
-Therefore 1. becomes::
-
-     Document X where
-     X class C, C name 'Cartoon'
-     X owned_by U, U login 'syt'
-     X available true
-
-I'm not sure that we should handle this at RQL level ...
-
-There should also be a special relation 'anonymous'.
-
-
-
-.. _Versa: http://uche.ogbuji.net/tech/rdf/versa/
-.. _SPARQL: http://www.w3.org/TR/rdf-sparql-query/
-
-
-[FIXME] see also RQL documentation in source rql/doc.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C050-rql.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,655 @@
+.. -*- coding: utf-8 -*-
+
+.. _RQL:
+
+======================================
+RQL language (Relation Query Language)
+======================================
+
+Introduction
+============
+
+Goals of RQL
+------------
+
+The goal is to have a language emphasizing the way of browsing
+relations. As such, attributes will be regarded as cases of
+special relations (in terms of implementation, the language
+user should see virtually no difference between an attribute and a
+relation).
+
+RQL is inspired by SQL but is the highest level. A knowledge of the 
+`CubicWeb` schema defining the application is necessary.
+
+Comparison with existing languages
+----------------------------------
+
+SQL
+```
+RQL builds on the features of SQL but is at a higher level
+(the current implementation of RQL generates SQL). For that it is limited
+to the way of browsing relations and introduces variables. 
+The user does not need to know the model underlying SQL, but the `CubicWeb` 
+schema defining the application.
+
+Versa
+`````
+We should look in more detail, but here are already some ideas for
+the moment ... Versa_ is the language most similar to what we wanted
+to do, but the model underlying data being RDF, there is some
+number of things such as namespaces or handling of the RDF types which 
+does not interest us. On the functionality level, Versa_ is very comprehensive
+including through many functions of conversion and basic types manipulation,
+which may need to be guided at one time or another. 
+Finally, the syntax is a little esoteric.
+
+Sparql
+``````
+
+The query language most similar to RQL is SPARQL_, defined by the W3C to serve
+for the semantic web. 
+
+
+The different types of queries
+------------------------------
+
+Search (`Any`)
+   Extract entities and attributes of entities.
+
+Insert entities (`INSERT`)
+   Insert new entities or relations in the database.
+   It can also directly create relationships for the newly created entities.
+
+Update entities, create relations (`SET`)
+   Update existing entities in the database,
+   or create relations between existing entities.
+
+Delete entities or relationship (`DELETE`)
+   Remove entities or relations existing in the database.
+
+Search Query
+------------
+
+   [ `DISTINCT`] <entity type> V1 (V2) \ *
+   [ `GROUPBY` V1 (V2) \*] [ `ORDERBY` <orderterms>]
+   [ `WHERE` <restriction>]
+   [ `LIMIT` <value>] [ `OFFSET` <value>]
+
+:entity type:
+   Type of selected variables.
+   The special type `Any` is equivalent to not specify a type.
+:restriction:
+   list of conditions to test successively 
+     `V1 relation V2 | <static value>`
+:orderterms:
+   Definition of the selection order: variable or column number followed by
+   sorting method ( `ASC`, `DESC`), ASC is the default.
+:note for grouped queries:
+   For grouped queries (e.g., a clause `GROUPBY`), all
+   selected variables must be aggregated or grouped.
+
+
+
+- *Search for the object of identifier 53*
+  ::
+
+        Any WHERE X
+        X eid 53
+
+- *Search material such as comics, owned by syt and available*
+  ::
+
+        WHERE X Document
+        X occurence_of F, F class C, C name 'Comics'
+        X owned_by U, U login 'syt'
+        X available true
+
+- *Looking for people working for eurocopter interested in training*
+  ::
+
+        Any P WHERE
+        P is Person, P work_for S, S name 'Eurocopter'
+        P interested_by T, T name 'training'
+
+- *Search note less than 10 days old written by jphc or ocy*
+  ::
+
+        Any N WHERE
+        N is Note, N written_on D, D day> (today -10),
+        N written_by P, P name 'jphc' or P name 'ocy'
+
+- *Looking for people interested in training or living in Paris*
+  ::
+
+        Any P WHERE
+        P is Person, (P interested_by T, T name 'training') OR
+        (P city 'Paris')
+
+- *The name and surname of all people*
+  ::
+
+        Any N, P WHERE
+        X is Person, X name N, X first_name P
+
+  Note that the selection of several entities generally force
+  the use of "Any" because the type specification applies otherwise
+  to all the selected variables. We could write here
+  ::
+
+        String N, P WHERE
+        X is Person, X name N, X first_name P
+
+
+  Note: You can not specify several types with * ... where X is FirstType or X is SecondType*.
+  To specify several types explicitely, you have to do
+
+  ::
+
+        Any X where X is in (FirstType, SecondType)
+
+
+Insertion query
+---------------
+
+    `INSERT` <entity type> V1 (, <entity type> V2) \ * `:` <assignments>
+    [ `WHERE` <restriction>]
+
+:assignments:
+   list of relations to assign in the form `V1 relationship V2 | <static value>`
+
+The restriction can define variables used in assignments.
+
+Caution, if a restriction is specified, the insertion is done for 
+*each line result returned by the restriction*.
+
+- *Insert a new person named 'foo'*
+  ::
+
+        INSERT Person X: X name 'foo'
+
+- *Insert a new person named 'foo', another called 'nice' and a 'friend' relation
+  between them*
+  ::
+
+        INSERT Person X, Person Y: X name 'foo', Y name 'nice', X friend Y
+
+- *Insert a new person named 'foo' and a 'friend' relation with an existing 
+  person called 'nice'*
+  ::
+
+        INSERT Person X: X name 'foo', X friend  Y WHERE name 'nice'
+
+Update and relation creation queries
+------------------------------------
+    `SET` <assignements>
+    [ `WHERE` <restriction>]
+
+Caution, if a restriction is specified, the update is done *for
+each result line returned by the restriction*.
+
+- *Renaming of the person named 'foo' to 'bar' with the first name changed*
+  ::
+
+        SET X name 'bar', X first_name 'original' WHERE X is Person, X name 'foo'
+
+- *Insert a relation of type 'know' between objects linked by 
+  the relation of type 'friend'*
+  ::
+
+        SET X know Y  WHERE X friend Y
+
+
+Deletion query
+--------------
+    `DELETE` (<entity type> V) | (V1 relation v2 ),...
+    [ `WHERE` <restriction>]
+
+Caution, if a restriction is specified, the deletion is made *for
+each line result returned by the restriction*.
+
+- *Deletion of the person named 'foo'*
+  ::
+
+        DELETE Person X WHERE X name 'foo'
+
+- *Removal of all relations of type 'friend' from the person named 'foo'*
+  ::
+
+        DELETE X friend Y WHERE X is Person, X name 'foo'
+
+
+(yet) Undocumented types of queries
+-----------------------------------
+
+**Limit / offset**
+::
+    
+    Any P ORDERBY N LIMIT 5 OFFSET 10 WHERE P is Person, P firstname N
+
+**Function calls**
+::
+    
+    Any UPPER(N) WHERE P firstname N
+
+**Exists**
+::
+    
+    Any X ORDERBY PN,N
+    WHERE X num N, X version_of P, P name PN, 
+          EXISTS(X in_state S, S name IN ("dev", "ready"))
+          OR EXISTS(T tags X, T name "priority")
+
+**Left outer join**
+::
+
+    Any T,P,V WHERE T is Ticket, T concerns P, T done_in V?
+    
+    
+**Having**
+::
+    
+    Any X GROUPBY X WHERE X knows Y HAVING COUNT(Y) > 10
+
+**Simple union**
+::
+
+    (Any X WHERE X is Person) UNION (Any X WHERE X is Company)
+    
+**Complex union**
+::
+
+     DISTINCT Any W, REF
+        WITH W, REF BEING 
+            (
+	      (Any W, REF WHERE W is Workcase, W ref REF, 
+                                 W concerned_by D, D name "Logilab")
+               UNION 
+              (Any W, REF WHERE W is Workcase, W ref REF, '
+                                W split_into WP, WP name "WP1")
+            )
+
+
+Language definition
+===================
+
+Reserved keywords
+-----------------
+The keywords are not case sensitive.
+
+::
+
+     DISTINCT, INSERT, SET, DELETE,
+     WHERE, AND, OR, NOT, EXISTS,
+     IN, LIKE, UNION, WITH, BEING,
+     TRUE, FALSE, NULL, TODAY, NOW,
+     LIMIT, OFFSET,
+     HAVING, GROUPBY, ORDERBY, ASC, DESC
+
+
+Variables and Typing
+--------------------
+
+With RQL, we do not distinguish between entities and attributes. The
+value of an attribute is considered an entity of a particular type (see
+below), linked to one (real) entity by a relation called the name of
+the attribute.
+
+Entities and values to browse and/or select are represented in
+the query by *variables* that must be written in capital letters.
+
+There is a special type **Any**, referring to a non specific type.
+
+We can restrict the possible types for a variable using the
+special relation **is**.
+The possible type(s) for each variable is derived from the schema
+according to the constraints expressed above and thanks to the relations between
+each variable.
+
+Built-in types
+``````````````
+
+The base types supported are string (between double or single quotes),
+integers or floats (the separator is '.'), dates and
+boolean. We expect to receive a schema in which types String,
+Int, Float, Date and Boolean are defined.
+
+* `String` (literal: between double or single quotes).
+* `Int`, `Float` (separator being'.').
+* `Date`, `Datetime`, `Time` (literal: string YYYY/MM/DD [hh:mm] or keywords
+  `TODAY` and `NOW`).
+* `Boolean` (keywords `TRUE` and `FALSE`).
+* `Keyword` NULL.
+
+
+Operators
+---------
+
+Logical Operators
+`````````````````
+::
+
+     AND, OR, NOT, ','
+
+',' is equivalent to 'AND' but with the smallest among the priority
+of logical operators (see :ref:`PriorityOperators`).
+
+Mathematical Operators
+``````````````````````
+::
+
+     +, -, *, /
+
+Comparison operators
+````````````````````
+::
+
+     =, <, <=, >=, >, ~=, IN, LIKE
+
+* The operator `=` is the default operator.
+
+* The operator `LIKE` equivalent to `~=` can be used with the
+  special character `%` in a string to indicate that the chain 
+  must start or finish by a prefix/suffix:
+  ::
+
+     Any X WHERE X name ~= 'Th%'
+     Any X WHERE X name LIKE '%lt'
+
+* The operator `IN` provides a list of possible values:
+  ::
+  
+    Any X WHERE X name IN ( 'chauvat', 'fayolle', 'di mascio', 'thenault')
+
+
+XXX nico: "A trick <> 'bar'" wouldn't it be more convenient than 
+"NOT A trick 'bar'" ?
+
+.. _PriorityOperators:
+
+Operator priority
+`````````````````
+
+1. '*', '/'
+
+2. '+', '-'
+
+3. 'not'
+
+4 'and'
+
+5 'or'
+
+6 ','
+
+
+Advanced Features
+-----------------
+
+Aggregate Functions
+```````````````````
+::
+
+     COUNT, MIN, MAX, AVG, SUM
+
+Functions on string
+```````````````````
+::
+
+     UPPER, LOWER
+
+Optional relations
+``````````````````
+
+* They allow you to select entities related or not to another.
+
+* You must use the `?` behind the variable to specify that the relation
+  toward it is optional:
+
+   - Anomalies of a project attached or not to a version ::
+
+       Any X, V WHERE X concerns P, P eid 42, X corrected_in V?
+
+   - All cards and the project they document if necessary ::
+
+       Any C, P WHERE C is Card, P? documented_by C
+
+
+
+BNF grammar
+-----------
+
+The terminal elements are in capital letters, non-terminal in lowercase.
+The value of the terminal elements (between quotes) is a Python regular
+expression.
+::
+
+     statement:: = (select | delete | insert | update) ';'
+
+
+     # select specific rules
+     select      ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort?
+
+     selected_terms ::= expression ( ',' expression)*
+
+     group       ::= 'GROUPBY' VARIABLE ( ',' VARIABLE)*
+
+     sort        ::= 'ORDERBY' sort_term ( ',' sort_term)*
+
+     sort_term   ::=  VARIABLE sort_method =?
+
+     sort_method ::= 'ASC' | 'DESC'
+
+
+     # delete specific rules
+     delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction?
+
+
+     # insert specific rules
+     insert ::= 'INSERT' variables_declaration ( ':' relations_declaration)? restriction?
+
+
+     # update specific rules
+     update ::= 'SET' relations_declaration restriction
+
+
+     # common rules
+     variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)*
+
+     relations_declaration ::= simple_relation (',' simple_relation)*
+
+     simple_relation ::= VARIABLE R_TYPE expression
+
+     restriction ::= 'WHERE' relations
+
+     relations   ::= relation (LOGIC_OP relation)*
+                   | '(' relations')'
+
+     relation    ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression
+                   | 'NOT'? R_TYPE VARIABLE 'IN' '(' expression (',' expression)* ')'
+                   
+     expression  ::= var_or_func_or_const (MATH_OP var_or_func_or_const) *
+                   | '(' expression ')'
+
+     var_or_func_or_const ::= VARIABLE | function | constant
+
+     function    ::= FUNCTION '(' expression ( ',' expression) * ')'
+
+     constant    ::= KEYWORD | STRING | FLOAT | INT
+
+     # tokens
+     LOGIC_OP ::= ',' | 'OR' | 'AND'
+     MATH_OP  ::= '+' | '-' | '/' | '*'
+     COMP_OP  ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE'
+
+     FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'UPPER' | 'LOWER'
+
+     VARIABLE ::= '[A-Z][A-Z0-9]*'
+     E_TYPE   ::= '[A-Z]\w*'
+     R_TYPE   ::= '[a-z_]+'
+
+     KEYWORD  ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW'
+     STRING   ::= "'([^'\]|\\.)*'" |'"([^\"]|\\.)*\"'
+     FLOAT    ::= '\d+\.\d*'
+     INT      ::= '\d+'
+
+
+Remarks
+-------
+
+Sorting and groups
+``````````````````
+
+- For grouped queries (e.g. with a GROUPBY clause), all
+  selected variables should be grouped.
+
+- To group and/or sort by attributes, we can do: "X,L user U, U
+  login L GROUPBY L, X ORDERBY L"
+
+- If the sorting method (SORT_METHOD) is not specified, then the sorting is
+  ascendant.
+
+Negation
+````````
+
+* A query such as `Document X WHERE NOT X owned_by U` means "the
+  documents have no relation `owned_by`".
+* But the query `Document X WHERE NOT X owned_by U, U login "syt"`
+  means "the documents have no relation `owned_by` with the user
+  syt". They may have a relation "owned_by" with another user.
+
+Identity
+````````
+
+You can use the special relation `identity` in a query to 
+add an identity constraint between two variables. This is equivalent
+to ``is`` in python::
+
+   Any A WHERE A comments B, A identity B
+
+return all objects that comment themselves. The relation
+`identity` is especially useful when defining the rules for securities
+with `RQLExpressions`.
+
+Implementation
+==============
+
+Internal representation (syntactic tree)
+----------------------------------------
+
+The tree research does not contain the selected variables 
+(e.g. there is only what follows "WHERE").
+
+The insertion tree does not contain the variables inserted or relations
+defined on these variables (e.g. there is only what follows "WHERE").
+
+The removal tree does not contain the deleted variables and relations
+(e.g. there is only what follows the "WHERE").
+
+The update tree does not contain the variables and relations updated
+(e.g. there is only what follows the "WHERE").
+
+::
+
+     Select         ((Relationship | And | Or)?, Group?, Sort?)
+     Insert         (Relations | And | Or)?
+     Delete         (Relationship | And | Or)?
+     Update         (Relations | And | Or)?
+
+     And            ((Relationship | And | Or), (Relationship | And | Or))
+     Or             ((Relationship | And | Or), (Relationship | And | Or))
+
+     Relationship   ((VariableRef, Comparison))
+
+     Comparison     ((Function | MathExpression | Keyword | Constant | VariableRef) +)
+
+     Function       (())
+     MathExpression ((MathExpression | Keyword | Constant | VariableRef), (MathExpression | Keyword | Constant | VariableRef))
+
+     Group          (VariableRef +)
+     Sort           (SortTerm +)
+     SortTerm       (VariableRef +)
+
+     VariableRef    ()
+     Variable       ()
+     Keyword        ()
+     Constant       ()
+
+
+Remarks
+-------
+
+- The current implementation does not support linking two relations of type
+  'is' with a OR. I do not think that the negation is  supported on this type 
+  of relation (XXX FIXME to be confirmed).
+
+- Relations defining the variables must be left to those using them. 
+  For example::
+
+     Point P where P abs X, P ord Y, P value X+Y
+
+  is valid, but::
+
+     Point P where P abs X, P value X+Y, P ord Y
+
+  is not.
+
+RQL logs
+--------
+
+You can configure the `CubicWeb` application to keep a log
+of the queries executed against your database. To do so, 
+edit the configuration file of your application 
+``.../etc/cubicweb.d/myapp/all-in-one.conf`` and uncomment the
+variable ``query-log-file``::
+
+  # web application query log file
+  query-log-file=/tmp/rql-myapp.log
+
+
+Conclusion
+==========
+
+Limitations
+-----------
+
+It lacks at the moment:
+
+- COALESCE
+
+- restrictions on groups (HAVING)
+
+and certainly other things ...
+
+A disadvantage is that to use this language we must know the
+format used (with real relation names and entities, not those viewing
+in the user interface). On the other hand, we can not really bypass
+that, and it is the job of a user interface to hide the RQL.
+
+
+Topics
+------
+
+It would be convenient to express the schema matching
+relations (non-recursive rules)::
+
+     Document class Type <-> Document occurence_of Fiche class Type
+     Sheet class Type    <-> Form collection Collection class Type
+    
+Therefore 1. becomes::
+
+     Document X where
+     X class C, C name 'Cartoon'
+     X owned_by U, U login 'syt'
+     X available true
+
+I'm not sure that we should handle this at RQL level ...
+
+There should also be a special relation 'anonymous'.
+
+
+
+.. _Versa: http://uche.ogbuji.net/tech/rdf/versa/
+.. _SPARQL: http://www.w3.org/TR/rdf-sparql-query/
+
+
+[FIXME] see also RQL documentation in source rql/doc.
--- a/doc/book/en/D000-annex.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/D000-annex.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -12,9 +12,10 @@
    :maxdepth: 1
 
    D010-faq.en.txt
-   D020-api-reference.en.txt
-   D030-architecture.en.txt
-   D040-modules-stdlib.en.txt
-   D050-modules-cbw-api.en.txt
-   D060-mercurial.en.txt
-   D070-cookbook.en.txt
+   D020-cookbook.en.txt
+   D030-cubicweb-ctl.en.txt
+   D040-api-reference.en.txt
+   D050-architecture.en.txt
+   D060-modules-stdlib.en.txt
+   D070-modules-cbw-api.en.txt
+   D080-mercurial.en.txt
--- a/doc/book/en/D010-faq.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/D010-faq.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -135,19 +135,19 @@
   `AppRsetObject` instances are selected on a request and a result
   set. `AppObject` instances are directly selected by id.
 
-HOW TO
-======
-
-[TO COMPLETE]
-
-
 * How to update a database after a schema modification?
 
   It depends on what has been modified in the schema.
 
-  * Update of a non final relation.
+  * Update of an attribute permissions and properties: 
+    ``synchronize_eschema('MyEntity')``.
 
-  * Update of a final relation.
+  * Update of a relation permissions and properties: 
+    ``synchronize_rschema('MyRelation')``.
+
+  * Add an attribute: ``add_attribute('MyEntityType', 'myattr')``.
+
+  * Add a relation: ``add_relation_definition('SubjRelation', 'MyRelation', 'ObjRelation')``.
 
 
 * How to create an anonymous user?
@@ -164,9 +164,16 @@
     anonymous-password=anon
 
   You also must ensure that this `anon` user is a registered user of
-  the DB backend. This could be the admin account (for development
+  the DB backend. If not, you can create through the administation
+  interface of your instance by adding a user with the role `guests`.
+  This could be the admin account (for development
   purposes, of course).
 
+.. note::
+    While creating a new instance, you can decide to allow access
+    to anonymous user, which will automatically execute what is
+    decribed above.
+
 
 * How to change the application logo?
 
@@ -225,3 +232,13 @@
   This will yield additional WARNINGs, like this: ::
 
     2009-01-09 16:43:52 - (cubicweb.selectors) WARNING: selector one_line_rset returned 0 for <class 'cubicweb.web.views.basecomponents.WFHistoryVComponent'>
+
+* How to format an entity date attribute?
+
+  If your schema has an attribute of type Date or Datetime, you might
+  want to format it. First, you should define your preferred format using
+  the site configuration panel ``http://appurl/view?vid=systemepropertiesform``
+  and then set ``ui.date`` and/or ``ui.datetime``.
+  Then in the view code, use::
+    
+    self.format_date(entity.date_attribute)
--- a/doc/book/en/D020-api-reference.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-API Reference
-=============
-
-Schema API
-----------
-
-Base Types
-~~~~~~~~~~
-
-Base types are defined as a set in yams.BASE_TYPES that includes:
-`String`, `Int`, `Float`, `Boolean`, `Date`, `Time`, `Datetime`,
-`Interval`, `Password`, `Bytes`.
-
-See `yams' API <http://www.cubicweb.org/doc/en/modindex.html>`_
-
-Constraints
-~~~~~~~~~~~
-
-Constraints are defined in yams.constraints and include:
-`UniqueConstraint`, `SizeConstraint`, `RegexpConstraint`,
-`BoundConstraint`, `IntervalBoundConstraint`,
-`StaticVocabularyConstraint`, `MultipleStaticVocabularyConstraint`.
-
-See `yams' API <http://www.cubicweb.org/doc/en/modindex.html>`_
-
-Views API
----------
-
-See `yams' API <http://www.cubicweb.org/doc/en/modindex.html>`_
-[WRITE ME]
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D020-cookbook.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,64 @@
+.. -*- coding: utf-8 -*-
+
+Cook book
+=========
+
+We gathered together some of our tricks and scripts that could make
+life easier.
+
+
+* How to import LDAP users in `CubicWeb`?
+
+  Here is a very useful script which enables you to import LDAP users
+  into your `CubicWeb` application by running the following: ::
+
+
+    import os
+    import pwd
+    import sys
+
+    from logilab.common.db import get_connection
+
+    def getlogin():
+        """avoid usinng os.getlogin() because of strange tty / stdin problems
+        (man 3 getlogin)
+        Another solution would be to use $LOGNAME, $USER or $USERNAME
+        """
+        return pwd.getpwuid(os.getuid())[0]
+
+
+    try:
+        database = sys.argv[1]
+    except IndexError:
+        print 'USAGE: python ldap2system.py <database>'
+        sys.exit(1)
+
+    if raw_input('update %s db ? [y/n]: ' % database).strip().lower().startswith('y'):
+        cnx = get_connection(user=getlogin(), database=database)
+        cursor = cnx.cursor()
+
+        insert = ('INSERT INTO euser (creation_date, eid, modification_date, login, firstname, surname, last_login_time, upassword) '
+                  "VALUES (%(mtime)s, %(eid)s, %(mtime)s, %(login)s, %(firstname)s, %(surname)s, %(mtime)s, './fqEz5LeZnT6');")
+        update = "UPDATE entities SET source='system' WHERE eid=%(eid)s;"
+        cursor.execute("SELECT eid,type,source,extid,mtime FROM entities WHERE source!='system'")
+        for eid, type, source, extid, mtime in cursor.fetchall():
+            if type != 'CWUser':
+                print "don't know what to do with entity type", type
+                continue
+            if source != 'ldapuser':
+                print "don't know what to do with source type", source
+                continue
+            ldapinfos = dict(x.strip().split('=') for x in extid.split(','))
+            login = ldapinfos['uid']
+            firstname = ldapinfos['uid'][0].upper()
+            surname = ldapinfos['uid'][1:].capitalize()
+            if login != 'jcuissinat':
+                args = dict(eid=eid, type=type, source=source, login=login,
+                            firstname=firstname, surname=surname, mtime=mtime)
+                print args
+                cursor.execute(insert, args)
+                cursor.execute(update, args)
+
+        cnx.commit()
+        cnx.close()
+
--- a/doc/book/en/D030-architecture.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Server Architecture
--------------------
-
-.. image:: images/server-class-diagram.png
-
-`Diagramme ArgoUML`_
-
-[FIXME]
-Make a downloadable source of zargo file.
-
-.. _`Diagramme ArgoUML`: cubicweb.zargo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D030-cubicweb-ctl.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,122 @@
+.. -*- coding: utf-8 -*-
+
+.. _cubicweb-ctl:
+
+``cubicweb-ctl`` tool
+=====================
+
+`cubicweb-ctl` is the swiss knife to manage `CubicWeb` instances.
+The general syntax is ::
+
+  cubicweb-ctl <command> [options command] <arguments commands>
+
+To view available commands ::
+
+  cubicweb-ctl
+  cubicweb-ctl --help
+
+Please note that the commands available depends on the `CubicWeb` packages
+and cubes that have been installed.
+
+To view the help menu on specific command ::
+
+  cubicweb-ctl <command> --help
+
+Command to create a cube
+------------------------
+
+* ``newcube``, create a new cube on the file system based on the name
+  given in the parameters. This command create a cube from an application
+  skeleton that includes default files required for debian packaging.
+  
+
+Command to create an instance
+-----------------------------
+* ``create``, creates the files for the instance configuration
+* ``db-create``, creates the system database of an instance (tables and
+  extensions only)
+* ``db-init``, initializes the system database of an instance
+  (schema, groups, users, workflows...)
+
+By default, those three commandes are encapsulated in ``create`` so
+that they can be executed consecutively.
+
+Command to create an instance for Google AppEngine datastore source
+-------------------------------------------------------------------
+* ``newgapp``, creates the configuration files for an instance
+
+This command needs to be followed by the commands responsible for
+the database initialization. As those are specific to the `datastore`,
+specific Google AppEgine database, they are not available for now
+in cubicweb-ctl, but they are available in the instance created.
+
+For more details, please see :ref:`gaecontents` .
+
+Commands to control instances
+-----------------------------
+* ``start``, starts one or more or all instances
+* ``stop``, stops one or more or all instances
+* ``restart``, restarts one or more or all instances
+* ``status``, returns the status of the instance
+
+Commands to maintain instances
+------------------------------
+* ``upgrade``, launches the existing instances migration when a new version
+  of `CubicWeb` or the cubes installed is available
+* ``shell``, opens a migration shell for manual maintenance of the instance
+* ``db-dump``, creates a dump of the system database
+* ``db-restore``, restores a dump of the system database
+* ``db-check``, checks data integrity of an instance. If the automatic correction
+  is activated, it is recommanded to create a dump before this operation.
+* ``schema-sync``, synchronizes the persistent schema of an instance with
+  the application schema. It is recommanded to create a dump before this operation.
+
+Commands to maintain i18n catalogs
+----------------------------------
+* ``i18nlibupdate``, regenerates messages catalogs of the `CubicWeb` library
+* ``i18nupdate``, regenerates the messages catalogs of a cube
+* ``i18ncompile``, recompiles the messages catalogs of an instance. 
+  This is automatically done while upgrading.
+
+See also chapter :ref:`internationalisation`.
+
+Other commands
+--------------
+* ``list``, provides a list of the available configuration, cubes
+  and instances.
+* ``delete``, deletes an instance (configuration files and database)
+
+
+Create an instance from an existing cube
+````````````````````````````````````````
+
+To create an instance from an existing cube, execute the following
+command ::
+
+   cubicweb-ctl create <cube_name> <instance_name>
+
+This command will create the configuration files of an instance in
+``~/etc/cubicweb.d/<instance_name>``.
+The tool ``cubicweb-ctl`` allows you to execute the command ``db-create``
+and ``db-init`` when you run ``create`` so that you can complete an
+instance creation in a single command.
+
+If you decide not to execut those commands while ``cubicweb-ctl create``,
+then you will have to execute them seperately(``cubicweb-ctl db-create``,
+``cubicweb-ctl db-init`` ) otherwise your installation will not be complete
+and you will not be able to launch your instance.
+
+
+Creation of an instance from a new cube
+```````````````````````````````````````
+
+Create first your new cube cube ::
+
+   cubicweb-ctl newcube <mycube>
+
+This will create a new cube in ``/path/to/forest/cubicweb/cubes/<mycube>``
+for a Mercurial forest installation, or in ``/usr/share/cubicweb/cubes``
+for a debian packages installation, and then create an instance as 
+explained just above.
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D040-api-reference.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,33 @@
+.. -*- coding: utf-8 -*-
+
+API Reference
+=============
+
+Schema API
+----------
+
+Base Types
+~~~~~~~~~~
+
+Base types are defined as a set in yams.BASE_TYPES that includes:
+`String`, `Int`, `Float`, `Boolean`, `Date`, `Time`, `Datetime`,
+`Interval`, `Password`, `Bytes`.
+
+See `yams' API <http://www.cubicweb.org/doc/en/modindex.html>`_
+
+Constraints
+~~~~~~~~~~~
+
+Constraints are defined in yams.constraints and include:
+`UniqueConstraint`, `SizeConstraint`, `RegexpConstraint`,
+`BoundConstraint`, `IntervalBoundConstraint`,
+`StaticVocabularyConstraint`, `MultipleStaticVocabularyConstraint`.
+
+See `yams' API <http://www.cubicweb.org/doc/en/modindex.html>`_
+
+Views API
+---------
+
+See `yams' API <http://www.cubicweb.org/doc/en/modindex.html>`_
+[WRITE ME]
+
--- a/doc/book/en/D040-modules-stdlib.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-================
-Standard library
-================
-
-:mod:`cubes.addressbook` 
-========================
-
-.. automodule:: cubes.addressbook
-   :members:
-
-:mod:`cubes.basket` 
-========================
-
-.. automodule:: cubes.basket
-   :members:
-
-:mod:`cubes.blog` 
-========================
-
-.. automodule:: cubes.blog
-   :members:
-
-:mod:`cubes.book` 
-========================
-
-.. automodule:: cubes.book
-   :members:
-
-:mod:`cubes.comment` 
-========================
-
-.. automodule:: cubes.comment
-   :members:
-
-:mod:`cubes.company` 
-========================
-
-.. automodule:: cubes.company
-   :members:
-
-
-:mod:`cubes.conference` 
-========================
-
-.. automodule:: cubes.conference
-   :members:
-
-:mod:`cubes.email` 
-========================
-
-.. automodule:: cubes.email
-   :members:
-
-:mod:`cubes.event` 
-========================
-
-.. automodule:: cubes.event
-   :members:
-
-:mod:`cubes.expense` 
-========================
-
-.. automodule:: cubes.expense
-   :members:
-
-
-:mod:`cubes.file` 
-========================
-
-.. automodule:: cubes.file
-   :members:
-
-:mod:`cubes.folder` 
-========================
-
-.. automodule:: cubes.folder
-   :members:
-
-:mod:`cubes.i18ncontent` 
-========================
-
-.. automodule:: cubes.i18ncontent
-   :members:
-
-:mod:`cubes.invoice` 
-========================
-
-.. automodule:: cubes.invoice
-   :members:
-
-:mod:`cubes.keyword` 
-========================
-
-.. automodule:: cubes.keyword
-   :members:
-
-:mod:`cubes.link` 
-========================
-
-.. automodule:: cubes.link
-   :members:
-
-:mod:`cubes.mailinglist` 
-========================
-
-.. automodule:: cubes.mailinglist
-   :members:
-
-:mod:`cubes.person` 
-========================
-
-.. automodule:: cubes.person
-   :members:
-
-:mod:`cubes.shopcart` 
-========================
-
-.. automodule:: cubes.shopcart
-   :members:
-
-:mod:`cubes.skillmat` 
-========================
-
-.. automodule:: cubes.skillmat
-   :members:
-
-:mod:`cubes.tag` 
-========================
-
-.. automodule:: cubes.tag
-   :members:
-
-:mod:`cubes.task` 
-========================
-
-.. automodule:: cubes.task
-   :members:
-
-:mod:`cubes.workcase` 
-========================
-
-.. automodule:: cubes.workcase
-   :members:
-
-:mod:`cubes.workorder` 
-========================
-
-.. automodule:: cubes.workorder
-   :members:
-
-:mod:`cubes.zone` 
-========================
-
-.. automodule:: cubes.zone
-   :members:
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D050-architecture.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,14 @@
+.. -*- coding: utf-8 -*-
+
+
+Server Architecture
+-------------------
+
+.. image:: images/server-class-diagram.png
+
+`Diagramme ArgoUML`_
+
+[FIXME]
+Make a downloadable source of zargo file.
+
+.. _`Diagramme ArgoUML`: cubicweb.zargo
--- a/doc/book/en/D050-modules-cbw-api.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1961 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-============
-CubicWeb API
-============
-
-:mod:`cubicweb.hercule`
-=======================
-
-.. automodule:: cubicweb.hercule
-   :members:
-
-:mod:`cubicweb.cwctl`
-=====================
-
-.. automodule:: cubicweb.cwctl
-   :members:
-
-:mod:`cubicweb.schema`
-======================
-
-.. automodule:: cubicweb.schema
-   :members:
-
-:mod:`cubicweb.cwconfig`
-========================
-
-.. automodule:: cubicweb.cwconfig
-   :members:
-
-:mod:`cubicweb.schemaviewer`
-============================
-
-.. automodule:: cubicweb.schemaviewer
-   :members:
-
-:mod:`cubicweb._exceptions`
-===========================
-
-.. automodule:: cubicweb._exceptions
-   :members:
-
-:mod:`cubicweb.dbapi`
-=====================
-
-.. automodule:: cubicweb.dbapi
-   :members:
-
-:mod:`cubicweb.toolsutils`
-==========================
-
-.. automodule:: cubicweb.toolsutils
-   :members:
-
-:mod:`cubicweb.cwvreg`
-======================
-
-.. automodule:: cubicweb.cwvreg
-   :members:
-
-:mod:`cubicweb.md5crypt`
-========================
-
-.. automodule:: cubicweb.md5crypt
-   :members:
-
-:mod:`cubicweb.rset`
-====================
-
-.. automodule:: cubicweb.rset
-   :members:
-
-:mod:`cubicweb`
-===============
-
-.. automodule:: cubicweb
-   :members:
-
-:mod:`cubicweb.setup`
-=====================
-
-.. automodule:: cubicweb.setup
-   :members:
-
-:mod:`cubicweb.gettext`
-=======================
-
-.. automodule:: cubicweb.gettext
-   :members:
-
-:mod:`cubicweb.interfaces`
-==========================
-
-.. automodule:: cubicweb.interfaces
-   :members:
-
-:mod:`cubicweb.vregistry`
-=========================
-
-.. automodule:: cubicweb.vregistry
-   :members:
-
-:mod:`cubicweb.web.httpcache`
-=============================
-
-.. automodule:: cubicweb.web.httpcache
-   :members:
-
-:mod:`cubicweb.web.webconfig`
-=============================
-
-.. automodule:: cubicweb.web.webconfig
-   :members:
-
-:mod:`cubicweb.web.request`
-===========================
-
-.. automodule:: cubicweb.web.request
-   :members:
-
-:mod:`cubicweb.web._exceptions`
-===============================
-
-.. automodule:: cubicweb.web._exceptions
-   :members:
-
-:mod:`cubicweb.web.webctl`
-==========================
-
-.. automodule:: cubicweb.web.webctl
-   :members:
-
-:mod:`cubicweb.web.application`
-===============================
-
-.. automodule:: cubicweb.web.application
-   :members:
-
-:mod:`cubicweb.web.controller`
-==============================
-
-.. automodule:: cubicweb.web.controller
-   :members:
-
-:mod:`cubicweb.web.widgets`
-===========================
-
-.. automodule:: cubicweb.web.widgets
-   :members:
-
-:mod:`cubicweb.web.htmlwidgets`
-===============================
-
-.. automodule:: cubicweb.web.htmlwidgets
-   :members:
-
-:mod:`cubicweb.web`
-===================
-
-.. automodule:: cubicweb.web
-   :members:
-
-:mod:`cubicweb.web.form`
-========================
-
-.. automodule:: cubicweb.web.form
-   :members:
-
-:mod:`cubicweb.web.box`
-=======================
-
-.. automodule:: cubicweb.web.box
-   :members:
-
-:mod:`cubicweb.web.component`
-=============================
-
-.. automodule:: cubicweb.web.component
-   :members:
-
-:mod:`cubicweb.web.action`
-==========================
-
-.. automodule:: cubicweb.web.action
-   :members:
-
-:mod:`cubicweb.web.facet`
-=========================
-
-.. automodule:: cubicweb.web.facet
-   :members:
-
-:mod:`cubicweb.web.views.plots`
-===============================
-
-.. automodule:: cubicweb.web.views.plots
-   :members:
-
-:mod:`cubicweb.web.views.error`
-===============================
-
-.. automodule:: cubicweb.web.views.error
-   :members:
-
-:mod:`cubicweb.web.views.magicsearch`
-=====================================
-
-.. automodule:: cubicweb.web.views.magicsearch
-   :members:
-
-:mod:`cubicweb.web.views.basetemplates`
-=======================================
-
-.. automodule:: cubicweb.web.views.basetemplates
-   :members:
-
-:mod:`cubicweb.web.views.idownloadable`
-=======================================
-
-.. automodule:: cubicweb.web.views.idownloadable
-   :members:
-
-:mod:`cubicweb.web.views.ajaxedit`
-==================================
-
-.. automodule:: cubicweb.web.views.ajaxedit
-   :members:
-
-:mod:`cubicweb.web.views.wfentities`
-====================================
-
-.. automodule:: cubicweb.web.views.wfentities
-   :members:
-
-:mod:`cubicweb.web.views.navigation`
-====================================
-
-.. automodule:: cubicweb.web.views.navigation
-   :members:
-
-:mod:`cubicweb.web.views.schemaentities`
-========================================
-
-.. automodule:: cubicweb.web.views.schemaentities
-   :members:
-
-:mod:`cubicweb.web.views.treeview`
-==================================
-
-.. automodule:: cubicweb.web.views.treeview
-   :members:
-
-:mod:`cubicweb.web.views.startup`
-=================================
-
-.. automodule:: cubicweb.web.views.startup
-   :members:
-
-:mod:`cubicweb.web.views.iprogress`
-===================================
-
-.. automodule:: cubicweb.web.views.iprogress
-   :members:
-
-:mod:`cubicweb.web.views.euser`
-===============================
-
-.. automodule:: cubicweb.web.views.euser
-   :members:
-
-:mod:`cubicweb.web.views.facets`
-================================
-
-.. automodule:: cubicweb.web.views.facets
-   :members:
-
-:mod:`cubicweb.web.views.emailaddress`
-======================================
-
-.. automodule:: cubicweb.web.views.emailaddress
-   :members:
-
-:mod:`cubicweb.web.views.sessions`
-==================================
-
-.. automodule:: cubicweb.web.views.sessions
-   :members:
-
-:mod:`cubicweb.web.views.timetable`
-===================================
-
-.. automodule:: cubicweb.web.views.timetable
-   :members:
-
-:mod:`cubicweb.web.views.timeline`
-==================================
-
-.. automodule:: cubicweb.web.views.timeline
-   :members:
-
-:mod:`cubicweb.web.views.baseviews`
-===================================
-
-.. automodule:: cubicweb.web.views.baseviews
-   :members:
-
-:mod:`cubicweb.web.views.boxes`
-===============================
-
-.. automodule:: cubicweb.web.views.boxes
-   :members:
-
-:mod:`cubicweb.web.views.old_calendar`
-======================================
-
-.. automodule:: cubicweb.web.views.old_calendar
-   :members:
-
-:mod:`cubicweb.web.views.card`
-==============================
-
-.. automodule:: cubicweb.web.views.card
-   :members:
-
-:mod:`cubicweb.web.views.ibreadcrumbs`
-======================================
-
-.. automodule:: cubicweb.web.views.ibreadcrumbs
-   :members:
-
-:mod:`cubicweb.web.views.basecontrollers`
-=========================================
-
-.. automodule:: cubicweb.web.views.basecontrollers
-   :members:
-
-:mod:`cubicweb.web.views.embedding`
-===================================
-
-.. automodule:: cubicweb.web.views.embedding
-   :members:
-
-:mod:`cubicweb.web.views.actions`
-=================================
-
-.. automodule:: cubicweb.web.views.actions
-   :members:
-
-:mod:`cubicweb.web.views.editcontroller`
-========================================
-
-.. automodule:: cubicweb.web.views.editcontroller
-   :members:
-
-:mod:`cubicweb.web.views.debug`
-===============================
-
-.. automodule:: cubicweb.web.views.debug
-   :members:
-
-:mod:`cubicweb.web.views.urlpublishing`
-=======================================
-
-.. automodule:: cubicweb.web.views.urlpublishing
-   :members:
-
-:mod:`cubicweb.web.views.baseforms`
-===================================
-
-.. automodule:: cubicweb.web.views.baseforms
-   :members:
-
-:mod:`cubicweb.web.views.urlrewrite`
-====================================
-
-.. automodule:: cubicweb.web.views.urlrewrite
-   :members:
-
-:mod:`cubicweb.web.views.massmailing`
-=====================================
-
-.. automodule:: cubicweb.web.views.massmailing
-   :members:
-
-:mod:`cubicweb.web.views`
-=========================
-
-.. automodule:: cubicweb.web.views
-   :members:
-
-:mod:`cubicweb.web.views.eproperties`
-=====================================
-
-.. automodule:: cubicweb.web.views.eproperties
-   :members:
-
-:mod:`cubicweb.web.views.tabs`
-==============================
-
-.. automodule:: cubicweb.web.views.tabs
-   :members:
-
-:mod:`cubicweb.web.views.vcard`
-===============================
-
-.. automodule:: cubicweb.web.views.vcard
-   :members:
-
-:mod:`cubicweb.web.views.wdoc`
-==============================
-
-.. automodule:: cubicweb.web.views.wdoc
-   :members:
-
-:mod:`cubicweb.web.views.authentication`
-========================================
-
-.. automodule:: cubicweb.web.views.authentication
-   :members:
-
-:mod:`cubicweb.web.views.tableview`
-===================================
-
-.. automodule:: cubicweb.web.views.tableview
-   :members:
-
-:mod:`cubicweb.web.views.management`
-====================================
-
-.. automodule:: cubicweb.web.views.management
-   :members:
-
-:mod:`cubicweb.web.views.igeocodable`
-=====================================
-
-.. automodule:: cubicweb.web.views.igeocodable
-   :members:
-
-:mod:`cubicweb.web.views.xbel`
-==============================
-
-.. automodule:: cubicweb.web.views.xbel
-   :members:
-
-:mod:`cubicweb.web.views.bookmark`
-==================================
-
-.. automodule:: cubicweb.web.views.bookmark
-   :members:
-
-:mod:`cubicweb.web.views.apacherewrite`
-=======================================
-
-.. automodule:: cubicweb.web.views.apacherewrite
-   :members:
-
-:mod:`cubicweb.web.views.dynimages`
-===================================
-
-.. automodule:: cubicweb.web.views.dynimages
-   :members:
-
-:mod:`cubicweb.web.views.searchrestriction`
-===========================================
-
-.. automodule:: cubicweb.web.views.searchrestriction
-   :members:
-
-:mod:`cubicweb.web.views.basecomponents`
-========================================
-
-.. automodule:: cubicweb.web.views.basecomponents
-   :members:
-
-:mod:`cubicweb.web.views.calendar`
-==================================
-
-.. automodule:: cubicweb.web.views.calendar
-   :members:
-
-:mod:`cubicweb.sobjects.supervising`
-====================================
-
-.. automodule:: cubicweb.sobjects.supervising
-   :members:
-
-:mod:`cubicweb.sobjects.hooks`
-==============================
-
-.. automodule:: cubicweb.sobjects.hooks
-   :members:
-
-:mod:`cubicweb.sobjects.email`
-==============================
-
-.. automodule:: cubicweb.sobjects.email
-   :members:
-
-:mod:`cubicweb.sobjects`
-========================
-
-.. automodule:: cubicweb.sobjects
-   :members:
-
-:mod:`cubicweb.sobjects.notification`
-=====================================
-
-.. automodule:: cubicweb.sobjects.notification
-   :members:
-
-:mod:`cubicweb.wsgi.request`
-============================
-
-.. automodule:: cubicweb.wsgi.request
-   :members:
-
-:mod:`cubicweb.wsgi`
-====================
-
-.. automodule:: cubicweb.wsgi
-   :members:
-
-:mod:`cubicweb.wsgi.handler`
-============================
-
-.. automodule:: cubicweb.wsgi.handler
-   :members:
-
-:mod:`cubicweb.etwist.server`
-=============================
-
-.. automodule:: cubicweb.etwist.server
-   :members:
-
-:mod:`cubicweb.etwist.request`
-==============================
-
-.. automodule:: cubicweb.etwist.request
-   :members:
-
-:mod:`cubicweb.etwist.twconfig`
-===============================
-
-.. automodule:: cubicweb.etwist.twconfig
-   :members:
-
-:mod:`cubicweb.etwist`
-======================
-
-.. automodule:: cubicweb.etwist
-   :members:
-
-:mod:`cubicweb.etwist.twctl`
-============================
-
-.. automodule:: cubicweb.etwist.twctl
-   :members:
-
-:mod:`cubicweb.goa.goaconfig`
-=============================
-
-.. automodule:: cubicweb.goa.goaconfig
-   :members:
-
-:mod:`cubicweb.goa.rqlinterpreter`
-==================================
-
-.. automodule:: cubicweb.goa.rqlinterpreter
-   :members:
-
-:mod:`cubicweb.goa.dbmyams`
-===========================
-
-.. automodule:: cubicweb.goa.dbmyams
-   :members:
-
-:mod:`cubicweb.goa.db`
-======================
-
-.. automodule:: cubicweb.goa.db
-   :members:
-
-:mod:`cubicweb.goa.goactl`
-==========================
-
-.. automodule:: cubicweb.goa.goactl
-   :members:
-
-:mod:`cubicweb.goa.goavreg`
-===========================
-
-.. automodule:: cubicweb.goa.goavreg
-   :members:
-
-:mod:`cubicweb.goa`
-===================
-
-.. automodule:: cubicweb.goa
-   :members:
-
-:mod:`cubicweb.goa.gaesource`
-=============================
-
-.. automodule:: cubicweb.goa.gaesource
-   :members:
-
-:mod:`cubicweb.goa.dbinit`
-==========================
-
-.. automodule:: cubicweb.goa.dbinit
-   :members:
-
-:mod:`cubicweb.goa.testlib`
-===========================
-
-.. automodule:: cubicweb.goa.testlib
-   :members:
-
-:mod:`cubicweb.goa.appobjects.dbmgmt`
-=====================================
-
-.. automodule:: cubicweb.goa.appobjects.dbmgmt
-   :members:
-
-:mod:`cubicweb.goa.appobjects.gauthservice`
-===========================================
-
-.. automodule:: cubicweb.goa.appobjects.gauthservice
-   :members:
-
-:mod:`cubicweb.goa.appobjects.sessions`
-=======================================
-
-.. automodule:: cubicweb.goa.appobjects.sessions
-   :members:
-
-:mod:`cubicweb.goa.appobjects`
-==============================
-
-.. automodule:: cubicweb.goa.appobjects
-   :members:
-
-:mod:`cubicweb.goa.appobjects.components`
-=========================================
-
-.. automodule:: cubicweb.goa.appobjects.components
-   :members:
-
-:mod:`cubicweb.goa.tools.laxctl`
-================================
-
-.. automodule:: cubicweb.goa.tools.laxctl
-   :members:
-
-:mod:`cubicweb.goa.tools.generate_schema_img`
-=============================================
-
-.. automodule:: cubicweb.goa.tools.generate_schema_img
-   :members:
-
-:mod:`cubicweb.goa.tools`
-=========================
-
-.. automodule:: cubicweb.goa.tools
-   :members:
-
-:mod:`cubicweb.goa.tools.i18n`
-==============================
-
-.. automodule:: cubicweb.goa.tools.i18n
-   :members:
-
-:mod:`cubicweb.goa.overrides.mttransforms`
-==========================================
-
-.. automodule:: cubicweb.goa.overrides.mttransforms
-   :members:
-
-:mod:`cubicweb.goa.overrides.rqlannotation`
-===========================================
-
-.. automodule:: cubicweb.goa.overrides.rqlannotation
-   :members:
-
-:mod:`cubicweb.goa.overrides.toolsutils`
-========================================
-
-.. automodule:: cubicweb.goa.overrides.toolsutils
-   :members:
-
-:mod:`cubicweb.goa.overrides`
-=============================
-
-.. automodule:: cubicweb.goa.overrides
-   :members:
-
-:mod:`cubicweb.goa.overrides.server__init__`
-============================================
-
-.. automodule:: cubicweb.goa.overrides.server__init__
-   :members:
-
-:mod:`cubicweb.goa.overrides.server_utils`
-==========================================
-
-.. automodule:: cubicweb.goa.overrides.server_utils
-   :members:
-
-:mod:`cubicweb.common.mttransforms`
-===================================
-
-.. automodule:: cubicweb.common.mttransforms
-   :members:
-
-:mod:`cubicweb.common.utils`
-============================
-
-.. automodule:: cubicweb.common.utils
-   :members:
-
-:mod:`cubicweb.common.schema`
-=============================
-
-.. automodule:: cubicweb.common.schema
-   :members:
-
-:mod:`cubicweb.common.tal`
-==========================
-
-.. automodule:: cubicweb.common.tal
-   :members:
-
-:mod:`cubicweb.common.appobject`
-================================
-
-.. automodule:: cubicweb.common.appobject
-   :members:
-
-:mod:`cubicweb.common.migration`
-================================
-
-.. automodule:: cubicweb.common.migration
-   :members:
-
-:mod:`cubicweb.common.rest`
-===========================
-
-.. automodule:: cubicweb.common.rest
-   :members:
-
-:mod:`cubicweb.common.html4zope`
-================================
-
-.. automodule:: cubicweb.common.html4zope
-   :members:
-
-:mod:`cubicweb.common.view`
-===========================
-
-.. automodule:: cubicweb.common.view
-   :members:
-
-:mod:`cubicweb.common.selectors`
-================================
-
-.. automodule:: cubicweb.common.selectors
-   :members:
-
-:mod:`cubicweb.common.entity`
-=============================
-
-.. automodule:: cubicweb.common.entity
-   :members:
-
-:mod:`cubicweb.common.mail`
-===========================
-
-.. automodule:: cubicweb.common.mail
-   :members:
-
-:mod:`cubicweb.common.mixins`
-=============================
-
-.. automodule:: cubicweb.common.mixins
-   :members:
-
-:mod:`cubicweb.common`
-======================
-
-.. automodule:: cubicweb.common
-   :members:
-
-:mod:`cubicweb.common.uilib`
-============================
-
-.. automodule:: cubicweb.common.uilib
-   :members:
-
-:mod:`cubicweb.common.registerers`
-==================================
-
-.. automodule:: cubicweb.common.registerers
-   :members:
-
-:mod:`cubicweb.common.i18n`
-===========================
-
-.. automodule:: cubicweb.common.i18n
-   :members:
-
-:mod:`cubicweb.entities.schemaobjs`
-===================================
-
-.. automodule:: cubicweb.entities.schemaobjs
-   :members:
-
-:mod:`cubicweb.entities.wfobjs`
-===============================
-
-.. automodule:: cubicweb.entities.wfobjs
-   :members:
-
-:mod:`cubicweb.entities`
-========================
-
-.. automodule:: cubicweb.entities
-   :members:
-
-:mod:`cubicweb.entities.authobjs`
-=================================
-
-.. automodule:: cubicweb.entities.authobjs
-   :members:
-
-:mod:`cubicweb.entities.lib`
-============================
-
-.. automodule:: cubicweb.entities.lib
-   :members:
-
-:mod:`cubicweb.server.server`
-=============================
-
-.. automodule:: cubicweb.server.server
-   :members:
-
-:mod:`cubicweb.server.utils`
-============================
-
-.. automodule:: cubicweb.server.utils
-   :members:
-
-:mod:`cubicweb.server.checkintegrity`
-=====================================
-
-.. automodule:: cubicweb.server.checkintegrity
-   :members:
-
-:mod:`cubicweb.server.rqlrewrite`
-=================================
-
-.. automodule:: cubicweb.server.rqlrewrite
-   :members:
-
-:mod:`cubicweb.server.rqlannotation`
-====================================
-
-.. automodule:: cubicweb.server.rqlannotation
-   :members:
-
-:mod:`cubicweb.server.hooks`
-============================
-
-.. automodule:: cubicweb.server.hooks
-   :members:
-
-:mod:`cubicweb.server.hooksmanager`
-===================================
-
-.. automodule:: cubicweb.server.hooksmanager
-   :members:
-
-:mod:`cubicweb.server.securityhooks`
-====================================
-
-.. automodule:: cubicweb.server.securityhooks
-   :members:
-
-:mod:`cubicweb.server.schemahooks`
-==================================
-
-.. automodule:: cubicweb.server.schemahooks
-   :members:
-
-:mod:`cubicweb.server.session`
-==============================
-
-.. automodule:: cubicweb.server.session
-   :members:
-
-:mod:`cubicweb.server.serverctl`
-================================
-
-.. automodule:: cubicweb.server.serverctl
-   :members:
-
-:mod:`cubicweb.server.serverconfig`
-===================================
-
-.. automodule:: cubicweb.server.serverconfig
-   :members:
-
-:mod:`cubicweb.server.pool`
-===========================
-
-.. automodule:: cubicweb.server.pool
-   :members:
-
-:mod:`cubicweb.server.mssteps`
-==============================
-
-.. automodule:: cubicweb.server.mssteps
-   :members:
-
-:mod:`cubicweb.server.hookhelper`
-=================================
-
-.. automodule:: cubicweb.server.hookhelper
-   :members:
-
-:mod:`cubicweb.server`
-======================
-
-.. automodule:: cubicweb.server
-   :members:
-
-:mod:`cubicweb.server.sqlutils`
-===============================
-
-.. automodule:: cubicweb.server.sqlutils
-   :members:
-
-:mod:`cubicweb.server.schemaserial`
-===================================
-
-.. automodule:: cubicweb.server.schemaserial
-   :members:
-
-:mod:`cubicweb.server.repository`
-=================================
-
-.. automodule:: cubicweb.server.repository
-   :members:
-
-:mod:`cubicweb.server.ssplanner`
-================================
-
-.. automodule:: cubicweb.server.ssplanner
-   :members:
-
-:mod:`cubicweb.server.msplanner`
-================================
-
-.. automodule:: cubicweb.server.msplanner
-   :members:
-
-:mod:`cubicweb.server.querier`
-==============================
-
-.. automodule:: cubicweb.server.querier
-   :members:
-
-:mod:`cubicweb.server.migractions`
-==================================
-
-.. automodule:: cubicweb.server.migractions
-   :members:
-
-:mod:`cubicweb.server.sources.rql2sql`
-======================================
-
-.. automodule:: cubicweb.server.sources.rql2sql
-   :members:
-
-:mod:`cubicweb.server.sources.ldapuser`
-=======================================
-
-.. automodule:: cubicweb.server.sources.ldapuser
-   :members:
-
-:mod:`cubicweb.server.sources`
-==============================
-
-.. automodule:: cubicweb.server.sources
-   :members:
-
-:mod:`cubicweb.server.sources.pyrorql`
-======================================
-
-.. automodule:: cubicweb.server.sources.pyrorql
-   :members:
-
-:mod:`cubicweb.server.sources.native`
-=====================================
-
-.. automodule:: cubicweb.server.sources.native
-   :members:
-
-:mod:`cubicweb.server.sources.extlite`
-======================================
-
-.. automodule:: cubicweb.server.sources.extlite
-   :members:
-
-:mod:`cubicweb.devtools.devctl`
-===============================
-
-.. automodule:: cubicweb.devtools.devctl
-   :members:
-
-:mod:`cubicweb.devtools.pkginfo`
-================================
-
-.. automodule:: cubicweb.devtools.pkginfo
-   :members:
-
-:mod:`cubicweb.devtools.migrtest`
-=================================
-
-.. automodule:: cubicweb.devtools.migrtest
-   :members:
-
-:mod:`cubicweb.devtools.htmlparser`
-===================================
-
-.. automodule:: cubicweb.devtools.htmlparser
-   :members:
-
-:mod:`cubicweb.devtools`
-========================
-
-.. automodule:: cubicweb.devtools
-   :members:
-
-:mod:`cubicweb.devtools.fill`
-=============================
-
-.. automodule:: cubicweb.devtools.fill
-   :members:
-
-:mod:`cubicweb.devtools._apptest`
-=================================
-
-.. automodule:: cubicweb.devtools._apptest
-   :members:
-
-:mod:`cubicweb.devtools.stresstester`
-=====================================
-
-.. automodule:: cubicweb.devtools.stresstester
-   :members:
-
-:mod:`cubicweb.devtools.fake`
-=============================
-
-.. automodule:: cubicweb.devtools.fake
-   :members:
-
-:mod:`cubicweb.devtools.apptest`
-================================
-
-.. automodule:: cubicweb.devtools.apptest
-   :members:
-
-:mod:`cubicweb.devtools.livetest`
-=================================
-
-.. automodule:: cubicweb.devtools.livetest
-   :members:
-
-:mod:`cubicweb.devtools.testlib`
-================================
-
-.. automodule:: cubicweb.devtools.testlib
-   :members:
-
-:mod:`cubicweb.devtools.repotest`
-=================================
-
-.. automodule:: cubicweb.devtools.repotest
-   :members:
-
-:mod:`cubicweb.devtools.cwtwill`
-================================
-
-.. automodule:: cubicweb.devtools.cwtwill
-   :members:
-
-:mod:`cubicweb.misc.cwdesklets.rqlsensor`
-=========================================
-
-.. automodule:: cubicweb.misc.cwdesklets.rqlsensor
-   :members:
-
-:mod:`cubicweb.embedded.mx`
-===========================
-
-.. automodule:: cubicweb.embedded.mx
-   :members:
-
-:mod:`cubicweb.embedded.mx.DateTime.mxDateTime_python`
-======================================================
-
-.. automodule:: cubicweb.embedded.mx.DateTime.mxDateTime_python
-   :members:
-
-:mod:`cubicweb.embedded.mx.DateTime.ARPA`
-=========================================
-
-.. automodule:: cubicweb.embedded.mx.DateTime.ARPA
-   :members:
-
-:mod:`cubicweb.embedded.mx.DateTime.ISO`
-========================================
-
-.. automodule:: cubicweb.embedded.mx.DateTime.ISO
-   :members:
-
-:mod:`cubicweb.embedded.mx.DateTime.Parser`
-===========================================
-
-.. automodule:: cubicweb.embedded.mx.DateTime.Parser
-   :members:
-
-:mod:`cubicweb.embedded.mx.DateTime`
-====================================
-
-.. automodule:: cubicweb.embedded.mx.DateTime
-   :members:
-
-:mod:`cubicweb.embedded.mx.DateTime.Timezone`
-=============================================
-
-.. automodule:: cubicweb.embedded.mx.DateTime.Timezone
-   :members:
-
-:mod:`cubicweb.embedded.mx.DateTime.DateTime`
-=============================================
-
-.. automodule:: cubicweb.embedded.mx.DateTime.DateTime
-   :members:
-
-:mod:`indexer`
-==============
-
-.. automodule:: indexer
-   :members:
-
-:mod:`indexer.indexable_objects`
-================================
-
-.. automodule:: indexer.indexable_objects
-   :members:
-
-:mod:`indexer.search`
-=====================
-
-.. automodule:: indexer.search
-   :members:
-
-:mod:`indexer.query_objects`
-============================
-
-.. automodule:: indexer.query_objects
-   :members:
-
-:mod:`indexer._exceptions`
-==========================
-
-.. automodule:: indexer._exceptions
-   :members:
-
-:mod:`indexer.setup`
-====================
-
-.. automodule:: indexer.setup
-   :members:
-
-:mod:`indexer.query`
-====================
-
-.. automodule:: indexer.query
-   :members:
-
-:mod:`logilab`
-==============
-
-.. automodule:: logilab
-   :members:
-
-:mod:`logilab.constraint.propagation`
-=====================================
-
-.. automodule:: logilab.constraint.propagation
-   :members:
-
-:mod:`logilab.constraint.psyco_wrapper`
-=======================================
-
-.. automodule:: logilab.constraint.psyco_wrapper
-   :members:
-
-:mod:`logilab.constraint.fd`
-============================
-
-.. automodule:: logilab.constraint.fd
-   :members:
-
-:mod:`logilab.constraint.fi`
-============================
-
-.. automodule:: logilab.constraint.fi
-   :members:
-
-:mod:`logilab.constraint`
-=========================
-
-.. automodule:: logilab.constraint
-   :members:
-
-:mod:`logilab.constraint.setup`
-===============================
-
-.. automodule:: logilab.constraint.setup
-   :members:
-
-:mod:`logilab.constraint.interfaces`
-====================================
-
-.. automodule:: logilab.constraint.interfaces
-   :members:
-
-:mod:`logilab.constraint.distributors`
-======================================
-
-.. automodule:: logilab.constraint.distributors
-   :members:
-
-:mod:`logilab.common.clcommands`
-================================
-
-.. automodule:: logilab.common.clcommands
-   :members:
-
-:mod:`logilab.common.table`
-===========================
-
-.. automodule:: logilab.common.table
-   :members:
-
-:mod:`logilab.common.interface`
-===============================
-
-.. automodule:: logilab.common.interface
-   :members:
-
-:mod:`logilab.common.logger`
-============================
-
-.. automodule:: logilab.common.logger
-   :members:
-
-:mod:`logilab.common.cli`
-=========================
-
-.. automodule:: logilab.common.cli
-   :members:
-
-:mod:`logilab.common.xmlrpcutils`
-=================================
-
-.. automodule:: logilab.common.xmlrpcutils
-   :members:
-
-:mod:`logilab.common.corbautils`
-================================
-
-.. automodule:: logilab.common.corbautils
-   :members:
-
-:mod:`logilab.common.cache`
-===========================
-
-.. automodule:: logilab.common.cache
-   :members:
-
-:mod:`logilab.common.astutils`
-==============================
-
-.. automodule:: logilab.common.astutils
-   :members:
-
-:mod:`logilab.common.daemon`
-============================
-
-.. automodule:: logilab.common.daemon
-   :members:
-
-:mod:`logilab.common.tree`
-==========================
-
-.. automodule:: logilab.common.tree
-   :members:
-
-:mod:`logilab.common.textutils`
-===============================
-
-.. automodule:: logilab.common.textutils
-   :members:
-
-:mod:`logilab.common.modutils`
-==============================
-
-.. automodule:: logilab.common.modutils
-   :members:
-
-:mod:`logilab.common.fileutils`
-===============================
-
-.. automodule:: logilab.common.fileutils
-   :members:
-
-:mod:`logilab.common.patricia`
-==============================
-
-.. automodule:: logilab.common.patricia
-   :members:
-
-:mod:`logilab.common.date`
-==========================
-
-.. automodule:: logilab.common.date
-   :members:
-
-:mod:`logilab.common.optparser`
-===============================
-
-.. automodule:: logilab.common.optparser
-   :members:
-
-:mod:`logilab.common.twisted_distutils`
-=======================================
-
-.. automodule:: logilab.common.twisted_distutils
-   :members:
-
-:mod:`logilab.common.decorators`
-================================
-
-.. automodule:: logilab.common.decorators
-   :members:
-
-:mod:`logilab.common.db`
-========================
-
-.. automodule:: logilab.common.db
-   :members:
-
-:mod:`logilab.common.deprecation`
-=================================
-
-.. automodule:: logilab.common.deprecation
-   :members:
-
-:mod:`logilab.common.tasksqueue`
-================================
-
-.. automodule:: logilab.common.tasksqueue
-   :members:
-
-:mod:`logilab.common.changelog`
-===============================
-
-.. automodule:: logilab.common.changelog
-   :members:
-
-:mod:`logilab.common.shellutils`
-================================
-
-.. automodule:: logilab.common.shellutils
-   :members:
-
-:mod:`logilab.common.sqlgen`
-============================
-
-.. automodule:: logilab.common.sqlgen
-   :members:
-
-:mod:`logilab.common.optik_ext`
-===============================
-
-.. automodule:: logilab.common.optik_ext
-   :members:
-
-:mod:`logilab.common.configuration`
-===================================
-
-.. automodule:: logilab.common.configuration
-   :members:
-
-:mod:`logilab.common.visitor`
-=============================
-
-.. automodule:: logilab.common.visitor
-   :members:
-
-:mod:`logilab.common.pytest`
-============================
-
-.. automodule:: logilab.common.pytest
-   :members:
-
-:mod:`logilab.common`
-=====================
-
-.. automodule:: logilab.common
-   :members:
-
-:mod:`logilab.common.setup`
-===========================
-
-.. automodule:: logilab.common.setup
-   :members:
-
-:mod:`logilab.common.logservice`
-================================
-
-.. automodule:: logilab.common.logservice
-   :members:
-
-:mod:`logilab.common.debugger`
-==============================
-
-.. automodule:: logilab.common.debugger
-   :members:
-
-:mod:`logilab.common.html`
-==========================
-
-.. automodule:: logilab.common.html
-   :members:
-
-:mod:`logilab.common.vcgutils`
-==============================
-
-.. automodule:: logilab.common.vcgutils
-   :members:
-
-:mod:`logilab.common.compat`
-============================
-
-.. automodule:: logilab.common.compat
-   :members:
-
-:mod:`logilab.common.logging_ext`
-=================================
-
-.. automodule:: logilab.common.logging_ext
-   :members:
-
-:mod:`logilab.common.umessage`
-==============================
-
-.. automodule:: logilab.common.umessage
-   :members:
-
-:mod:`logilab.common.proc`
-==========================
-
-.. automodule:: logilab.common.proc
-   :members:
-
-:mod:`logilab.common.monclient`
-===============================
-
-.. automodule:: logilab.common.monclient
-   :members:
-
-:mod:`logilab.common.bind`
-==========================
-
-.. automodule:: logilab.common.bind
-   :members:
-
-:mod:`logilab.common.graph`
-===========================
-
-.. automodule:: logilab.common.graph
-   :members:
-
-:mod:`logilab.common.testlib`
-=============================
-
-.. automodule:: logilab.common.testlib
-   :members:
-
-:mod:`logilab.common.contexts`
-==============================
-
-.. automodule:: logilab.common.contexts
-   :members:
-
-:mod:`logilab.common.adbh`
-==========================
-
-.. automodule:: logilab.common.adbh
-   :members:
-
-:mod:`logilab.common.pdf_ext`
-=============================
-
-.. automodule:: logilab.common.pdf_ext
-   :members:
-
-:mod:`logilab.common.monserver`
-===============================
-
-.. automodule:: logilab.common.monserver
-   :members:
-
-:mod:`logilab.common.ureports.nodes`
-====================================
-
-.. automodule:: logilab.common.ureports.nodes
-   :members:
-
-:mod:`logilab.common.ureports`
-==============================
-
-.. automodule:: logilab.common.ureports
-   :members:
-
-:mod:`logilab.common.ureports.html_writer`
-==========================================
-
-.. automodule:: logilab.common.ureports.html_writer
-   :members:
-
-:mod:`logilab.common.ureports.text_writer`
-==========================================
-
-.. automodule:: logilab.common.ureports.text_writer
-   :members:
-
-:mod:`logilab.common.ureports.docbook_writer`
-=============================================
-
-.. automodule:: logilab.common.ureports.docbook_writer
-   :members:
-
-:mod:`logilab.mtconverter.engine`
-=================================
-
-.. automodule:: logilab.mtconverter.engine
-   :members:
-
-:mod:`logilab.mtconverter.transform`
-====================================
-
-.. automodule:: logilab.mtconverter.transform
-   :members:
-
-:mod:`logilab.mtconverter`
-==========================
-
-.. automodule:: logilab.mtconverter
-   :members:
-
-:mod:`logilab.mtconverter.setup`
-================================
-
-.. automodule:: logilab.mtconverter.setup
-   :members:
-
-:mod:`logilab.mtconverter.transforms.html2text`
-===============================================
-
-.. automodule:: logilab.mtconverter.transforms.html2text
-   :members:
-
-:mod:`logilab.mtconverter.transforms.cmdtransforms`
-===================================================
-
-.. automodule:: logilab.mtconverter.transforms.cmdtransforms
-   :members:
-
-:mod:`logilab.mtconverter.transforms.python`
-============================================
-
-.. automodule:: logilab.mtconverter.transforms.python
-   :members:
-
-:mod:`logilab.mtconverter.transforms.pygmentstransforms`
-========================================================
-
-.. automodule:: logilab.mtconverter.transforms.pygmentstransforms
-   :members:
-
-:mod:`logilab.mtconverter.transforms`
-=====================================
-
-.. automodule:: logilab.mtconverter.transforms
-   :members:
-
-:mod:`logilab.mtconverter.transforms.piltransforms`
-===================================================
-
-.. automodule:: logilab.mtconverter.transforms.piltransforms
-   :members:
-
-:mod:`logilab.devtools.cvstatus`
-================================
-
-.. automodule:: logilab.devtools.cvstatus
-   :members:
-
-:mod:`logilab.devtools.changelog`
-=================================
-
-.. automodule:: logilab.devtools.changelog
-   :members:
-
-:mod:`logilab.devtools`
-=======================
-
-.. automodule:: logilab.devtools
-   :members:
-
-:mod:`logilab.devtools.setup`
-=============================
-
-.. automodule:: logilab.devtools.setup
-   :members:
-
-:mod:`logilab.devtools.cvslog`
-==============================
-
-.. automodule:: logilab.devtools.cvslog
-   :members:
-
-:mod:`logilab.devtools.lgp.utils`
-=================================
-
-.. automodule:: logilab.devtools.lgp.utils
-   :members:
-
-:mod:`logilab.devtools.lgp.tag`
-===============================
-
-.. automodule:: logilab.devtools.lgp.tag
-   :members:
-
-:mod:`logilab.devtools.lgp.setupinfo`
-=====================================
-
-.. automodule:: logilab.devtools.lgp.setupinfo
-   :members:
-
-:mod:`logilab.devtools.lgp.changelog`
-=====================================
-
-.. automodule:: logilab.devtools.lgp.changelog
-   :members:
-
-:mod:`logilab.devtools.lgp.preparedist`
-=======================================
-
-.. automodule:: logilab.devtools.lgp.preparedist
-   :members:
-
-:mod:`logilab.devtools.lgp.build`
-=================================
-
-.. automodule:: logilab.devtools.lgp.build
-   :members:
-
-:mod:`logilab.devtools.lgp.clean`
-=================================
-
-.. automodule:: logilab.devtools.lgp.clean
-   :members:
-
-:mod:`logilab.devtools.lgp`
-===========================
-
-.. automodule:: logilab.devtools.lgp
-   :members:
-
-:mod:`logilab.devtools.lgp.setup`
-=================================
-
-.. automodule:: logilab.devtools.lgp.setup
-   :members:
-
-:mod:`logilab.devtools.lgp.check`
-=================================
-
-.. automodule:: logilab.devtools.lgp.check
-   :members:
-
-:mod:`logilab.devtools.lgp.exceptions`
-======================================
-
-.. automodule:: logilab.devtools.lgp.exceptions
-   :members:
-
-:mod:`logilab.devtools.templates`
-=================================
-
-.. automodule:: logilab.devtools.templates
-   :members:
-
-:mod:`logilab.devtools.templates.setup`
-=======================================
-
-.. automodule:: logilab.devtools.templates.setup
-   :members:
-
-:mod:`logilab.devtools.lib.coverage`
-====================================
-
-.. automodule:: logilab.devtools.lib.coverage
-   :members:
-
-:mod:`logilab.devtools.lib.manifest`
-====================================
-
-.. automodule:: logilab.devtools.lib.manifest
-   :members:
-
-:mod:`logilab.devtools.lib.pkginfo`
-===================================
-
-.. automodule:: logilab.devtools.lib.pkginfo
-   :members:
-
-:mod:`logilab.devtools.lib`
-===========================
-
-.. automodule:: logilab.devtools.lib
-   :members:
-
-:mod:`logilab.devtools.vcslib.cvsparse`
-=======================================
-
-.. automodule:: logilab.devtools.vcslib.cvsparse
-   :members:
-
-:mod:`logilab.devtools.vcslib.svn`
-==================================
-
-.. automodule:: logilab.devtools.vcslib.svn
-   :members:
-
-:mod:`logilab.devtools.vcslib.node`
-===================================
-
-.. automodule:: logilab.devtools.vcslib.node
-   :members:
-
-:mod:`logilab.devtools.vcslib`
-==============================
-
-.. automodule:: logilab.devtools.vcslib
-   :members:
-
-:mod:`logilab.devtools.vcslib.interfaces`
-=========================================
-
-.. automodule:: logilab.devtools.vcslib.interfaces
-   :members:
-
-:mod:`logilab.devtools.vcslib.cvs`
-==================================
-
-.. automodule:: logilab.devtools.vcslib.cvs
-   :members:
-
-:mod:`logilab.devtools.vcslib.hg`
-=================================
-
-.. automodule:: logilab.devtools.vcslib.hg
-   :members:
-
-:mod:`rql.nodes`
-================
-
-.. automodule:: rql.nodes
-   :members:
-
-:mod:`rql.undo`
-===============
-
-.. automodule:: rql.undo
-   :members:
-
-:mod:`rql.utils`
-================
-
-.. automodule:: rql.utils
-   :members:
-
-:mod:`rql.base`
-===============
-
-.. automodule:: rql.base
-   :members:
-
-:mod:`rql.analyze`
-==================
-
-.. automodule:: rql.analyze
-   :members:
-
-:mod:`rql._exceptions`
-======================
-
-.. automodule:: rql._exceptions
-   :members:
-
-:mod:`rql.compare`
-==================
-
-.. automodule:: rql.compare
-   :members:
-
-:mod:`rql.stmts`
-================
-
-.. automodule:: rql.stmts
-   :members:
-
-:mod:`rql.parser_main`
-======================
-
-.. automodule:: rql.parser_main
-   :members:
-
-:mod:`rql.stcheck`
-==================
-
-.. automodule:: rql.stcheck
-   :members:
-
-:mod:`rql.parser`
-=================
-
-.. automodule:: rql.parser
-   :members:
-
-:mod:`rql`
-==========
-
-.. automodule:: rql
-   :members:
-
-:mod:`rql.setup`
-================
-
-.. automodule:: rql.setup
-   :members:
-
-:mod:`rql.interfaces`
-=====================
-
-.. automodule:: rql.interfaces
-   :members:
-
-:mod:`rql.editextensions`
-=========================
-
-.. automodule:: rql.editextensions
-   :members:
-
-:mod:`rql.fol`
-==============
-
-.. automodule:: rql.fol
-   :members:
-
-:mod:`rqlgen`
-=============
-
-.. automodule:: rqlgen
-   :members:
-
-:mod:`yams.schema`
-==================
-
-.. automodule:: yams.schema
-   :members:
-
-:mod:`yams.reader`
-==================
-
-.. automodule:: yams.reader
-   :members:
-
-:mod:`yams.schema2sql`
-======================
-
-.. automodule:: yams.schema2sql
-   :members:
-
-:mod:`yams._exceptions`
-=======================
-
-.. automodule:: yams._exceptions
-   :members:
-
-:mod:`yams.sqlreader`
-=====================
-
-.. automodule:: yams.sqlreader
-   :members:
-
-:mod:`yams.schema2dot`
-======================
-
-.. automodule:: yams.schema2dot
-   :members:
-
-:mod:`yams`
-===========
-
-.. automodule:: yams
-   :members:
-
-:mod:`yams.setup`
-=================
-
-.. automodule:: yams.setup
-   :members:
-
-:mod:`yams.interfaces`
-======================
-
-.. automodule:: yams.interfaces
-   :members:
-
-:mod:`yams.buildobjs`
-=====================
-
-.. automodule:: yams.buildobjs
-   :members:
-
-:mod:`yams.constraints`
-=======================
-
-.. automodule:: yams.constraints
-   :members:
--- a/doc/book/en/D060-mercurial.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _MercurialPresentation:
-
-Introducing Mercurial
-=====================
-
-Introduction
-````````````
-Mercurial_ manages a distributed repository containing revisions
-trees (each revision indicates the changes required to obtain the
-next, and so on). Locally, we have a repository containing revisions
-tree, and a working directory. It is possible
-to put in its working directory, one of the versions of its local repository,
-modify and then push it in its repository. 
-It is also possible to get revisions from another repository or to export
-its own revisions from the local repository to another repository.
-
-.. _Mercurial: http://www.selenic.com/mercurial/
-
-In contrast to CVS/Subversion, we usually create a repository by
-project to manage.
-
-In a collaborative development, we usually create a central repository
-accessible to all developers of the project. These central repository is used
-as a reference. According to its needs, then everyone can have a local repository,
-that you will have to synchronize with the central repository from time to time.
-
-
-Major commands
-``````````````
-* Create a local repository::
-
-     hg clone ssh://myhost//home/src/repo
-
-* See the contents of the local repository (graphical tool in Tk)::
-
-     hgview
-
-* Add a sub-directory or file in the current directory::
-
-     hg add subdir
-
-* Move to the working directory a specific revision (or last
-  revision) from the local repository::
-
-     hg update [identifier-revision]
-     hg up [identifier-revision]
-
-* Get in its local repository, the tree of revisions contained in a
-  remote repository (this does not change the local directory)::
-
-     hg pull ssh://myhost//home/src/repo
-     hg pull -u ssh://myhost//home/src/repo # equivalent to pull + update
-
-* See what are the heads of branches of the local repository if a `pull`
-  returned a new branch::
-
-     hg heads
-
-* Submit the working directory in the local repository (and create a new
-  revision)::
-
-     hg commit
-     hg ci
-
-* Merge with the mother revision of local directory, another revision from
-  the local respository (the new revision will be then two mothers
-  revisions)::
-
-     hg merge identifier-revision
-
-* Export to a remote repository, the tree of revisions in its content
-  local respository (this does not change the local directory)::
-
-     hg push ssh://myhost//home/src/repo
-
-* See what local revisions are not in another repository::
-
-     hg outgoing ssh://myhost//home/src/repo
-
-* See what are the revisions of a repository not found locally::
-
-     hg incoming ssh://myhost//home/src/repo
-
-* See what is the revision of the local repository which has been taken out 
-  from the working directory and amended::
-
-     hg parent
-
-* See the differences between the working directory and the mother revision
-  of the local repository, possibly to submit them in the local repository::
-
-     hg diff
-     hg commit-tool
-     hg ct
-
-
-Best Practices
-``````````````
-* Remember to `hg pull -u` regularly, and particularly before
-   a `hg commit`.
-
-* Remember to `hg push` when your repository contains a version
-  relatively stable of your changes.
-
-* If a `hg pull -u` created a new branch head:
-
-   1. find its identifier with `hg head`
-   2. merge with `hg merge`
-   3. `hg ci`
-   4. `hg push`
-
-Installation of the forest extension
-````````````````````````````````````
-
-Set up the forest extension by getting a copy of the sources 
-from http://hg.akoha.org/hgforest/ and adding the following 
-lines to your ``~/.hgrc``: ::
-
-   [extensions]
-   hgext.forest=
-   # or, if forest.py is not in the hgext dir:
-   # forest=/path/to/forest.py
-
-
-More information
-````````````````
-
-For more information about Mercurial, please refer to the Mercurial project online documentation_.
-
-.. _documentation: http://www.selenic.com/mercurial/wiki/
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D060-modules-stdlib.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,158 @@
+.. -*- coding: utf-8 -*-
+
+================
+Standard library
+================
+
+:mod:`cubes.addressbook` 
+========================
+
+.. automodule:: cubes.addressbook
+   :members:
+
+:mod:`cubes.basket` 
+========================
+
+.. automodule:: cubes.basket
+   :members:
+
+:mod:`cubes.blog` 
+========================
+
+.. automodule:: cubes.blog
+   :members:
+
+:mod:`cubes.book` 
+========================
+
+.. automodule:: cubes.book
+   :members:
+
+:mod:`cubes.comment` 
+========================
+
+.. automodule:: cubes.comment
+   :members:
+
+:mod:`cubes.company` 
+========================
+
+.. automodule:: cubes.company
+   :members:
+
+
+:mod:`cubes.conference` 
+========================
+
+.. automodule:: cubes.conference
+   :members:
+
+:mod:`cubes.email` 
+========================
+
+.. automodule:: cubes.email
+   :members:
+
+:mod:`cubes.event` 
+========================
+
+.. automodule:: cubes.event
+   :members:
+
+:mod:`cubes.expense` 
+========================
+
+.. automodule:: cubes.expense
+   :members:
+
+
+:mod:`cubes.file` 
+========================
+
+.. automodule:: cubes.file
+   :members:
+
+:mod:`cubes.folder` 
+========================
+
+.. automodule:: cubes.folder
+   :members:
+
+:mod:`cubes.i18ncontent` 
+========================
+
+.. automodule:: cubes.i18ncontent
+   :members:
+
+:mod:`cubes.invoice` 
+========================
+
+.. automodule:: cubes.invoice
+   :members:
+
+:mod:`cubes.keyword` 
+========================
+
+.. automodule:: cubes.keyword
+   :members:
+
+:mod:`cubes.link` 
+========================
+
+.. automodule:: cubes.link
+   :members:
+
+:mod:`cubes.mailinglist` 
+========================
+
+.. automodule:: cubes.mailinglist
+   :members:
+
+:mod:`cubes.person` 
+========================
+
+.. automodule:: cubes.person
+   :members:
+
+:mod:`cubes.shopcart` 
+========================
+
+.. automodule:: cubes.shopcart
+   :members:
+
+:mod:`cubes.skillmat` 
+========================
+
+.. automodule:: cubes.skillmat
+   :members:
+
+:mod:`cubes.tag` 
+========================
+
+.. automodule:: cubes.tag
+   :members:
+
+:mod:`cubes.task` 
+========================
+
+.. automodule:: cubes.task
+   :members:
+
+:mod:`cubes.workcase` 
+========================
+
+.. automodule:: cubes.workcase
+   :members:
+
+:mod:`cubes.workorder` 
+========================
+
+.. automodule:: cubes.workorder
+   :members:
+
+:mod:`cubes.zone` 
+========================
+
+.. automodule:: cubes.zone
+   :members:
+
--- a/doc/book/en/D070-cookbook.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Cook book
-=========
-
-We gathered together some of our tricks and scripts that could make
-life easier.
-
-
-* How to import LDAP users in `CubicWeb`?
-
-  Here is a very usefull script which enables you to import LDAP users
-  into your `CubicWeb` application by running the following: ::
-
-
-    import os
-    import pwd
-    import sys
-
-    from logilab.common.db import get_connection
-
-    def getlogin():
-        """avoid usinng os.getlogin() because of strange tty / stdin problems
-        (man 3 getlogin)
-        Another solution would be to use $LOGNAME, $USER or $USERNAME
-        """
-        return pwd.getpwuid(os.getuid())[0]
-
-
-    try:
-        database = sys.argv[1]
-    except IndexError:
-        print 'USAGE: python ldap2system.py <database>'
-        sys.exit(1)
-
-    if raw_input('update %s db ? [y/n]: ' % database).strip().lower().startswith('y'):
-        cnx = get_connection(user=getlogin(), database=database)
-        cursor = cnx.cursor()
-
-        insert = ('INSERT INTO euser (creation_date, eid, modification_date, login, firstname, surname, last_login_time, upassword) '
-                  "VALUES (%(mtime)s, %(eid)s, %(mtime)s, %(login)s, %(firstname)s, %(surname)s, %(mtime)s, './fqEz5LeZnT6');")
-        update = "UPDATE entities SET source='system' WHERE eid=%(eid)s;"
-        cursor.execute("SELECT eid,type,source,extid,mtime FROM entities WHERE source!='system'")
-        for eid, type, source, extid, mtime in cursor.fetchall():
-            if type != 'EUser':
-                print "don't know what to do with entity type", type
-                continue
-            if source != 'ldapuser':
-                print "don't know what to do with source type", source
-                continue
-            ldapinfos = dict(x.strip().split('=') for x in extid.split(','))
-            login = ldapinfos['uid']
-            firstname = ldapinfos['uid'][0].upper()
-            surname = ldapinfos['uid'][1:].capitalize()
-            if login != 'jcuissinat':
-                args = dict(eid=eid, type=type, source=source, login=login,
-                            firstname=firstname, surname=surname, mtime=mtime)
-                print args
-                cursor.execute(insert, args)
-                cursor.execute(update, args)
-
-        cnx.commit()
-        cnx.close()
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D070-modules-cbw-api.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,1961 @@
+.. -*- coding: utf-8 -*-
+
+============
+CubicWeb API
+============
+
+:mod:`cubicweb.hercule`
+=======================
+
+.. automodule:: cubicweb.hercule
+   :members:
+
+:mod:`cubicweb.cwctl`
+=====================
+
+.. automodule:: cubicweb.cwctl
+   :members:
+
+:mod:`cubicweb.schema`
+======================
+
+.. automodule:: cubicweb.schema
+   :members:
+
+:mod:`cubicweb.cwconfig`
+========================
+
+.. automodule:: cubicweb.cwconfig
+   :members:
+
+:mod:`cubicweb.schemaviewer`
+============================
+
+.. automodule:: cubicweb.schemaviewer
+   :members:
+
+:mod:`cubicweb._exceptions`
+===========================
+
+.. automodule:: cubicweb._exceptions
+   :members:
+
+:mod:`cubicweb.dbapi`
+=====================
+
+.. automodule:: cubicweb.dbapi
+   :members:
+
+:mod:`cubicweb.toolsutils`
+==========================
+
+.. automodule:: cubicweb.toolsutils
+   :members:
+
+:mod:`cubicweb.cwvreg`
+======================
+
+.. automodule:: cubicweb.cwvreg
+   :members:
+
+:mod:`cubicweb.md5crypt`
+========================
+
+.. automodule:: cubicweb.md5crypt
+   :members:
+
+:mod:`cubicweb.rset`
+====================
+
+.. automodule:: cubicweb.rset
+   :members:
+
+:mod:`cubicweb`
+===============
+
+.. automodule:: cubicweb
+   :members:
+
+:mod:`cubicweb.setup`
+=====================
+
+.. automodule:: cubicweb.setup
+   :members:
+
+:mod:`cubicweb.gettext`
+=======================
+
+.. automodule:: cubicweb.gettext
+   :members:
+
+:mod:`cubicweb.interfaces`
+==========================
+
+.. automodule:: cubicweb.interfaces
+   :members:
+
+:mod:`cubicweb.vregistry`
+=========================
+
+.. automodule:: cubicweb.vregistry
+   :members:
+
+:mod:`cubicweb.web.httpcache`
+=============================
+
+.. automodule:: cubicweb.web.httpcache
+   :members:
+
+:mod:`cubicweb.web.webconfig`
+=============================
+
+.. automodule:: cubicweb.web.webconfig
+   :members:
+
+:mod:`cubicweb.web.request`
+===========================
+
+.. automodule:: cubicweb.web.request
+   :members:
+
+:mod:`cubicweb.web._exceptions`
+===============================
+
+.. automodule:: cubicweb.web._exceptions
+   :members:
+
+:mod:`cubicweb.web.webctl`
+==========================
+
+.. automodule:: cubicweb.web.webctl
+   :members:
+
+:mod:`cubicweb.web.application`
+===============================
+
+.. automodule:: cubicweb.web.application
+   :members:
+
+:mod:`cubicweb.web.controller`
+==============================
+
+.. automodule:: cubicweb.web.controller
+   :members:
+
+:mod:`cubicweb.web.widgets`
+===========================
+
+.. automodule:: cubicweb.web.widgets
+   :members:
+
+:mod:`cubicweb.web.htmlwidgets`
+===============================
+
+.. automodule:: cubicweb.web.htmlwidgets
+   :members:
+
+:mod:`cubicweb.web`
+===================
+
+.. automodule:: cubicweb.web
+   :members:
+
+:mod:`cubicweb.web.form`
+========================
+
+.. automodule:: cubicweb.web.form
+   :members:
+
+:mod:`cubicweb.web.box`
+=======================
+
+.. automodule:: cubicweb.web.box
+   :members:
+
+:mod:`cubicweb.web.component`
+=============================
+
+.. automodule:: cubicweb.web.component
+   :members:
+
+:mod:`cubicweb.web.action`
+==========================
+
+.. automodule:: cubicweb.web.action
+   :members:
+
+:mod:`cubicweb.web.facet`
+=========================
+
+.. automodule:: cubicweb.web.facet
+   :members:
+
+:mod:`cubicweb.web.views.plots`
+===============================
+
+.. automodule:: cubicweb.web.views.plots
+   :members:
+
+:mod:`cubicweb.web.views.error`
+===============================
+
+.. automodule:: cubicweb.web.views.error
+   :members:
+
+:mod:`cubicweb.web.views.magicsearch`
+=====================================
+
+.. automodule:: cubicweb.web.views.magicsearch
+   :members:
+
+:mod:`cubicweb.web.views.basetemplates`
+=======================================
+
+.. automodule:: cubicweb.web.views.basetemplates
+   :members:
+
+:mod:`cubicweb.web.views.idownloadable`
+=======================================
+
+.. automodule:: cubicweb.web.views.idownloadable
+   :members:
+
+:mod:`cubicweb.web.views.ajaxedit`
+==================================
+
+.. automodule:: cubicweb.web.views.ajaxedit
+   :members:
+
+:mod:`cubicweb.web.views.wfentities`
+====================================
+
+.. automodule:: cubicweb.web.views.wfentities
+   :members:
+
+:mod:`cubicweb.web.views.navigation`
+====================================
+
+.. automodule:: cubicweb.web.views.navigation
+   :members:
+
+:mod:`cubicweb.web.views.schemaentities`
+========================================
+
+.. automodule:: cubicweb.web.views.schemaentities
+   :members:
+
+:mod:`cubicweb.web.views.treeview`
+==================================
+
+.. automodule:: cubicweb.web.views.treeview
+   :members:
+
+:mod:`cubicweb.web.views.startup`
+=================================
+
+.. automodule:: cubicweb.web.views.startup
+   :members:
+
+:mod:`cubicweb.web.views.iprogress`
+===================================
+
+.. automodule:: cubicweb.web.views.iprogress
+   :members:
+
+:mod:`cubicweb.web.views.euser`
+===============================
+
+.. automodule:: cubicweb.web.views.euser
+   :members:
+
+:mod:`cubicweb.web.views.facets`
+================================
+
+.. automodule:: cubicweb.web.views.facets
+   :members:
+
+:mod:`cubicweb.web.views.emailaddress`
+======================================
+
+.. automodule:: cubicweb.web.views.emailaddress
+   :members:
+
+:mod:`cubicweb.web.views.sessions`
+==================================
+
+.. automodule:: cubicweb.web.views.sessions
+   :members:
+
+:mod:`cubicweb.web.views.timetable`
+===================================
+
+.. automodule:: cubicweb.web.views.timetable
+   :members:
+
+:mod:`cubicweb.web.views.timeline`
+==================================
+
+.. automodule:: cubicweb.web.views.timeline
+   :members:
+
+:mod:`cubicweb.web.views.baseviews`
+===================================
+
+.. automodule:: cubicweb.web.views.baseviews
+   :members:
+
+:mod:`cubicweb.web.views.boxes`
+===============================
+
+.. automodule:: cubicweb.web.views.boxes
+   :members:
+
+:mod:`cubicweb.web.views.old_calendar`
+======================================
+
+.. automodule:: cubicweb.web.views.old_calendar
+   :members:
+
+:mod:`cubicweb.web.views.card`
+==============================
+
+.. automodule:: cubicweb.web.views.card
+   :members:
+
+:mod:`cubicweb.web.views.ibreadcrumbs`
+======================================
+
+.. automodule:: cubicweb.web.views.ibreadcrumbs
+   :members:
+
+:mod:`cubicweb.web.views.basecontrollers`
+=========================================
+
+.. automodule:: cubicweb.web.views.basecontrollers
+   :members:
+
+:mod:`cubicweb.web.views.embedding`
+===================================
+
+.. automodule:: cubicweb.web.views.embedding
+   :members:
+
+:mod:`cubicweb.web.views.actions`
+=================================
+
+.. automodule:: cubicweb.web.views.actions
+   :members:
+
+:mod:`cubicweb.web.views.editcontroller`
+========================================
+
+.. automodule:: cubicweb.web.views.editcontroller
+   :members:
+
+:mod:`cubicweb.web.views.debug`
+===============================
+
+.. automodule:: cubicweb.web.views.debug
+   :members:
+
+:mod:`cubicweb.web.views.urlpublishing`
+=======================================
+
+.. automodule:: cubicweb.web.views.urlpublishing
+   :members:
+
+:mod:`cubicweb.web.views.baseforms`
+===================================
+
+.. automodule:: cubicweb.web.views.baseforms
+   :members:
+
+:mod:`cubicweb.web.views.urlrewrite`
+====================================
+
+.. automodule:: cubicweb.web.views.urlrewrite
+   :members:
+
+:mod:`cubicweb.web.views.massmailing`
+=====================================
+
+.. automodule:: cubicweb.web.views.massmailing
+   :members:
+
+:mod:`cubicweb.web.views`
+=========================
+
+.. automodule:: cubicweb.web.views
+   :members:
+
+:mod:`cubicweb.web.views.eproperties`
+=====================================
+
+.. automodule:: cubicweb.web.views.eproperties
+   :members:
+
+:mod:`cubicweb.web.views.tabs`
+==============================
+
+.. automodule:: cubicweb.web.views.tabs
+   :members:
+
+:mod:`cubicweb.web.views.vcard`
+===============================
+
+.. automodule:: cubicweb.web.views.vcard
+   :members:
+
+:mod:`cubicweb.web.views.wdoc`
+==============================
+
+.. automodule:: cubicweb.web.views.wdoc
+   :members:
+
+:mod:`cubicweb.web.views.authentication`
+========================================
+
+.. automodule:: cubicweb.web.views.authentication
+   :members:
+
+:mod:`cubicweb.web.views.tableview`
+===================================
+
+.. automodule:: cubicweb.web.views.tableview
+   :members:
+
+:mod:`cubicweb.web.views.management`
+====================================
+
+.. automodule:: cubicweb.web.views.management
+   :members:
+
+:mod:`cubicweb.web.views.igeocodable`
+=====================================
+
+.. automodule:: cubicweb.web.views.igeocodable
+   :members:
+
+:mod:`cubicweb.web.views.xbel`
+==============================
+
+.. automodule:: cubicweb.web.views.xbel
+   :members:
+
+:mod:`cubicweb.web.views.bookmark`
+==================================
+
+.. automodule:: cubicweb.web.views.bookmark
+   :members:
+
+:mod:`cubicweb.web.views.apacherewrite`
+=======================================
+
+.. automodule:: cubicweb.web.views.apacherewrite
+   :members:
+
+:mod:`cubicweb.web.views.dynimages`
+===================================
+
+.. automodule:: cubicweb.web.views.dynimages
+   :members:
+
+:mod:`cubicweb.web.views.searchrestriction`
+===========================================
+
+.. automodule:: cubicweb.web.views.searchrestriction
+   :members:
+
+:mod:`cubicweb.web.views.basecomponents`
+========================================
+
+.. automodule:: cubicweb.web.views.basecomponents
+   :members:
+
+:mod:`cubicweb.web.views.calendar`
+==================================
+
+.. automodule:: cubicweb.web.views.calendar
+   :members:
+
+:mod:`cubicweb.sobjects.supervising`
+====================================
+
+.. automodule:: cubicweb.sobjects.supervising
+   :members:
+
+:mod:`cubicweb.sobjects.hooks`
+==============================
+
+.. automodule:: cubicweb.sobjects.hooks
+   :members:
+
+:mod:`cubicweb.sobjects.email`
+==============================
+
+.. automodule:: cubicweb.sobjects.email
+   :members:
+
+:mod:`cubicweb.sobjects`
+========================
+
+.. automodule:: cubicweb.sobjects
+   :members:
+
+:mod:`cubicweb.sobjects.notification`
+=====================================
+
+.. automodule:: cubicweb.sobjects.notification
+   :members:
+
+:mod:`cubicweb.wsgi.request`
+============================
+
+.. automodule:: cubicweb.wsgi.request
+   :members:
+
+:mod:`cubicweb.wsgi`
+====================
+
+.. automodule:: cubicweb.wsgi
+   :members:
+
+:mod:`cubicweb.wsgi.handler`
+============================
+
+.. automodule:: cubicweb.wsgi.handler
+   :members:
+
+:mod:`cubicweb.etwist.server`
+=============================
+
+.. automodule:: cubicweb.etwist.server
+   :members:
+
+:mod:`cubicweb.etwist.request`
+==============================
+
+.. automodule:: cubicweb.etwist.request
+   :members:
+
+:mod:`cubicweb.etwist.twconfig`
+===============================
+
+.. automodule:: cubicweb.etwist.twconfig
+   :members:
+
+:mod:`cubicweb.etwist`
+======================
+
+.. automodule:: cubicweb.etwist
+   :members:
+
+:mod:`cubicweb.etwist.twctl`
+============================
+
+.. automodule:: cubicweb.etwist.twctl
+   :members:
+
+:mod:`cubicweb.goa.goaconfig`
+=============================
+
+.. automodule:: cubicweb.goa.goaconfig
+   :members:
+
+:mod:`cubicweb.goa.rqlinterpreter`
+==================================
+
+.. automodule:: cubicweb.goa.rqlinterpreter
+   :members:
+
+:mod:`cubicweb.goa.dbmyams`
+===========================
+
+.. automodule:: cubicweb.goa.dbmyams
+   :members:
+
+:mod:`cubicweb.goa.db`
+======================
+
+.. automodule:: cubicweb.goa.db
+   :members:
+
+:mod:`cubicweb.goa.goactl`
+==========================
+
+.. automodule:: cubicweb.goa.goactl
+   :members:
+
+:mod:`cubicweb.goa.goavreg`
+===========================
+
+.. automodule:: cubicweb.goa.goavreg
+   :members:
+
+:mod:`cubicweb.goa`
+===================
+
+.. automodule:: cubicweb.goa
+   :members:
+
+:mod:`cubicweb.goa.gaesource`
+=============================
+
+.. automodule:: cubicweb.goa.gaesource
+   :members:
+
+:mod:`cubicweb.goa.dbinit`
+==========================
+
+.. automodule:: cubicweb.goa.dbinit
+   :members:
+
+:mod:`cubicweb.goa.testlib`
+===========================
+
+.. automodule:: cubicweb.goa.testlib
+   :members:
+
+:mod:`cubicweb.goa.appobjects.dbmgmt`
+=====================================
+
+.. automodule:: cubicweb.goa.appobjects.dbmgmt
+   :members:
+
+:mod:`cubicweb.goa.appobjects.gauthservice`
+===========================================
+
+.. automodule:: cubicweb.goa.appobjects.gauthservice
+   :members:
+
+:mod:`cubicweb.goa.appobjects.sessions`
+=======================================
+
+.. automodule:: cubicweb.goa.appobjects.sessions
+   :members:
+
+:mod:`cubicweb.goa.appobjects`
+==============================
+
+.. automodule:: cubicweb.goa.appobjects
+   :members:
+
+:mod:`cubicweb.goa.appobjects.components`
+=========================================
+
+.. automodule:: cubicweb.goa.appobjects.components
+   :members:
+
+:mod:`cubicweb.goa.tools.laxctl`
+================================
+
+.. automodule:: cubicweb.goa.tools.laxctl
+   :members:
+
+:mod:`cubicweb.goa.tools.generate_schema_img`
+=============================================
+
+.. automodule:: cubicweb.goa.tools.generate_schema_img
+   :members:
+
+:mod:`cubicweb.goa.tools`
+=========================
+
+.. automodule:: cubicweb.goa.tools
+   :members:
+
+:mod:`cubicweb.goa.tools.i18n`
+==============================
+
+.. automodule:: cubicweb.goa.tools.i18n
+   :members:
+
+:mod:`cubicweb.goa.overrides.mttransforms`
+==========================================
+
+.. automodule:: cubicweb.goa.overrides.mttransforms
+   :members:
+
+:mod:`cubicweb.goa.overrides.rqlannotation`
+===========================================
+
+.. automodule:: cubicweb.goa.overrides.rqlannotation
+   :members:
+
+:mod:`cubicweb.goa.overrides.toolsutils`
+========================================
+
+.. automodule:: cubicweb.goa.overrides.toolsutils
+   :members:
+
+:mod:`cubicweb.goa.overrides`
+=============================
+
+.. automodule:: cubicweb.goa.overrides
+   :members:
+
+:mod:`cubicweb.goa.overrides.server__init__`
+============================================
+
+.. automodule:: cubicweb.goa.overrides.server__init__
+   :members:
+
+:mod:`cubicweb.goa.overrides.server_utils`
+==========================================
+
+.. automodule:: cubicweb.goa.overrides.server_utils
+   :members:
+
+:mod:`cubicweb.common.mttransforms`
+===================================
+
+.. automodule:: cubicweb.common.mttransforms
+   :members:
+
+:mod:`cubicweb.common.utils`
+============================
+
+.. automodule:: cubicweb.common.utils
+   :members:
+
+:mod:`cubicweb.common.schema`
+=============================
+
+.. automodule:: cubicweb.common.schema
+   :members:
+
+:mod:`cubicweb.common.tal`
+==========================
+
+.. automodule:: cubicweb.common.tal
+   :members:
+
+:mod:`cubicweb.common.appobject`
+================================
+
+.. automodule:: cubicweb.common.appobject
+   :members:
+
+:mod:`cubicweb.common.migration`
+================================
+
+.. automodule:: cubicweb.common.migration
+   :members:
+
+:mod:`cubicweb.common.rest`
+===========================
+
+.. automodule:: cubicweb.common.rest
+   :members:
+
+:mod:`cubicweb.common.html4zope`
+================================
+
+.. automodule:: cubicweb.common.html4zope
+   :members:
+
+:mod:`cubicweb.common.view`
+===========================
+
+.. automodule:: cubicweb.common.view
+   :members:
+
+:mod:`cubicweb.common.selectors`
+================================
+
+.. automodule:: cubicweb.common.selectors
+   :members:
+
+:mod:`cubicweb.common.entity`
+=============================
+
+.. automodule:: cubicweb.common.entity
+   :members:
+
+:mod:`cubicweb.common.mail`
+===========================
+
+.. automodule:: cubicweb.common.mail
+   :members:
+
+:mod:`cubicweb.common.mixins`
+=============================
+
+.. automodule:: cubicweb.common.mixins
+   :members:
+
+:mod:`cubicweb.common`
+======================
+
+.. automodule:: cubicweb.common
+   :members:
+
+:mod:`cubicweb.common.uilib`
+============================
+
+.. automodule:: cubicweb.common.uilib
+   :members:
+
+:mod:`cubicweb.common.registerers`
+==================================
+
+.. automodule:: cubicweb.common.registerers
+   :members:
+
+:mod:`cubicweb.common.i18n`
+===========================
+
+.. automodule:: cubicweb.common.i18n
+   :members:
+
+:mod:`cubicweb.entities.schemaobjs`
+===================================
+
+.. automodule:: cubicweb.entities.schemaobjs
+   :members:
+
+:mod:`cubicweb.entities.wfobjs`
+===============================
+
+.. automodule:: cubicweb.entities.wfobjs
+   :members:
+
+:mod:`cubicweb.entities`
+========================
+
+.. automodule:: cubicweb.entities
+   :members:
+
+:mod:`cubicweb.entities.authobjs`
+=================================
+
+.. automodule:: cubicweb.entities.authobjs
+   :members:
+
+:mod:`cubicweb.entities.lib`
+============================
+
+.. automodule:: cubicweb.entities.lib
+   :members:
+
+:mod:`cubicweb.server.server`
+=============================
+
+.. automodule:: cubicweb.server.server
+   :members:
+
+:mod:`cubicweb.server.utils`
+============================
+
+.. automodule:: cubicweb.server.utils
+   :members:
+
+:mod:`cubicweb.server.checkintegrity`
+=====================================
+
+.. automodule:: cubicweb.server.checkintegrity
+   :members:
+
+:mod:`cubicweb.server.rqlrewrite`
+=================================
+
+.. automodule:: cubicweb.server.rqlrewrite
+   :members:
+
+:mod:`cubicweb.server.rqlannotation`
+====================================
+
+.. automodule:: cubicweb.server.rqlannotation
+   :members:
+
+:mod:`cubicweb.server.hooks`
+============================
+
+.. automodule:: cubicweb.server.hooks
+   :members:
+
+:mod:`cubicweb.server.hooksmanager`
+===================================
+
+.. automodule:: cubicweb.server.hooksmanager
+   :members:
+
+:mod:`cubicweb.server.securityhooks`
+====================================
+
+.. automodule:: cubicweb.server.securityhooks
+   :members:
+
+:mod:`cubicweb.server.schemahooks`
+==================================
+
+.. automodule:: cubicweb.server.schemahooks
+   :members:
+
+:mod:`cubicweb.server.session`
+==============================
+
+.. automodule:: cubicweb.server.session
+   :members:
+
+:mod:`cubicweb.server.serverctl`
+================================
+
+.. automodule:: cubicweb.server.serverctl
+   :members:
+
+:mod:`cubicweb.server.serverconfig`
+===================================
+
+.. automodule:: cubicweb.server.serverconfig
+   :members:
+
+:mod:`cubicweb.server.pool`
+===========================
+
+.. automodule:: cubicweb.server.pool
+   :members:
+
+:mod:`cubicweb.server.mssteps`
+==============================
+
+.. automodule:: cubicweb.server.mssteps
+   :members:
+
+:mod:`cubicweb.server.hookhelper`
+=================================
+
+.. automodule:: cubicweb.server.hookhelper
+   :members:
+
+:mod:`cubicweb.server`
+======================
+
+.. automodule:: cubicweb.server
+   :members:
+
+:mod:`cubicweb.server.sqlutils`
+===============================
+
+.. automodule:: cubicweb.server.sqlutils
+   :members:
+
+:mod:`cubicweb.server.schemaserial`
+===================================
+
+.. automodule:: cubicweb.server.schemaserial
+   :members:
+
+:mod:`cubicweb.server.repository`
+=================================
+
+.. automodule:: cubicweb.server.repository
+   :members:
+
+:mod:`cubicweb.server.ssplanner`
+================================
+
+.. automodule:: cubicweb.server.ssplanner
+   :members:
+
+:mod:`cubicweb.server.msplanner`
+================================
+
+.. automodule:: cubicweb.server.msplanner
+   :members:
+
+:mod:`cubicweb.server.querier`
+==============================
+
+.. automodule:: cubicweb.server.querier
+   :members:
+
+:mod:`cubicweb.server.migractions`
+==================================
+
+.. automodule:: cubicweb.server.migractions
+   :members:
+
+:mod:`cubicweb.server.sources.rql2sql`
+======================================
+
+.. automodule:: cubicweb.server.sources.rql2sql
+   :members:
+
+:mod:`cubicweb.server.sources.ldapuser`
+=======================================
+
+.. automodule:: cubicweb.server.sources.ldapuser
+   :members:
+
+:mod:`cubicweb.server.sources`
+==============================
+
+.. automodule:: cubicweb.server.sources
+   :members:
+
+:mod:`cubicweb.server.sources.pyrorql`
+======================================
+
+.. automodule:: cubicweb.server.sources.pyrorql
+   :members:
+
+:mod:`cubicweb.server.sources.native`
+=====================================
+
+.. automodule:: cubicweb.server.sources.native
+   :members:
+
+:mod:`cubicweb.server.sources.extlite`
+======================================
+
+.. automodule:: cubicweb.server.sources.extlite
+   :members:
+
+:mod:`cubicweb.devtools.devctl`
+===============================
+
+.. automodule:: cubicweb.devtools.devctl
+   :members:
+
+:mod:`cubicweb.devtools.pkginfo`
+================================
+
+.. automodule:: cubicweb.devtools.pkginfo
+   :members:
+
+:mod:`cubicweb.devtools.migrtest`
+=================================
+
+.. automodule:: cubicweb.devtools.migrtest
+   :members:
+
+:mod:`cubicweb.devtools.htmlparser`
+===================================
+
+.. automodule:: cubicweb.devtools.htmlparser
+   :members:
+
+:mod:`cubicweb.devtools`
+========================
+
+.. automodule:: cubicweb.devtools
+   :members:
+
+:mod:`cubicweb.devtools.fill`
+=============================
+
+.. automodule:: cubicweb.devtools.fill
+   :members:
+
+:mod:`cubicweb.devtools._apptest`
+=================================
+
+.. automodule:: cubicweb.devtools._apptest
+   :members:
+
+:mod:`cubicweb.devtools.stresstester`
+=====================================
+
+.. automodule:: cubicweb.devtools.stresstester
+   :members:
+
+:mod:`cubicweb.devtools.fake`
+=============================
+
+.. automodule:: cubicweb.devtools.fake
+   :members:
+
+:mod:`cubicweb.devtools.apptest`
+================================
+
+.. automodule:: cubicweb.devtools.apptest
+   :members:
+
+:mod:`cubicweb.devtools.livetest`
+=================================
+
+.. automodule:: cubicweb.devtools.livetest
+   :members:
+
+:mod:`cubicweb.devtools.testlib`
+================================
+
+.. automodule:: cubicweb.devtools.testlib
+   :members:
+
+:mod:`cubicweb.devtools.repotest`
+=================================
+
+.. automodule:: cubicweb.devtools.repotest
+   :members:
+
+:mod:`cubicweb.devtools.cwtwill`
+================================
+
+.. automodule:: cubicweb.devtools.cwtwill
+   :members:
+
+:mod:`cubicweb.misc.cwdesklets.rqlsensor`
+=========================================
+
+.. automodule:: cubicweb.misc.cwdesklets.rqlsensor
+   :members:
+
+:mod:`cubicweb.embedded.mx`
+===========================
+
+.. automodule:: cubicweb.embedded.mx
+   :members:
+
+:mod:`cubicweb.embedded.mx.DateTime.mxDateTime_python`
+======================================================
+
+.. automodule:: cubicweb.embedded.mx.DateTime.mxDateTime_python
+   :members:
+
+:mod:`cubicweb.embedded.mx.DateTime.ARPA`
+=========================================
+
+.. automodule:: cubicweb.embedded.mx.DateTime.ARPA
+   :members:
+
+:mod:`cubicweb.embedded.mx.DateTime.ISO`
+========================================
+
+.. automodule:: cubicweb.embedded.mx.DateTime.ISO
+   :members:
+
+:mod:`cubicweb.embedded.mx.DateTime.Parser`
+===========================================
+
+.. automodule:: cubicweb.embedded.mx.DateTime.Parser
+   :members:
+
+:mod:`cubicweb.embedded.mx.DateTime`
+====================================
+
+.. automodule:: cubicweb.embedded.mx.DateTime
+   :members:
+
+:mod:`cubicweb.embedded.mx.DateTime.Timezone`
+=============================================
+
+.. automodule:: cubicweb.embedded.mx.DateTime.Timezone
+   :members:
+
+:mod:`cubicweb.embedded.mx.DateTime.DateTime`
+=============================================
+
+.. automodule:: cubicweb.embedded.mx.DateTime.DateTime
+   :members:
+
+:mod:`indexer`
+==============
+
+.. automodule:: indexer
+   :members:
+
+:mod:`indexer.indexable_objects`
+================================
+
+.. automodule:: indexer.indexable_objects
+   :members:
+
+:mod:`indexer.search`
+=====================
+
+.. automodule:: indexer.search
+   :members:
+
+:mod:`indexer.query_objects`
+============================
+
+.. automodule:: indexer.query_objects
+   :members:
+
+:mod:`indexer._exceptions`
+==========================
+
+.. automodule:: indexer._exceptions
+   :members:
+
+:mod:`indexer.setup`
+====================
+
+.. automodule:: indexer.setup
+   :members:
+
+:mod:`indexer.query`
+====================
+
+.. automodule:: indexer.query
+   :members:
+
+:mod:`logilab`
+==============
+
+.. automodule:: logilab
+   :members:
+
+:mod:`logilab.constraint.propagation`
+=====================================
+
+.. automodule:: logilab.constraint.propagation
+   :members:
+
+:mod:`logilab.constraint.psyco_wrapper`
+=======================================
+
+.. automodule:: logilab.constraint.psyco_wrapper
+   :members:
+
+:mod:`logilab.constraint.fd`
+============================
+
+.. automodule:: logilab.constraint.fd
+   :members:
+
+:mod:`logilab.constraint.fi`
+============================
+
+.. automodule:: logilab.constraint.fi
+   :members:
+
+:mod:`logilab.constraint`
+=========================
+
+.. automodule:: logilab.constraint
+   :members:
+
+:mod:`logilab.constraint.setup`
+===============================
+
+.. automodule:: logilab.constraint.setup
+   :members:
+
+:mod:`logilab.constraint.interfaces`
+====================================
+
+.. automodule:: logilab.constraint.interfaces
+   :members:
+
+:mod:`logilab.constraint.distributors`
+======================================
+
+.. automodule:: logilab.constraint.distributors
+   :members:
+
+:mod:`logilab.common.clcommands`
+================================
+
+.. automodule:: logilab.common.clcommands
+   :members:
+
+:mod:`logilab.common.table`
+===========================
+
+.. automodule:: logilab.common.table
+   :members:
+
+:mod:`logilab.common.interface`
+===============================
+
+.. automodule:: logilab.common.interface
+   :members:
+
+:mod:`logilab.common.logger`
+============================
+
+.. automodule:: logilab.common.logger
+   :members:
+
+:mod:`logilab.common.cli`
+=========================
+
+.. automodule:: logilab.common.cli
+   :members:
+
+:mod:`logilab.common.xmlrpcutils`
+=================================
+
+.. automodule:: logilab.common.xmlrpcutils
+   :members:
+
+:mod:`logilab.common.corbautils`
+================================
+
+.. automodule:: logilab.common.corbautils
+   :members:
+
+:mod:`logilab.common.cache`
+===========================
+
+.. automodule:: logilab.common.cache
+   :members:
+
+:mod:`logilab.common.astutils`
+==============================
+
+.. automodule:: logilab.common.astutils
+   :members:
+
+:mod:`logilab.common.daemon`
+============================
+
+.. automodule:: logilab.common.daemon
+   :members:
+
+:mod:`logilab.common.tree`
+==========================
+
+.. automodule:: logilab.common.tree
+   :members:
+
+:mod:`logilab.common.textutils`
+===============================
+
+.. automodule:: logilab.common.textutils
+   :members:
+
+:mod:`logilab.common.modutils`
+==============================
+
+.. automodule:: logilab.common.modutils
+   :members:
+
+:mod:`logilab.common.fileutils`
+===============================
+
+.. automodule:: logilab.common.fileutils
+   :members:
+
+:mod:`logilab.common.patricia`
+==============================
+
+.. automodule:: logilab.common.patricia
+   :members:
+
+:mod:`logilab.common.date`
+==========================
+
+.. automodule:: logilab.common.date
+   :members:
+
+:mod:`logilab.common.optparser`
+===============================
+
+.. automodule:: logilab.common.optparser
+   :members:
+
+:mod:`logilab.common.twisted_distutils`
+=======================================
+
+.. automodule:: logilab.common.twisted_distutils
+   :members:
+
+:mod:`logilab.common.decorators`
+================================
+
+.. automodule:: logilab.common.decorators
+   :members:
+
+:mod:`logilab.common.db`
+========================
+
+.. automodule:: logilab.common.db
+   :members:
+
+:mod:`logilab.common.deprecation`
+=================================
+
+.. automodule:: logilab.common.deprecation
+   :members:
+
+:mod:`logilab.common.tasksqueue`
+================================
+
+.. automodule:: logilab.common.tasksqueue
+   :members:
+
+:mod:`logilab.common.changelog`
+===============================
+
+.. automodule:: logilab.common.changelog
+   :members:
+
+:mod:`logilab.common.shellutils`
+================================
+
+.. automodule:: logilab.common.shellutils
+   :members:
+
+:mod:`logilab.common.sqlgen`
+============================
+
+.. automodule:: logilab.common.sqlgen
+   :members:
+
+:mod:`logilab.common.optik_ext`
+===============================
+
+.. automodule:: logilab.common.optik_ext
+   :members:
+
+:mod:`logilab.common.configuration`
+===================================
+
+.. automodule:: logilab.common.configuration
+   :members:
+
+:mod:`logilab.common.visitor`
+=============================
+
+.. automodule:: logilab.common.visitor
+   :members:
+
+:mod:`logilab.common.pytest`
+============================
+
+.. automodule:: logilab.common.pytest
+   :members:
+
+:mod:`logilab.common`
+=====================
+
+.. automodule:: logilab.common
+   :members:
+
+:mod:`logilab.common.setup`
+===========================
+
+.. automodule:: logilab.common.setup
+   :members:
+
+:mod:`logilab.common.logservice`
+================================
+
+.. automodule:: logilab.common.logservice
+   :members:
+
+:mod:`logilab.common.debugger`
+==============================
+
+.. automodule:: logilab.common.debugger
+   :members:
+
+:mod:`logilab.common.html`
+==========================
+
+.. automodule:: logilab.common.html
+   :members:
+
+:mod:`logilab.common.vcgutils`
+==============================
+
+.. automodule:: logilab.common.vcgutils
+   :members:
+
+:mod:`logilab.common.compat`
+============================
+
+.. automodule:: logilab.common.compat
+   :members:
+
+:mod:`logilab.common.logging_ext`
+=================================
+
+.. automodule:: logilab.common.logging_ext
+   :members:
+
+:mod:`logilab.common.umessage`
+==============================
+
+.. automodule:: logilab.common.umessage
+   :members:
+
+:mod:`logilab.common.proc`
+==========================
+
+.. automodule:: logilab.common.proc
+   :members:
+
+:mod:`logilab.common.monclient`
+===============================
+
+.. automodule:: logilab.common.monclient
+   :members:
+
+:mod:`logilab.common.bind`
+==========================
+
+.. automodule:: logilab.common.bind
+   :members:
+
+:mod:`logilab.common.graph`
+===========================
+
+.. automodule:: logilab.common.graph
+   :members:
+
+:mod:`logilab.common.testlib`
+=============================
+
+.. automodule:: logilab.common.testlib
+   :members:
+
+:mod:`logilab.common.contexts`
+==============================
+
+.. automodule:: logilab.common.contexts
+   :members:
+
+:mod:`logilab.common.adbh`
+==========================
+
+.. automodule:: logilab.common.adbh
+   :members:
+
+:mod:`logilab.common.pdf_ext`
+=============================
+
+.. automodule:: logilab.common.pdf_ext
+   :members:
+
+:mod:`logilab.common.monserver`
+===============================
+
+.. automodule:: logilab.common.monserver
+   :members:
+
+:mod:`logilab.common.ureports.nodes`
+====================================
+
+.. automodule:: logilab.common.ureports.nodes
+   :members:
+
+:mod:`logilab.common.ureports`
+==============================
+
+.. automodule:: logilab.common.ureports
+   :members:
+
+:mod:`logilab.common.ureports.html_writer`
+==========================================
+
+.. automodule:: logilab.common.ureports.html_writer
+   :members:
+
+:mod:`logilab.common.ureports.text_writer`
+==========================================
+
+.. automodule:: logilab.common.ureports.text_writer
+   :members:
+
+:mod:`logilab.common.ureports.docbook_writer`
+=============================================
+
+.. automodule:: logilab.common.ureports.docbook_writer
+   :members:
+
+:mod:`logilab.mtconverter.engine`
+=================================
+
+.. automodule:: logilab.mtconverter.engine
+   :members:
+
+:mod:`logilab.mtconverter.transform`
+====================================
+
+.. automodule:: logilab.mtconverter.transform
+   :members:
+
+:mod:`logilab.mtconverter`
+==========================
+
+.. automodule:: logilab.mtconverter
+   :members:
+
+:mod:`logilab.mtconverter.setup`
+================================
+
+.. automodule:: logilab.mtconverter.setup
+   :members:
+
+:mod:`logilab.mtconverter.transforms.html2text`
+===============================================
+
+.. automodule:: logilab.mtconverter.transforms.html2text
+   :members:
+
+:mod:`logilab.mtconverter.transforms.cmdtransforms`
+===================================================
+
+.. automodule:: logilab.mtconverter.transforms.cmdtransforms
+   :members:
+
+:mod:`logilab.mtconverter.transforms.python`
+============================================
+
+.. automodule:: logilab.mtconverter.transforms.python
+   :members:
+
+:mod:`logilab.mtconverter.transforms.pygmentstransforms`
+========================================================
+
+.. automodule:: logilab.mtconverter.transforms.pygmentstransforms
+   :members:
+
+:mod:`logilab.mtconverter.transforms`
+=====================================
+
+.. automodule:: logilab.mtconverter.transforms
+   :members:
+
+:mod:`logilab.mtconverter.transforms.piltransforms`
+===================================================
+
+.. automodule:: logilab.mtconverter.transforms.piltransforms
+   :members:
+
+:mod:`logilab.devtools.cvstatus`
+================================
+
+.. automodule:: logilab.devtools.cvstatus
+   :members:
+
+:mod:`logilab.devtools.changelog`
+=================================
+
+.. automodule:: logilab.devtools.changelog
+   :members:
+
+:mod:`logilab.devtools`
+=======================
+
+.. automodule:: logilab.devtools
+   :members:
+
+:mod:`logilab.devtools.setup`
+=============================
+
+.. automodule:: logilab.devtools.setup
+   :members:
+
+:mod:`logilab.devtools.cvslog`
+==============================
+
+.. automodule:: logilab.devtools.cvslog
+   :members:
+
+:mod:`logilab.devtools.lgp.utils`
+=================================
+
+.. automodule:: logilab.devtools.lgp.utils
+   :members:
+
+:mod:`logilab.devtools.lgp.tag`
+===============================
+
+.. automodule:: logilab.devtools.lgp.tag
+   :members:
+
+:mod:`logilab.devtools.lgp.setupinfo`
+=====================================
+
+.. automodule:: logilab.devtools.lgp.setupinfo
+   :members:
+
+:mod:`logilab.devtools.lgp.changelog`
+=====================================
+
+.. automodule:: logilab.devtools.lgp.changelog
+   :members:
+
+:mod:`logilab.devtools.lgp.preparedist`
+=======================================
+
+.. automodule:: logilab.devtools.lgp.preparedist
+   :members:
+
+:mod:`logilab.devtools.lgp.build`
+=================================
+
+.. automodule:: logilab.devtools.lgp.build
+   :members:
+
+:mod:`logilab.devtools.lgp.clean`
+=================================
+
+.. automodule:: logilab.devtools.lgp.clean
+   :members:
+
+:mod:`logilab.devtools.lgp`
+===========================
+
+.. automodule:: logilab.devtools.lgp
+   :members:
+
+:mod:`logilab.devtools.lgp.setup`
+=================================
+
+.. automodule:: logilab.devtools.lgp.setup
+   :members:
+
+:mod:`logilab.devtools.lgp.check`
+=================================
+
+.. automodule:: logilab.devtools.lgp.check
+   :members:
+
+:mod:`logilab.devtools.lgp.exceptions`
+======================================
+
+.. automodule:: logilab.devtools.lgp.exceptions
+   :members:
+
+:mod:`logilab.devtools.templates`
+=================================
+
+.. automodule:: logilab.devtools.templates
+   :members:
+
+:mod:`logilab.devtools.templates.setup`
+=======================================
+
+.. automodule:: logilab.devtools.templates.setup
+   :members:
+
+:mod:`logilab.devtools.lib.coverage`
+====================================
+
+.. automodule:: logilab.devtools.lib.coverage
+   :members:
+
+:mod:`logilab.devtools.lib.manifest`
+====================================
+
+.. automodule:: logilab.devtools.lib.manifest
+   :members:
+
+:mod:`logilab.devtools.lib.pkginfo`
+===================================
+
+.. automodule:: logilab.devtools.lib.pkginfo
+   :members:
+
+:mod:`logilab.devtools.lib`
+===========================
+
+.. automodule:: logilab.devtools.lib
+   :members:
+
+:mod:`logilab.devtools.vcslib.cvsparse`
+=======================================
+
+.. automodule:: logilab.devtools.vcslib.cvsparse
+   :members:
+
+:mod:`logilab.devtools.vcslib.svn`
+==================================
+
+.. automodule:: logilab.devtools.vcslib.svn
+   :members:
+
+:mod:`logilab.devtools.vcslib.node`
+===================================
+
+.. automodule:: logilab.devtools.vcslib.node
+   :members:
+
+:mod:`logilab.devtools.vcslib`
+==============================
+
+.. automodule:: logilab.devtools.vcslib
+   :members:
+
+:mod:`logilab.devtools.vcslib.interfaces`
+=========================================
+
+.. automodule:: logilab.devtools.vcslib.interfaces
+   :members:
+
+:mod:`logilab.devtools.vcslib.cvs`
+==================================
+
+.. automodule:: logilab.devtools.vcslib.cvs
+   :members:
+
+:mod:`logilab.devtools.vcslib.hg`
+=================================
+
+.. automodule:: logilab.devtools.vcslib.hg
+   :members:
+
+:mod:`rql.nodes`
+================
+
+.. automodule:: rql.nodes
+   :members:
+
+:mod:`rql.undo`
+===============
+
+.. automodule:: rql.undo
+   :members:
+
+:mod:`rql.utils`
+================
+
+.. automodule:: rql.utils
+   :members:
+
+:mod:`rql.base`
+===============
+
+.. automodule:: rql.base
+   :members:
+
+:mod:`rql.analyze`
+==================
+
+.. automodule:: rql.analyze
+   :members:
+
+:mod:`rql._exceptions`
+======================
+
+.. automodule:: rql._exceptions
+   :members:
+
+:mod:`rql.compare`
+==================
+
+.. automodule:: rql.compare
+   :members:
+
+:mod:`rql.stmts`
+================
+
+.. automodule:: rql.stmts
+   :members:
+
+:mod:`rql.parser_main`
+======================
+
+.. automodule:: rql.parser_main
+   :members:
+
+:mod:`rql.stcheck`
+==================
+
+.. automodule:: rql.stcheck
+   :members:
+
+:mod:`rql.parser`
+=================
+
+.. automodule:: rql.parser
+   :members:
+
+:mod:`rql`
+==========
+
+.. automodule:: rql
+   :members:
+
+:mod:`rql.setup`
+================
+
+.. automodule:: rql.setup
+   :members:
+
+:mod:`rql.interfaces`
+=====================
+
+.. automodule:: rql.interfaces
+   :members:
+
+:mod:`rql.editextensions`
+=========================
+
+.. automodule:: rql.editextensions
+   :members:
+
+:mod:`rql.fol`
+==============
+
+.. automodule:: rql.fol
+   :members:
+
+:mod:`rqlgen`
+=============
+
+.. automodule:: rqlgen
+   :members:
+
+:mod:`yams.schema`
+==================
+
+.. automodule:: yams.schema
+   :members:
+
+:mod:`yams.reader`
+==================
+
+.. automodule:: yams.reader
+   :members:
+
+:mod:`yams.schema2sql`
+======================
+
+.. automodule:: yams.schema2sql
+   :members:
+
+:mod:`yams._exceptions`
+=======================
+
+.. automodule:: yams._exceptions
+   :members:
+
+:mod:`yams.sqlreader`
+=====================
+
+.. automodule:: yams.sqlreader
+   :members:
+
+:mod:`yams.schema2dot`
+======================
+
+.. automodule:: yams.schema2dot
+   :members:
+
+:mod:`yams`
+===========
+
+.. automodule:: yams
+   :members:
+
+:mod:`yams.setup`
+=================
+
+.. automodule:: yams.setup
+   :members:
+
+:mod:`yams.interfaces`
+======================
+
+.. automodule:: yams.interfaces
+   :members:
+
+:mod:`yams.buildobjs`
+=====================
+
+.. automodule:: yams.buildobjs
+   :members:
+
+:mod:`yams.constraints`
+=======================
+
+.. automodule:: yams.constraints
+   :members:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D080-mercurial.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,133 @@
+.. -*- coding: utf-8 -*-
+
+.. _MercurialPresentation:
+
+Introducing Mercurial
+=====================
+
+Introduction
+````````````
+Mercurial_ manages a distributed repository containing revisions
+trees (each revision indicates the changes required to obtain the
+next, and so on). Locally, we have a repository containing revisions
+tree, and a working directory. It is possible
+to put in its working directory, one of the versions of its local repository,
+modify and then push it in its repository. 
+It is also possible to get revisions from another repository or to export
+its own revisions from the local repository to another repository.
+
+.. _Mercurial: http://www.selenic.com/mercurial/
+
+In contrast to CVS/Subversion, we usually create a repository by
+project to manage.
+
+In a collaborative development, we usually create a central repository
+accessible to all developers of the project. These central repository is used
+as a reference. According to its needs, then everyone can have a local repository,
+that you will have to synchronize with the central repository from time to time.
+
+
+Major commands
+``````````````
+* Create a local repository::
+
+     hg clone ssh://myhost//home/src/repo
+
+* See the contents of the local repository (graphical tool in Tk)::
+
+     hgview
+
+* Add a sub-directory or file in the current directory::
+
+     hg add subdir
+
+* Move to the working directory a specific revision (or last
+  revision) from the local repository::
+
+     hg update [identifier-revision]
+     hg up [identifier-revision]
+
+* Get in its local repository, the tree of revisions contained in a
+  remote repository (this does not change the local directory)::
+
+     hg pull ssh://myhost//home/src/repo
+     hg pull -u ssh://myhost//home/src/repo # equivalent to pull + update
+
+* See what are the heads of branches of the local repository if a `pull`
+  returned a new branch::
+
+     hg heads
+
+* Submit the working directory in the local repository (and create a new
+  revision)::
+
+     hg commit
+     hg ci
+
+* Merge with the mother revision of local directory, another revision from
+  the local respository (the new revision will be then two mothers
+  revisions)::
+
+     hg merge identifier-revision
+
+* Export to a remote repository, the tree of revisions in its content
+  local respository (this does not change the local directory)::
+
+     hg push ssh://myhost//home/src/repo
+
+* See what local revisions are not in another repository::
+
+     hg outgoing ssh://myhost//home/src/repo
+
+* See what are the revisions of a repository not found locally::
+
+     hg incoming ssh://myhost//home/src/repo
+
+* See what is the revision of the local repository which has been taken out 
+  from the working directory and amended::
+
+     hg parent
+
+* See the differences between the working directory and the mother revision
+  of the local repository, possibly to submit them in the local repository::
+
+     hg diff
+     hg commit-tool
+     hg ct
+
+
+Best Practices
+``````````````
+* Remember to `hg pull -u` regularly, and particularly before
+   a `hg commit`.
+
+* Remember to `hg push` when your repository contains a version
+  relatively stable of your changes.
+
+* If a `hg pull -u` created a new branch head:
+
+   1. find its identifier with `hg head`
+   2. merge with `hg merge`
+   3. `hg ci`
+   4. `hg push`
+
+Installation of the forest extension
+````````````````````````````````````
+
+Set up the forest extension by getting a copy of the sources 
+from http://hg.akoha.org/hgforest/ and adding the following 
+lines to your ``~/.hgrc``: ::
+
+   [extensions]
+   hgext.forest=
+   # or, if forest.py is not in the hgext dir:
+   # forest=/path/to/forest.py
+
+
+More information
+````````````````
+
+For more information about Mercurial, please refer to the Mercurial project online documentation_.
+
+.. _documentation: http://www.selenic.com/mercurial/wiki/
+
--- a/doc/book/en/MERGE_ME-tut-create-app.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/MERGE_ME-tut-create-app.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -323,7 +323,7 @@
   
   _ = unicode
 
-  moderators      = add_entity('EGroup', name=u"moderators")
+  moderators      = add_entity('CWGroup', name=u"moderators")
 
   submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
   published = add_state(_('published'), 'BlogEntry')
--- a/doc/book/en/Z010-beginners.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/Z010-beginners.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -2,11 +2,10 @@
 
 .. _QuickInstall:
 
-===========================================
 Quick Installation of a `CubicWeb` instance
 ===========================================
 
-.. include:: C011-installation.en.txt
+.. include:: C010-setup.en.txt
 .. include:: Z012-create-instance.en.txt
 
 
--- a/doc/book/en/Z012-create-instance.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/Z012-create-instance.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -1,5 +1,6 @@
 .. -*- coding: utf-8 -*-
 
+===============================
 Creation of your first instance
 ===============================
 
--- a/doc/book/en/Z013-blog-less-ten-minutes.en.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/Z013-blog-less-ten-minutes.en.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -1,86 +1,26 @@
 .. -*- coding: utf-8 -*-
 
-.. BlogTenMinutes:
-
-Have a blog ready in less than ten minutes!
--------------------------------------------
-
-Installation
-~~~~~~~~~~~~
-
-You need to install the following packages::
+.. _BlogTenMinutes:
 
-    cubicweb, cubicweb-blog
-
-The package `cubicweb` is installing the command `cubicweb-ctl` that
-will allow you to create new application.
+Get a Blog running in less than ten minutes!
+--------------------------------------------
 
-The package `cubicweb-blog` is installing the blogging support for the
-`CubicWeb` framework.
+You need to install the following packages (:ref:`DebianInstallation`)::
 
-Application creation
-~~~~~~~~~~~~~~~~~~~~
+    cubicweb, cubicweb-dev, cubicweb-blog
 
 Creation and initialization of your application by running::
     
     cubicweb-ctl create blog myblog
 
-*myblog* is the name of the application you are creating.
-
-*blog* is the name of the component on which your application
-is based. 
-
-Application launch
-~~~~~~~~~~~~~~~~~~
-
 Your application is now ready to go::
 
     cubicweb-ctl start -D myblog
 
 This is it. Your blog is ready to you. Go to http://localhost:8080 and enjoy!!
 
-
-A little code snapshot from behind the scene
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The component `blog`, referred as a `cube` in the book 
-(see :ref:`TermsVocabulary` for a complete definition), defines
-a data model in ``/usr/share/cubicweb/cubes/blog/schema.py``. 
-Here is the corresponding Python code::
-
-    from cubicweb.schema import format_constraint
-
-    class Blog(EntityType):
-        title = String(maxsize=50, required=True)
-        description_format = String(meta=True, internationalizable=True, maxsize=50,
-                                    default='text/rest', constraints=[format_constraint])
-        description = String()
-        rss_url = String(maxsize=128, description=_('blog\'s rss url (useful for when using external site such as feedburner)'))
+As a developper, you'll want to know more about how to develop new
+cubes and cutomize the look of your application and this is what we
+talk about now. 
 
 
-    class BlogEntry(EntityType):
-        title = String(required=True, fulltextindexed=True, maxsize=256)
-        content_format = String(meta=True, internationalizable=True, maxsize=50,
-                                default='text/rest', constraints=[format_constraint])
-        content = String(required=True, fulltextindexed=True)
-        entry_of = SubjectRelation('Blog', cardinality='?*')
-
-Two types of entities are defined here: Blog and BlogEntry.
-
-A Blog is defined by a title, a description and its format and a
-RSS URL to provide RSS feed.
-
-A BlogEntry is defined by a title, a content and its format and
-a relation to a Blog, meaning a BlogEntry belongs to a Blog.
-
-
-Next step
-~~~~~~~~~
-
-This was a brief demonstration of the re-usability of cubes and a way
-to show how you can use `CubicWeb` straigth out of the box.
-
-As a developper, you'll want to know more about how to develop new
-cubes and cutomize the views and this is what we talk about now. 
-
-
--- a/doc/book/en/index.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/en/index.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -25,7 +25,7 @@
 for semantic web application development that promotes quality, reusability and
 efficiency.
 
-The unbeliever will read the :ref:`Overview`.
+The unbeliever will read the :ref:`Tutorial`.
 
 The hacker will join development at the forge_.
 
--- a/doc/book/fr/02-foundation.fr.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/fr/02-foundation.fr.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -258,7 +258,7 @@
     réponse 
   * `cursor()` retourne un curseur RQL sur la session
   * `execute(*args, **kwargs)`, raccourci vers .cursor().execute()
-  * `property_value(key)`, gestion des propriétés (`EProperty`)
+  * `property_value(key)`, gestion des propriétés (`CWProperty`)
   * le dictionaire `data` pour stocker des données pour partager de
     l'information entre les composants *durant l'éxécution de la requête*.
 
--- a/doc/book/fr/04-01-schema-stdlib.fr.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/fr/04-01-schema-stdlib.fr.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -11,10 +11,10 @@
 Schémas "systèmes"
 ``````````````````
 
-* `EUser`, utilisateurs du système
-* `EGroup`, groupes d'utilisateurs
-* `EEType`, types d'entité
-* `ERType`, types de relation
+* `CWUser`, utilisateurs du système
+* `CWGroup`, groupes d'utilisateurs
+* `CWEType`, types d'entité
+* `CWRType`, types de relation
 
 * `State`, état d'un workflow
 * `Transition`, transition d'un workflow
@@ -23,8 +23,8 @@
 * `EmailAddress`, adresse électronique, utilisé par le système de notification
   pour les utilisateurs et par d'autres schéma optionnels
 
-* `EProperty`, utilisé pour configurer l'application
-* `EPermission`, utilisé pour configurer la sécurité de l'application
+* `CWProperty`, utilisé pour configurer l'application
+* `CWPermission`, utilisé pour configurer la sécurité de l'application
 
 * `Card`, fiche documentaire générique
 * `Bookmark`, un type d'entité utilisé pour permetter à un utilisateur de
--- a/doc/book/fr/04-02-schema-definition.fr.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/fr/04-02-schema-definition.fr.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -32,12 +32,12 @@
   
   - `modification_date` (`Datetime`)
   
-  - `created_by` (`EUser`) (quel utilisateur a créé l'entité)
+  - `created_by` (`CWUser`) (quel utilisateur a créé l'entité)
   
-  - `owned_by` (`EUser`) (à qui appartient l'entité, par défaut le
+  - `owned_by` (`CWUser`) (à qui appartient l'entité, par défaut le
      créateur mais pas forcément et il peut exister plusieurs propriétaires)
      
-  - `is` (`EEType`)
+  - `is` (`CWEType`)
 
   
 * il est également possible de définir des relations dont le type d'entité est
@@ -167,7 +167,7 @@
     inlined = True
     cardinality = '?*'
     subject = '*'
-    object = 'EUser'
+    object = 'CWUser'
 
 En plus des permissions, les propriétés propres aux types de relation (et donc
 partagés par toutes les définitions de relation de ce type) sont :
@@ -263,16 +263,16 @@
     'add'/'read' son pris en considération
 
 
-En plus de cela, le type d'entité `EPermission` de la librairie standard permet
+En plus de cela, le type d'entité `CWPermission` de la librairie standard permet
 de construire des modèles de sécurités très complexes et dynamiques. Le schéma
 de ce type d'entité est le suivant : ::
 
 
-    class EPermission(MetaEntityType):
+    class CWPermission(MetaEntityType):
 	"""entity type that may be used to construct some advanced security configuration
 	"""
 	name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
-	require_group = SubjectRelation('EGroup', cardinality='+*',
+	require_group = SubjectRelation('CWGroup', cardinality='+*',
 					description=_('groups to which the permission is granted'))
 	require_state = SubjectRelation('State',
 				    description=_("entity'state in which the permission is applyable"))
@@ -311,7 +311,7 @@
 		       }
 	inlined = True
 
-Cette configuration suppose indique qu'une entité `EPermission` de nom
+Cette configuration suppose indique qu'une entité `CWPermission` de nom
 "add_version" peut-être associée à un projet et donner le droit de créer des
 versions sur ce projet à des groupes spécifiques. Il est important de noter les
 points suivants :
@@ -319,7 +319,7 @@
 * dans ce cas il faut protéger à la fois le type d'entité "Version" et la
   relation liant une version à un projet ("version_of")
 
-* du fait de la généricité du type d'entité `EPermission`, il faut effectuer
+* du fait de la généricité du type d'entité `CWPermission`, il faut effectuer
   l'unification avec les groupes et / ou les états le cas échéant dans
   l'expression ("U in_group G, P require_group G" dans l'exemple ci-dessus)
 
--- a/doc/book/fr/06-define-workflows.fr.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/fr/06-define-workflows.fr.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -117,7 +117,7 @@
   
   _ = unicode
 
-  moderators      = add_entity('EGroup', name=u"moderators")
+  moderators      = add_entity('CWGroup', name=u"moderators")
 
   submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
   published = add_state(_('published'), 'BlogEntry')
--- a/doc/book/fr/09-instance-config.fr.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/fr/09-instance-config.fr.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -29,7 +29,7 @@
 
 :`main.anonymous-user`, `main.anonymous-password`:
    login et mot de passe à utiliser pour se connecter au serveur RQL lors des
-   connexions HTTP anonymes. Il faut que le compte EUser associé existe.
+   connexions HTTP anonymes. Il faut que le compte CWUser associé existe.
 
 :`main.base-url`:
    url de base du site, à utiliser pour générer les urls des pages web
@@ -145,7 +145,7 @@
 
 Configuration Eproperties
 -------------------------
-D'autres paramètres de configuration sont sous la forme d'entités `EProperty`
+D'autres paramètres de configuration sont sous la forme d'entités `CWProperty`
 dans la base de données. Il faut donc les éditer via l'interface web ou par des
 requêtes rql.
 
--- a/doc/book/fr/12-ui-components.fr.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/fr/12-ui-components.fr.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -9,6 +9,6 @@
 ---------------------
 XXXFILLME
 
-EProperty
+CWProperty
 ---------
 XXXFILLME
--- a/doc/book/fr/MERGE_ME-tut-create-app.fr.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/doc/book/fr/MERGE_ME-tut-create-app.fr.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -331,7 +331,7 @@
   
   _ = unicode
 
-  moderators      = add_entity('EGroup', name=u"moderators")
+  moderators      = add_entity('CWGroup', name=u"moderators")
 
   submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
   published = add_state(_('published'), 'BlogEntry')
--- a/entities/__init__.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/entities/__init__.py	Fri Apr 24 19:46:47 2009 +0200
@@ -25,7 +25,7 @@
     """
     id = 'Any'                    
     __implements__ = (IBreadCrumbs, IFeed)
-    
+
     @classmethod
     def selected(cls, etype):
         """the special Any entity is used as the default factory, so
@@ -124,7 +124,7 @@
         
     @property
     def creator(self):
-        """return the EUser entity which has created this entity, or None if
+        """return the CWUser entity which has created this entity, or None if
         unknown or if the curent user doesn't has access to this euser
         """
         try:
--- a/entities/authobjs.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/entities/authobjs.py	Fri Apr 24 19:46:47 2009 +0200
@@ -5,22 +5,23 @@
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 """
 __docformat__ = "restructuredtext en"
+
 from logilab.common.decorators import cached
 
 from cubicweb import Unauthorized
 from cubicweb.entities import AnyEntity, fetch_config
 
-class EGroup(AnyEntity):
-    id = 'EGroup'
+class CWGroup(AnyEntity):
+    id = 'CWGroup'
     fetch_attrs, fetch_order = fetch_config(['name'])
     fetch_unrelated_order = fetch_order
 
     def db_key_name(self):
         """XXX goa specific"""
         return self.get('name')
-    
-class EUser(AnyEntity):
-    id = 'EUser'
+
+class CWUser(AnyEntity):
+    id = 'CWUser'
     fetch_attrs, fetch_order = fetch_config(['login', 'firstname', 'surname'])
     fetch_unrelated_order = fetch_order
     
@@ -31,7 +32,7 @@
     def __init__(self, *args, **kwargs):
         groups = kwargs.pop('groups', None)
         properties = kwargs.pop('properties', None)
-        super(EUser, self).__init__(*args, **kwargs)
+        super(CWUser, self).__init__(*args, **kwargs)
         if groups is not None:
             self._groups = groups
         if properties is not None:
@@ -91,7 +92,7 @@
     def owns(self, eid):
         if hasattr(self.req, 'unsafe_execute'):
             # use unsafe_execute on the repository side, in case
-            # session's user doesn't have access to EUser
+            # session's user doesn't have access to CWUser
             execute = self.req.unsafe_execute
         else:
             execute = self.req.execute
@@ -103,7 +104,7 @@
     owns = cached(owns, keyarg=1)
 
     def has_permission(self, pname, contexteid=None):
-        rql = 'Any P WHERE P is EPermission, U eid %(u)s, U in_group G, '\
+        rql = 'Any P WHERE P is CWPermission, U eid %(u)s, U in_group G, '\
               'P name %(pname)s, P require_group G'
         kwargs = {'pname': pname, 'u': self.eid}
         cachekey = None
@@ -138,5 +139,5 @@
         return self.get('login')
 
 from logilab.common.deprecation import class_renamed
-Euser = class_renamed('Euser', EUser)
-Euser.id = 'Euser'
+EUser = class_renamed('EUser', CWUser)
+EGroup = class_renamed('EGroup', CWGroup)
--- a/entities/lib.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/entities/lib.py	Fri Apr 24 19:46:47 2009 +0200
@@ -30,11 +30,11 @@
         if self.alias:
             return '%s <%s>' % (self.alias, self.display_address())
         return self.display_address()
-    
+
     @property
     def email_of(self):
         return self.reverse_use_email and self.reverse_use_email[0]
-    
+
     @cached
     def canonical_form(self):
         if self.canonical:
@@ -88,15 +88,15 @@
 Emailaddress.id = 'Emailaddress'
 
 
-class EProperty(AnyEntity):
-    id = 'EProperty'
+class CWProperty(AnyEntity):
+    id = 'CWProperty'
 
-    fetch_attrs, fetch_order = fetch_config(['pkey', 'value'])    
+    fetch_attrs, fetch_order = fetch_config(['pkey', 'value'])
     rest_attr = 'pkey'
 
     def typed_value(self):
         return self.vreg.typed_value(self.pkey, self.value)
-        
+
     def dc_description(self):
         try:
             return self.req._(self.vreg.property_info(self.pkey)['help'])
@@ -108,7 +108,7 @@
         information when this entity is being deleted
         """
         return 'view', {}
-        
+
 
 class Bookmark(AnyEntity):
     """customized class for Bookmark entities"""
@@ -130,24 +130,9 @@
         return self.absolute_url() + '/follow'
 
 
-class Card(AnyEntity):
-    """customized class for Card entities"""
-    id = 'Card'
-    rest_attr = 'wikiid'
-    
-    fetch_attrs, fetch_order = fetch_config(['title'])
-
-    def dc_title(self):
-        return self.title
-
-    def dc_description(self, format='text/plain'):
-        return self.synopsis or u''
-
-
-class ECache(AnyEntity):
+class CWCache(AnyEntity):
     """Cache"""
-    id = 'ECache'
-    
+    id = 'CWCache'
     fetch_attrs, fetch_order = fetch_config(['name'])
 
     def touch(self):
--- a/entities/schemaobjs.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/entities/schemaobjs.py	Fri Apr 24 19:46:47 2009 +0200
@@ -14,8 +14,8 @@
 from cubicweb.entities import AnyEntity, fetch_config
 
 
-class EEType(AnyEntity):
-    id = 'EEType'
+class CWEType(AnyEntity):
+    id = 'CWEType'
     fetch_attrs, fetch_order = fetch_config(['name'])
 
     def dc_title(self):
@@ -37,8 +37,8 @@
         return self.get('name')
 
 
-class ERType(AnyEntity):
-    id = 'ERType'
+class CWRType(AnyEntity):
+    id = 'CWRType'
     fetch_attrs, fetch_order = fetch_config(['name'])
     
     def dc_title(self):
@@ -85,8 +85,8 @@
         return self.get('name')
 
 
-class ENFRDef(AnyEntity):
-    id = 'ENFRDef'
+class CWRelation(AnyEntity):
+    id = 'CWRelation'
     fetch_attrs = fetch_config(['cardinality'])[0]
     
     def dc_title(self):
@@ -113,11 +113,11 @@
         """
         if self.relation_type:
             return self.relation_type[0].rest_path(), {}
-        return super(ENFRDef, self).after_deletion_path()
+        return super(CWRelation, self).after_deletion_path()
 
 
-class EFRDef(ENFRDef):
-    id = 'EFRDef'
+class CWAttribute(CWRelation):
+    id = 'CWAttribute'
     
     def dc_long_title(self):
         card = self.cardinality
@@ -130,8 +130,8 @@
             self.to_entity[0].name)
 
 
-class EConstraint(AnyEntity):
-    id = 'EConstraint'
+class CWConstraint(AnyEntity):
+    id = 'CWConstraint'
     fetch_attrs, fetch_order = fetch_config(['value'])
 
     def dc_title(self):
@@ -143,7 +143,7 @@
         """
         if self.reverse_constrained_by:
             return self.reverse_constrained_by[0].rest_path(), {}
-        return super(EConstraint, self).after_deletion_path()
+        return super(CWConstraint, self).after_deletion_path()
 
     @property
     def type(self):
@@ -184,8 +184,8 @@
         return super(RQLExpression, self).after_deletion_path()
 
 
-class EPermission(AnyEntity):
-    id = 'EPermission'
+class CWPermission(AnyEntity):
+    id = 'CWPermission'
     fetch_attrs, fetch_order = fetch_config(['name', 'label'])
 
     def dc_title(self):
@@ -200,4 +200,4 @@
         permissionof = getattr(self, 'reverse_require_permission', ())
         if len(permissionof) == 1:
             return permissionof[0].rest_path(), {}
-        return super(EPermission, self).after_deletion_path()
+        return super(CWPermission, self).after_deletion_path()
--- a/entities/test/unittest_base.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/entities/test/unittest_base.py	Fri Apr 24 19:46:47 2009 +0200
@@ -10,7 +10,7 @@
 from cubicweb import ValidationError
 from cubicweb.interfaces import IMileStone, IWorkflowable
 from cubicweb.entities import AnyEntity
-from cubicweb.entities.authobjs import EUser
+from cubicweb.entities.authobjs import CWUser
 from cubicweb.web.widgets import AutoCompletionWidget
 
 
@@ -36,20 +36,20 @@
 
     def test_entity_meta_attributes(self):
         # XXX move to yams
-        self.assertEquals(self.schema['EUser'].meta_attributes(), {})
+        self.assertEquals(self.schema['CWUser'].meta_attributes(), {})
         self.assertEquals(dict((str(k), v) for k, v in self.schema['Card'].meta_attributes().iteritems()),
                           {'content_format': ('format', 'content')})
         
 
-class EUserTC(BaseEntityTC):
+class CWUserTC(BaseEntityTC):
     def test_dc_title_and_name(self):
-        e = self.entity('EUser U WHERE U login "member"')
+        e = self.entity('CWUser U WHERE U login "member"')
         self.assertEquals(e.dc_title(), 'member')
         self.assertEquals(e.name(), 'member')
-        self.execute(u'SET X firstname "bouah" WHERE X is EUser, X login "member"')
+        self.execute(u'SET X firstname "bouah" WHERE X is CWUser, X login "member"')
         self.assertEquals(e.dc_title(), 'member')
         self.assertEquals(e.name(), u'bouah')
-        self.execute(u'SET X surname "lôt" WHERE X is EUser, X login "member"')
+        self.execute(u'SET X surname "lôt" WHERE X is CWUser, X login "member"')
         self.assertEquals(e.dc_title(), 'member')
         self.assertEquals(e.name(), u'bouah lôt')
 
@@ -57,7 +57,7 @@
 class StateAndTransitionsTC(BaseEntityTC):
         
     def test_transitions(self):
-        user = self.entity('EUser X')
+        user = self.entity('CWUser X')
         e = self.entity('State S WHERE S name "activated"')
         trs = list(e.transitions(user))
         self.assertEquals(len(trs), 1)
@@ -71,12 +71,12 @@
         e = self.entity('State S WHERE S name "activated"')
         trs = list(e.transitions(user))
         self.assertEquals(len(trs), 0)
-        user = self.entity('EUser X')
+        user = self.entity('CWUser X')
         self.assert_(not user.can_pass_transition('deactivate'))
         self.assert_(not user.can_pass_transition('activate'))
         
     def test_transitions_with_dest_specfied(self):
-        user = self.entity('EUser X')
+        user = self.entity('CWUser X')
         e = self.entity('State S WHERE S name "activated"')
         e2 = self.entity('State S WHERE S name "deactivated"')
         trs = list(e.transitions(user, e2.eid))
@@ -132,9 +132,9 @@
         state3 = self.add_entity('State', name=u'state3')
         tr1 = self.add_entity('Transition', name=u'tr1')
         tr2 = self.add_entity('Transition', name=u'tr2')
-        self.execute('SET X state_of Y WHERE X eid in (%s, %s), Y is EEType, Y name "Card"' %
+        self.execute('SET X state_of Y WHERE X eid in (%s, %s), Y is CWEType, Y name "Card"' %
                       (state1.eid, state2.eid))
-        self.execute('SET X state_of Y WHERE X eid in (%s, %s), Y is EEType, Y name "Bookmark"' %
+        self.execute('SET X state_of Y WHERE X eid in (%s, %s), Y is CWEType, Y name "Bookmark"' %
                       (state1.eid, state3.eid))
         self.execute('SET X transition_of Y WHERE X eid %s, Y name "Card"' % tr1.eid)
         self.execute('SET X transition_of Y WHERE X eid %s, Y name "Bookmark"' % tr2.eid)
@@ -171,9 +171,9 @@
         state2 = self.add_entity('State', name=u'state2')
         tr1 = self.add_entity('Transition', name=u'tr1')
         tr2 = self.add_entity('Transition', name=u'tr2')
-        self.execute('SET X state_of Y WHERE X eid in (%s, %s), Y is EEType, Y name "Card"' %
+        self.execute('SET X state_of Y WHERE X eid in (%s, %s), Y is CWEType, Y name "Card"' %
                       (state1.eid, state2.eid))
-        self.execute('SET X state_of Y WHERE X eid in (%s, %s), Y is EEType, Y name "Bookmark"' %
+        self.execute('SET X state_of Y WHERE X eid in (%s, %s), Y is CWEType, Y name "Bookmark"' %
                       (state1.eid, state2.eid))
         self.execute('SET X transition_of Y WHERE X eid %s, Y name "Card"' % tr1.eid)
         self.execute('SET X transition_of Y WHERE X eid %s, Y name "Bookmark"' % tr2.eid)
@@ -225,15 +225,15 @@
         self.assertEquals(email.printable_value('address'), 'syt')
 
 
-class EUserTC(BaseEntityTC):
+class CWUserTC(BaseEntityTC):
     
     def test_complete(self):
-        e = self.entity('EUser X WHERE X login "admin"')
+        e = self.entity('CWUser X WHERE X login "admin"')
         e.complete()
 
         
     def test_matching_groups(self):
-        e = self.entity('EUser X WHERE X login "admin"')
+        e = self.entity('CWUser X WHERE X login "admin"')
         self.failUnless(e.matching_groups('managers'))
         self.failIf(e.matching_groups('xyz'))
         self.failUnless(e.matching_groups(('xyz', 'managers')))
@@ -251,7 +251,7 @@
         e.change_state(deactivatedeid, u'deactivate 2')
         self.commit()
         # get a fresh user to avoid potential cache issues
-        e = self.entity('EUser X WHERE X eid %s' % e.eid)
+        e = self.entity('CWUser X WHERE X eid %s' % e.eid)
         self.assertEquals([tr.comment for tr in e.reverse_wf_info_for],
                           [None, 'deactivate 1', 'activate 1', 'deactivate 2'])
         self.assertEquals(e.latest_trinfo().comment, 'deactivate 2')
@@ -260,11 +260,11 @@
 class InterfaceTC(EnvBasedTC):
 
     def test_nonregr_subclasses_and_mixins_interfaces(self):
-        class MyUser(EUser):
+        class MyUser(CWUser):
             __implements__ = (IMileStone,)
         self.vreg._loadedmods[__name__] = {}
         self.vreg.register_vobject_class(MyUser)
-        self.failUnless(implements(EUser, IWorkflowable))
+        self.failUnless(implements(CWUser, IWorkflowable))
         self.failUnless(implements(MyUser, IMileStone))
         self.failUnless(implements(MyUser, IWorkflowable))
 
--- a/entity.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/entity.py	Fri Apr 24 19:46:47 2009 +0200
@@ -59,10 +59,10 @@
                 AutomaticEntityForm.rinlined.set_rtag(True, rtype, role, stype, otype)
             else:
                 raise ValueError(tag)
-            
+
 except ImportError:
     AutomaticEntityForm = None
-    
+
     def dispatch_rtags(*args):
         pass
 
@@ -74,7 +74,7 @@
             etype = getattr(base, 'id', None)
             if etype and etype != 'Any':
                 return etype
-            
+
 def _get_defs(attr, name, bases, classdict):
     try:
         yield name, classdict.pop(attr)
@@ -86,7 +86,7 @@
                 yield base.__name__, value
             except AttributeError:
                 continue
-            
+
 class metaentity(type):
     """this metaclass sets the relation tags on the entity class
     and deals with the `widgets` attribute
@@ -138,7 +138,7 @@
 class Entity(AppRsetObject, dict):
     """an entity instance has e_schema automagically set on
     the class and instances has access to their issuing cursor.
-    
+
     A property is set for each attribute and relation on each entity's type
     class. Becare that among attributes, 'eid' is *NEITHER* stored in the
     dict containment (which acts as a cache for other attributes dynamically
@@ -151,7 +151,7 @@
     :cvar rest_var: indicates which attribute should be used to build REST urls
                     If None is specified, the first non-meta attribute will
                     be used
-                    
+
     :type skip_copy_for: list
     :cvar skip_copy_for: a list of relations that should be skipped when copying
                          this kind of entity. Note that some relations such
@@ -162,14 +162,14 @@
     __registry__ = 'etypes'
     __select__ = yes()
 
-    # class attributes that must be set in class definition 
+    # class attributes that must be set in class definition
     id = None
     rest_attr = None
     fetch_attrs = None
     skip_copy_for = ()
     # class attributes set automatically at registration time
     e_schema = None
-    
+
     @classmethod
     def registered(cls, registry):
         """build class using descriptor at registration time"""
@@ -178,7 +178,7 @@
         if cls.id != 'Any':
             cls.__initialize__()
         return cls
-                
+
     MODE_TAGS = set(('link', 'create'))
     CATEGORY_TAGS = set(('primary', 'secondary', 'generic', 'generated')) # , 'metadata'))
     @classmethod
@@ -210,7 +210,7 @@
         if mixins:
             cls.__bases__ = tuple(mixins + [p for p in cls.__bases__ if not p is object])
             cls.debug('plugged %s mixins on %s', mixins, etype)
-    
+
     @classmethod
     def fetch_rql(cls, user, restriction=None, fetchattrs=None, mainvar='X',
                   settype=True, ordermethod='fetch_order'):
@@ -231,7 +231,7 @@
             rql +=  ' ORDERBY %s' % ','.join(orderby)
         rql += ' WHERE %s' % ', '.join(restrictions)
         return rql
-    
+
     @classmethod
     def _fetch_restrictions(cls, mainvar, varmaker, fetchattrs,
                             selection, orderby, restrictions, user,
@@ -277,7 +277,14 @@
                 orderby.append(orderterm)
         return selection, orderby, restrictions
 
-    def __init__(self, req, rset, row=None, col=0):
+    @classmethod
+    @cached
+    def parent_classes(cls):
+        parents = [cls.vreg.etype_class(e.type) for e in cls.e_schema.ancestors()]
+        parents.append(cls.vreg.etype_class('Any'))
+        return parents
+
+    def __init__(self, req, rset=None, row=None, col=0):
         AppRsetObject.__init__(self, req, rset, row, col)
         dict.__init__(self)
         self._related_cache = {}
@@ -286,7 +293,7 @@
         else:
             self.eid = None
         self._is_saved = True
-        
+
     def __repr__(self):
         return '<Entity %s %s %s at %s>' % (
             self.e_schema, self.eid, self.keys(), id(self))
@@ -301,11 +308,11 @@
         """hook called by the repository before doing anything to add the entity
         (before_add entity hooks have not been called yet). This give the
         occasion to do weird stuff such as autocast (File -> Image for instance).
-        
+
         This method must return the actual entity to be added.
         """
         return self
-    
+
     def set_eid(self, eid):
         self.eid = self['eid'] = eid
 
@@ -326,7 +333,7 @@
         saved in its source.
         """
         return self.has_eid() and self._is_saved
-    
+
     @cached
     def metainformation(self):
         res = dict(zip(('type', 'source', 'extid'), self.req.describe(self.eid)))
@@ -342,7 +349,7 @@
 
     def has_perm(self, action):
         return self.e_schema.has_perm(self.req, action, self.eid)
-        
+
     def view(self, vid, __registry='views', **kwargs):
         """shortcut to apply a view on this entity"""
         return self.vreg.render(__registry, vid, self.req, rset=self.rset,
@@ -445,9 +452,9 @@
         trdata = TransformData(data, format, encoding, appobject=self)
         data = _engine.convert(trdata, target_format).decode()
         if format == 'text/html':
-            data = soup2xhtml(data, self.req.encoding)                
+            data = soup2xhtml(data, self.req.encoding)
         return data
-    
+
     # entity cloning ##########################################################
 
     def copy_relations(self, ceid):
@@ -510,7 +517,7 @@
         rset = ResultSet([(self.eid,)], 'Any X WHERE X eid %(x)s',
                          {'x': self.eid}, [(self.id,)])
         return self.req.decorate_rset(rset)
-                       
+
     def to_complete_relations(self):
         """by default complete final relations to when calling .complete()"""
         for rschema in self.e_schema.subject_relations():
@@ -526,7 +533,7 @@
                    all(matching_groups(es.get_groups('read'))
                        for es in rschema.objects(self.e_schema)):
                     yield rschema, 'subject'
-                    
+
     def to_complete_attributes(self, skip_bytes=True):
         for rschema, attrschema in self.e_schema.attribute_definitions():
             # skip binary data by default
@@ -541,7 +548,7 @@
                 self[attr] = None
                 continue
             yield attr
-            
+
     def complete(self, attributes=None, skip_bytes=True):
         """complete this entity by adding missing attributes (i.e. query the
         repository to fill the entity)
@@ -611,7 +618,7 @@
                 else:
                     rrset = self.req.eid_rset(value)
                 self.set_related_cache(rtype, x, rrset)
-                
+
     def get_value(self, name):
         """get value for the attribute relation <name>, query the repository
         to get the value if necessary.
@@ -647,7 +654,7 @@
 
     def related(self, rtype, role='subject', limit=None, entities=False):
         """returns a resultset of related entities
-        
+
         :param role: is the role played by 'self' in the relation ('subject' or 'object')
         :param limit: resultset's maximum size
         :param entities: if True, the entites are returned; if False, a result set is returned
@@ -693,7 +700,7 @@
             args = tuple(rql.split(' WHERE ', 1))
             rql = '%s ORDERBY Z DESC WHERE X modification_date Z, %s' % args
         return rql
-    
+
     # generic vocabulary methods ##############################################
 
     @obsolete('see new form api')
@@ -701,7 +708,7 @@
         """vocabulary functions must return a list of couples
         (label, eid) that will typically be used to fill the
         edition view's combobox.
-        
+
         If `eid` is None in one of these couples, it should be
         interpreted as a separator in case vocabulary results are grouped
         """
@@ -710,7 +717,7 @@
         form = EntityFieldsForm(self.req, entity=self)
         field = mock_object(name=rtype, role=role)
         return form.form_field_vocabulary(field, limit)
-            
+
     def unrelated_rql(self, rtype, targettype, role, ordermethod=None,
                       vocabconstraints=True):
         """build a rql to fetch `targettype` entities unrelated to this entity
@@ -746,7 +753,7 @@
             before, after = rql.split(' WHERE ', 1)
             rql = '%s ORDERBY %s WHERE %s' % (before, searchedvar, after)
         return rql
-    
+
     def unrelated(self, rtype, targettype, role='subject', limit=None,
                   ordermethod=None):
         """return a result set of target type objects that may be related
@@ -759,14 +766,14 @@
         if self.has_eid():
             return self.req.execute(rql, {'x': self.eid})
         return self.req.execute(rql)
-        
+
     # relations cache handling ################################################
-    
+
     def relation_cached(self, rtype, role):
         """return true if the given relation is already cached on the instance
         """
         return '%s_%s' % (rtype, role) in self._related_cache
-    
+
     def related_cache(self, rtype, role, entities=True, limit=None):
         """return values for the given relation if it's cached on the instance,
         else raise `KeyError`
@@ -778,7 +785,7 @@
             else:
                 res = res.limit(limit)
         return res
-    
+
     def set_related_cache(self, rtype, role, rset, col=0):
         """set cached values for the given relation"""
         if rset:
@@ -798,7 +805,7 @@
         else:
             related = []
         self._related_cache['%s_%s' % (rtype, role)] = (rset, related)
-        
+
     def clear_related_cache(self, rtype=None, role=None):
         """clear cached values for the given relation or the entire cache if
         no relation is given
@@ -808,9 +815,9 @@
         else:
             assert role
             self._related_cache.pop('%s_%s' % (rtype, role), None)
-        
+
     # raw edition utilities ###################################################
-    
+
     def set_attributes(self, **kwargs):
         assert kwargs
         relations = []
@@ -822,14 +829,14 @@
         kwargs['x'] = self.eid
         self.req.execute('SET %s WHERE X eid %%(x)s' % ','.join(relations),
                          kwargs, 'x')
-            
+
     def delete(self):
         assert self.has_eid(), self.eid
         self.req.execute('DELETE %s X WHERE X eid %%(x)s' % self.e_schema,
                          {'x': self.eid})
-    
+
     # server side utilities ###################################################
-        
+
     def set_defaults(self):
         """set default values according to the schema"""
         self._default_set = set()
@@ -872,13 +879,13 @@
                 yield self
         else:
             yield self
-                    
+
     def get_words(self):
         """used by the full text indexer to get words to index
 
         this method should only be used on the repository side since it depends
         on the indexer package
-        
+
         :rtype: list
         :return: the list of indexable word of this entity
         """
@@ -895,7 +902,7 @@
                 continue
             if value:
                 words += tokenize(value)
-        
+
         for rschema, role in self.e_schema.fulltext_relations():
             if role == 'subject':
                 for entity in getattr(self, rschema.type):
@@ -940,7 +947,7 @@
             raise AttributeError('%s cannot be only be accessed from instances'
                                  % self._rtype)
         return eobj.related(self._rtype, self._role, entities=True)
-    
+
     def __set__(self, eobj, value):
         raise NotImplementedError
 
@@ -948,7 +955,7 @@
 class SubjectRelation(Relation):
     """descriptor that controls schema relation access"""
     _role = 'subject'
-    
+
 class ObjectRelation(Relation):
     """descriptor that controls schema relation access"""
     _role = 'object'
--- a/etwist/server.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/etwist/server.py	Fri Apr 24 19:46:47 2009 +0200
@@ -18,7 +18,7 @@
 from twisted.web2 import static, resource, responsecode
 
 from cubicweb import ObjectNotFound
-from cubicweb.web import (AuthenticationError, NotFound, Redirect, 
+from cubicweb.web import (AuthenticationError, NotFound, Redirect,
                        RemoteCallFailed, DirectResponse, StatusResponse,
                        ExplicitLogin)
 from cubicweb.web.application import CubicWebPublisher
@@ -42,7 +42,7 @@
         start_task(interval, catch_error_func)
     # ensure no tasks will be further added
     repo._looping_tasks = ()
-    
+
 
 class LongTimeExpiringFile(static.File):
     """overrides static.File and sets a far futre ``Expires`` date
@@ -71,7 +71,7 @@
 
 class CubicWebRootResource(resource.PostableResource):
     addSlash = False
-    
+
     def __init__(self, config, debug=None):
         self.appli = CubicWebPublisher(config, debug=debug)
         self.debugmode = debug
@@ -103,7 +103,7 @@
         interval = min(config['cleanup-session-time'] or 120,
                        config['cleanup-anonymous-session-time'] or 720) / 2.
         start_task(interval, self.appli.session_handler.clean_sessions)
-        
+
     def shutdown_event(self):
         """callback fired when the server is shutting down to properly
         clean opened sessions
@@ -116,7 +116,7 @@
             self.pyro_daemon.handleRequests(self.pyro_listen_timeout)
         except select.error:
             return
-        
+
     def locateChild(self, request, segments):
         """Indicate which resource to use to process down the URL's path"""
         if segments:
@@ -143,7 +143,7 @@
                     return static.File(fckeditordir), segments[1:]
         # Otherwise we use this single resource
         return self, ()
-    
+
     def render(self, request):
         """Render a page from the root resource"""
         # reload modified files (only in development or debug mode)
@@ -153,7 +153,7 @@
             return self.render_request(request)
         else:
             return threads.deferToThread(self.render_request, request)
-            
+
     def render_request(self, request):
         origpath = request.path
         host = request.host
@@ -163,7 +163,7 @@
             origpath = origpath[6:]
             request.uri = request.uri[6:]
             https = True
-            baseurl = self.https_url or self.base_url 
+            baseurl = self.https_url or self.base_url
         else:
             https = False
             baseurl = self.base_url
@@ -180,7 +180,7 @@
             return self.redirect(req, ex.location)
         if https and req.cnx.anonymous_connection:
             # don't allow anonymous on https connection
-            return self.request_auth(req)            
+            return self.request_auth(req)
         if self.url_rewriter is not None:
             # XXX should occur before authentication?
             try:
@@ -226,11 +226,6 @@
                 return self.request_auth(req, loggedout=True)
         except Redirect, ex:
             return self.redirect(req, ex.location)
-        if not result:
-            # no result, something went wrong...
-            self.error('no data (%s)', req)
-            # 500 Internal server error
-            return self.redirect(req, req.build_url('error'))
         # request may be referenced by "onetime callback", so clear its entity
         # cache to avoid memory usage
         req.drop_entity_cache()
@@ -242,11 +237,11 @@
         self.debug('redirecting to %s', location)
         # 303 See other
         return http.Response(code=303, headers=req.headers_out)
-        
+
     def request_auth(self, req, loggedout=False):
         if self.https_url and req.base_url() != self.https_url:
             req.headers_out.setHeader('location', self.https_url + 'login')
-            return http.Response(code=303, headers=req.headers_out)            
+            return http.Response(code=303, headers=req.headers_out)
         if self.config['auth-mode'] == 'http':
             code = responsecode.UNAUTHORIZED
         else:
@@ -260,7 +255,7 @@
             content = self.appli.need_login_content(req)
         return http.Response(code, req.headers_out, content)
 
-    
+
 # This part gets run when you run this file via: "twistd -noy demo.py"
 def main(appid, cfgname):
     """Starts an cubicweb  twisted server for an application
@@ -295,12 +290,12 @@
 
 # XXX set max file size to 100Mo: put max upload size in the configuration
 # line below for twisted >= 8.0, default param value for earlier version
-resource.PostableResource.maxSize = 100*1024*1024 
+resource.PostableResource.maxSize = 100*1024*1024
 def parsePOSTData(request, maxMem=100*1024, maxFields=1024,
                   maxSize=100*1024*1024):
     if request.stream.length == 0:
         return defer.succeed(None)
-    
+
     ctype = request.headers.getHeader('content-type')
 
     if ctype is None:
@@ -318,7 +313,7 @@
     def error(f):
         f.trap(fileupload.MimeFormatError)
         raise http.HTTPError(responsecode.BAD_REQUEST)
-    
+
     if ctype.mediaType == 'application' and ctype.mediaSubtype == 'x-www-form-urlencoded':
         d = fileupload.parse_urlencoded(request.stream, keep_blank_values=True)
         d.addCallbacks(updateArgs, error)
--- a/ext/rest.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/ext/rest.py	Fri Apr 24 19:46:47 2009 +0200
@@ -189,7 +189,7 @@
         context = state.document.settings.context
         context.req.add_css('pygments.css')
         return [nodes.raw('', parsed, format='html')]
-     
+
     pygments_directive.arguments = (1, 0, 1)
     pygments_directive.content = 1
     directives.register_directive('sourcecode', pygments_directive)
@@ -216,11 +216,9 @@
         self.finish_parse()
 
 
-_REST_PARSER = CubicWebReSTParser()
-
 def rest_publish(context, data):
     """publish a string formatted as ReStructured Text to HTML
-    
+
     :type context: a cubicweb application object
 
     :type data: str
@@ -239,7 +237,7 @@
                 'warning_stream': StringIO(), 'context': context,
                 # dunno what's the max, severe is 4, and we never want a crash
                 # (though try/except may be a better option...)
-                'halt_level': 10, 
+                'halt_level': 10,
                 }
     if context:
         if hasattr(req, 'url'):
@@ -252,7 +250,7 @@
         base_url = None
     try:
         return publish_string(writer=Writer(base_url=base_url),
-                              parser=_REST_PARSER, source=data,
+                              parser=CubicWebReSTParser(), source=data,
                               settings_overrides=settings)
     except Exception:
         LOGGER.exception('error while publishing ReST text')
--- a/goa/appobjects/dbmgmt.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/appobjects/dbmgmt.py	Fri Apr 24 19:46:47 2009 +0200
@@ -168,7 +168,7 @@
 class ContentClear(StartupView):
     id = 'contentclear'
     __select__ = none_rset() & match_user_groups('managers')
-    skip_etypes = ('EGroup', 'EUser')
+    skip_etypes = ('CWGroup', 'CWUser')
     
     def call(self):
         # XXX should use unsafe_execute with all hooks deactivated
--- a/goa/appobjects/gauthservice.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/appobjects/gauthservice.py	Fri Apr 24 19:46:47 2009 +0200
@@ -12,7 +12,7 @@
 from google.appengine.api import users
 
 
-class GAEUserLink(UserLink):
+class GACWUserLink(UserLink):
 
     def anon_user_link(self):
         self.w(self.req._('anonymous'))
@@ -26,5 +26,5 @@
     
 def registration_callback(vreg):
     if hasattr(vreg.config, 'has_resource'):
-        vreg.register(GAEUserLink, clear=True)
+        vreg.register(GACWUserLink, clear=True)
         vreg.register(GAELogoutAction, clear=True)
--- a/goa/dbinit.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/dbinit.py	Fri Apr 24 19:46:47 2009 +0200
@@ -15,7 +15,7 @@
     try:
         return _GROUP_CACHE[groupname]
     except KeyError:
-        key = Key.from_path('EGroup', 'key_' + groupname, parent=None)
+        key = Key.from_path('CWGroup', 'key_' + groupname, parent=None)
         try:
             group = Get(key)
         except datastore_errors.EntityNotFoundError:
@@ -29,7 +29,7 @@
 def create_user(login, password, groups):
     """create a cubicweb user"""
     from cubicweb.server.utils import crypt_password
-    user = Entity('EUser', name=login)
+    user = Entity('CWUser', name=login)
     user['s_login'] = unicode(login)
     user['s_upassword'] = crypt_password(password)
     set_user_groups(user, groups)
@@ -39,7 +39,7 @@
 def create_groups():
     """create initial cubicweb groups"""
     for groupname in ('managers', 'users', 'guests'):
-        group = Entity('EGroup', name='key_' + groupname)
+        group = Entity('CWGroup', name='key_' + groupname)
         group['s_name'] = unicode(groupname)
         Put(group)
         _GROUP_CACHE[groupname] = group
@@ -74,23 +74,23 @@
             gaeentity[dsrelation] = None
     
 def fix_entities(schema):
-    for etype in ('EUser', 'EGroup'):
+    for etype in ('CWUser', 'CWGroup'):
         eschema = schema.eschema(etype)
         for gaeentity in Query(etype).Run():
             init_relations(gaeentity, eschema)
-            # XXX o_is on EEType entity
-            gaeentity['s_is'] = Key.from_path('EEType', 'key_' + etype, parent=None)
+            # XXX o_is on CWEType entity
+            gaeentity['s_is'] = Key.from_path('CWEType', 'key_' + etype, parent=None)
             Put(gaeentity)
     
 def init_persistent_schema(ssession, schema):
     execute = ssession.unsafe_execute
-    rql = ('INSERT EEType X: X name %(name)s, X description %(descr)s,'
+    rql = ('INSERT CWEType X: X name %(name)s, X description %(descr)s,'
            'X final FALSE, X meta %(meta)s')
-    eschema = schema.eschema('EEType')
-    execute(rql, {'name': u'EEType', 'descr': unicode(eschema.description),
+    eschema = schema.eschema('CWEType')
+    execute(rql, {'name': u'CWEType', 'descr': unicode(eschema.description),
                   'meta': eschema.meta})
     for eschema in schema.entities():
-        if eschema.is_final() or eschema == 'EEType':
+        if eschema.is_final() or eschema == 'CWEType':
             continue
         execute(rql, {'name': unicode(eschema), 'meta': eschema.meta,
                       'descr': unicode(eschema.description)})
@@ -98,11 +98,11 @@
 def insert_versions(ssession, config):
     execute = ssession.unsafe_execute
     # insert versions
-    execute('INSERT EProperty X: X pkey %(pk)s, X value%(v)s',
+    execute('INSERT CWProperty X: X pkey %(pk)s, X value%(v)s',
             {'pk': u'system.version.cubicweb',
              'v': unicode(config.cubicweb_version())})
     for cube in config.cubes():
-        execute('INSERT EProperty X: X pkey %(pk)s, X value%(v)s',
+        execute('INSERT CWProperty X: X pkey %(pk)s, X value%(v)s',
                 {'pk': u'system.version.%s' % cube,
                  'v': unicode(config.cube_version(cube))})
     
--- a/goa/dbmyams.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/dbmyams.py	Fri Apr 24 19:46:47 2009 +0200
@@ -179,7 +179,7 @@
         for obj in vars(appschema).values():
             if isinstance(obj, type) and issubclass(obj, goadb.Model) and obj.__module__ == appschema.__name__:
                 loader.load_dbmodel(obj.__name__, goadb.extract_dbmodel(obj))
-    for erschema in ('EGroup', 'EEType', 'ERType', 'RQLExpression',
+    for erschema in ('CWGroup', 'CWEType', 'CWRType', 'RQLExpression',
                      'is_', 'is_instance_of',
                      'read_permission', 'add_permission',
                      'delete_permission', 'update_permission'):
@@ -194,18 +194,18 @@
     if extrahook is not None:
         extrahook(loader)
     if config['use-google-auth']:
-        loader.defined['EUser'].remove_relation('upassword')
-        loader.defined['EUser'].permissions['add'] = ()
-        loader.defined['EUser'].permissions['delete'] = ()
-    for etype in ('EGroup', 'RQLExpression'):
+        loader.defined['CWUser'].remove_relation('upassword')
+        loader.defined['CWUser'].permissions['add'] = ()
+        loader.defined['CWUser'].permissions['delete'] = ()
+    for etype in ('CWGroup', 'RQLExpression'):
         read_perm_rel = loader.defined[etype].get_relations('read_permission').next()
         read_perm_rel.cardinality = '**'
-    # XXX not yet ready for EUser workflow
-    loader.defined['EUser'].remove_relation('in_state')
-    loader.defined['EUser'].remove_relation('wf_info_for')
-    # remove RQLConstraint('NOT O name "owners"') on EUser in_group EGroup
+    # XXX not yet ready for CWUser workflow
+    loader.defined['CWUser'].remove_relation('in_state')
+    loader.defined['CWUser'].remove_relation('wf_info_for')
+    # remove RQLConstraint('NOT O name "owners"') on CWUser in_group CWGroup
     # since "owners" group is not persistent with gae
-    loader.defined['EUser'].get_relations('in_group').next().constraints = []
+    loader.defined['CWUser'].get_relations('in_group').next().constraints = []
     # return the full schema including the cubes' schema
     for ertype in loader.defined.values():
         if getattr(ertype, 'inlined', False):
--- a/goa/doc/devmanual_fr/chap_autres_composants_ui.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/doc/devmanual_fr/chap_autres_composants_ui.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -9,6 +9,6 @@
 ---------------------
 XXXFILLME
 
-EProperty
+CWProperty
 ---------
 XXXFILLME
--- a/goa/doc/devmanual_fr/chap_bases_framework_erudi.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/doc/devmanual_fr/chap_bases_framework_erudi.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -127,7 +127,7 @@
     réponse 
   * `cursor()` retourne un curseur RQL sur la session
   * `execute(*args, **kwargs)`, raccourci vers .cursor().execute()
-  * `property_value(key)`, gestion des propriétés (`EProperty`)
+  * `property_value(key)`, gestion des propriétés (`CWProperty`)
   * le dictionaire `data` pour stocker des données pour partager de
     l'information entre les composants *durant l'éxécution de la requête*.
 
--- a/goa/doc/devmanual_fr/chap_configuration_instance.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/doc/devmanual_fr/chap_configuration_instance.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -27,7 +27,7 @@
 
 :`main.anonymous-user`, `main.anonymous-password`:
    login et mot de passe à utiliser pour se connecter au serveur RQL lors des
-   connexions HTTP anonymes. Il faut que le compte EUser associé existe.
+   connexions HTTP anonymes. Il faut que le compte CWUser associé existe.
 
 :`main.base-url`:
    url de base du site, à utiliser pour générer les urls des pages web
@@ -143,7 +143,7 @@
 
 Configuration Eproperties
 -------------------------
-D'autres paramètres de configuration sont sous la forme d'entités `EProperty`
+D'autres paramètres de configuration sont sous la forme d'entités `CWProperty`
 dans la base de données. Il faut donc les éditer via l'interface web ou par des
 requêtes rql.
 
--- a/goa/doc/devmanual_fr/sect_definition_schema.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/doc/devmanual_fr/sect_definition_schema.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -27,8 +27,8 @@
   - `eid` (`Int`)
   - `creation_date` (`Datetime`)
   - `modification_date` (`Datetime`)
-  - `owned_by` (`EUser`)
-  - `is` (`EEType`)
+  - `owned_by` (`CWUser`)
+  - `is` (`CWEType`)
 
 * il est également possible de définir des relations dont le type d'entité est
   l'objet en utilisant `ObjectRelation` plutôt que `SubjectRelation`
@@ -158,7 +158,7 @@
     inlined = True
     cardinality = '?*'
     subject = '*'
-    object = 'EUser'
+    object = 'CWUser'
 
 En plus des permissions, les propriétés propres aux types de relation (et donc
 partagés par toutes les définitions de relation de ce type) sont :
@@ -254,16 +254,16 @@
     'add'/'read' son pris en considération
 
 
-En plus de cela, le type d'entité `EPermission` de la librairie standard permet
+En plus de cela, le type d'entité `CWPermission` de la librairie standard permet
 de construire des modèles de sécurités très complexes et dynamiques. Le schéma
 de ce type d'entité est le suivant : ::
 
 
-    class EPermission(MetaEntityType):
+    class CWPermission(MetaEntityType):
 	"""entity type that may be used to construct some advanced security configuration
 	"""
 	name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
-	require_group = SubjectRelation('EGroup', cardinality='+*',
+	require_group = SubjectRelation('CWGroup', cardinality='+*',
 					description=_('groups to which the permission is granted'))
 	require_state = SubjectRelation('State',
 				    description=_("entity'state in which the permission is applyable"))
@@ -302,7 +302,7 @@
 		       }
 	inlined = True
 
-Cette configuration suppose indique qu'une entité `EPermission` de nom
+Cette configuration suppose indique qu'une entité `CWPermission` de nom
 "add_version" peut-être associée à un projet et donner le droit de créer des
 versions sur ce projet à des groupes spécifiques. Il est important de noter les
 points suivants :
@@ -310,7 +310,7 @@
 * dans ce cas il faut protéger à la fois le type d'entité "Version" et la
   relation liant une version à un projet ("version_of")
 
-* du fait de la généricité du type d'entité `EPermission`, il faut effectuer
+* du fait de la généricité du type d'entité `CWPermission`, il faut effectuer
   l'unification avec les groupes et / ou les états le cas échéant dans
   l'expression ("U in_group G, P require_group G" dans l'exemple ci-dessus)
 
--- a/goa/doc/devmanual_fr/sect_stdlib_schemas.txt	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/doc/devmanual_fr/sect_stdlib_schemas.txt	Fri Apr 24 19:46:47 2009 +0200
@@ -9,10 +9,10 @@
 Schémas "systèmes"
 ``````````````````
 
-* `EUser`, utilisateurs du système
-* `EGroup`, groupes d'utilisateurs
-* `EEType`, types d'entité
-* `ERType`, types de relation
+* `CWUser`, utilisateurs du système
+* `CWGroup`, groupes d'utilisateurs
+* `CWEType`, types d'entité
+* `CWRType`, types de relation
 
 * `State`, état d'un workflow
 * `Transition`, transition d'un workflow
@@ -21,8 +21,8 @@
 * `EmailAddress`, adresse électronique, utilisé par le système de notification
   pour les utilisateurs et par d'autres schéma optionnels
 
-* `EProperty`, utilisé pour configurer l'application
-* `EPermission`, utilisé pour configurer la sécurité de l'application
+* `CWProperty`, utilisé pour configurer l'application
+* `CWPermission`, utilisé pour configurer la sécurité de l'application
 
 * `Card`, fiche documentaire générique
 * `Bookmark`, un type d'entité utilisé pour permetter à un utilisateur de
--- a/goa/gaesource.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/gaesource.py	Fri Apr 24 19:46:47 2009 +0200
@@ -36,11 +36,11 @@
             pass
         else:
             entity.clear_related_cache(rtype, role)
-    if gaesubject.kind() == 'EUser':
+    if gaesubject.kind() == 'CWUser':
         for asession in session.repo._sessions.itervalues():
             if asession.user.eid == subject:
                 asession.user.clear_related_cache(rtype, 'subject')
-    if gaeobject.kind() == 'EUser':
+    if gaeobject.kind() == 'CWUser':
         for asession in session.repo._sessions.itervalues():
             if asession.user.eid == object:
                 asession.user.clear_related_cache(rtype, 'object')
@@ -114,9 +114,9 @@
 class GAESource(AbstractSource):
     """adapter for a system source on top of google appengine datastore"""
 
-    passwd_rql = "Any P WHERE X is EUser, X login %(login)s, X upassword P"
-    auth_rql = "Any X WHERE X is EUser, X login %(login)s, X upassword %(pwd)s"
-    _sols = ({'X': 'EUser', 'P': 'Password'},)
+    passwd_rql = "Any P WHERE X is CWUser, X login %(login)s, X upassword P"
+    auth_rql = "Any X WHERE X is CWUser, X login %(login)s, X upassword %(pwd)s"
+    _sols = ({'X': 'CWUser', 'P': 'Password'},)
     
     options = ()
     
@@ -157,7 +157,7 @@
         """set the application'schema"""
         self.interpreter = RQLInterpreter(schema)
         self.schema = schema
-        if 'EUser' in schema and not self.repo.config['use-google-auth']:
+        if 'CWUser' in schema and not self.repo.config['use-google-auth']:
             # rql syntax trees used to authenticate users
             self._passwd_rqlst = self.compile_rql(self.passwd_rql)
             self._auth_rqlst = self.compile_rql(self.auth_rql)
@@ -185,7 +185,7 @@
         # XXX http://code.google.com/appengine/docs/users/userobjects.html
         # use a reference property to automatically work with email address
         # changes after the propagation feature is implemented
-        key = Key.from_path('EUser', 'key_' + login, parent=None)
+        key = Key.from_path('CWUser', 'key_' + login, parent=None)
         try:
             euser = session.datastore_get(key)
             # XXX fix user. Required until we find a better way to fix broken records
@@ -195,14 +195,14 @@
             return str(key)
         except datastore_errors.EntityNotFoundError:
             # create a record for this user
-            euser = Entity('EUser', name='key_' + login)
+            euser = Entity('CWUser', name='key_' + login)
             euser['s_login'] = login
             _init_groups(guser, euser)
             Put(euser)
             return str(euser.key())
         
     def authenticate_local(self, session, login, password):
-        """return EUser eid for the given login/password if this account is
+        """return CWUser eid for the given login/password if this account is
         defined in this source, else raise `AuthenticationError`
 
         two queries are needed since passwords are stored crypted, so we have
@@ -249,7 +249,7 @@
         """replace an entity in the source"""
         gaeentity = entity.to_gae_model()
         _mark_modified(session, entity.to_gae_model())
-        if gaeentity.kind() == 'EUser':
+        if gaeentity.kind() == 'CWUser':
             for asession in self.repo._sessions.itervalues():
                 if asession.user.eid == entity.eid:
                     asession.user.update(dict(gaeentity))
--- a/goa/goactl.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/goactl.py	Fri Apr 24 19:46:47 2009 +0200
@@ -65,7 +65,6 @@
     'common/migration.py',
     'common/mixins.py',
     'common/mttransforms.py',
-    'common/registerers.py',
     'common/uilib.py',
 
     'ext/html4zope.py',
--- a/goa/test/unittest_db.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/test/unittest_db.py	Fri Apr 24 19:46:47 2009 +0200
@@ -18,20 +18,20 @@
     MODEL_CLASSES = (Blog,)
 
     def test_set_none_relation(self):
-        eprop = self.add_entity('EProperty', pkey=u'ui.language', value=u'en')
+        eprop = self.add_entity('CWProperty', pkey=u'ui.language', value=u'en')
         self.failUnless('s_for_user' in eprop._dbmodel)
         self.assertEquals(eprop._dbmodel['s_for_user'], None)
 
     def test_euser_key(self):
-        euser = self.add_entity('EUser', login=u'toto', upassword='toto')
+        euser = self.add_entity('CWUser', login=u'toto', upassword='toto')
         self.assertEquals(euser.key().name(), 'key_toto')
         
     def test_egroup_key(self):
-        egroup = self.add_entity('EGroup', name=u'toto')
+        egroup = self.add_entity('CWGroup', name=u'toto')
         self.assertEquals(egroup.key().name(), 'key_toto')
 
     def test_password_encryption(self):
-        euser = self.add_entity('EUser', login=u'toto', upassword='toto')
+        euser = self.add_entity('CWUser', login=u'toto', upassword='toto')
         self.failUnless(euser.upassword != 'toto', euser.upassword)
         self.assertEquals(crypt_password('toto', euser.upassword[:2]), euser.upassword)
 
--- a/goa/test/unittest_editcontroller.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/test/unittest_editcontroller.py	Fri Apr 24 19:46:47 2009 +0200
@@ -8,7 +8,7 @@
 from cubicweb.web import INTERNAL_FIELD_VALUE, Redirect
 
 from cubicweb.goa.goaconfig import GAEConfiguration
-from cubicweb.entities.authobjs import EUser
+from cubicweb.entities.authobjs import CWUser
 
 
 class EditControllerTC(GAEBasedTC):
@@ -73,7 +73,7 @@
     def test_validation_unique(self):
         """test creation of two linked entities"""        
         user = self.user
-        self.req.form = {'eid': 'X', '__type:X': 'EUser',
+        self.req.form = {'eid': 'X', '__type:X': 'CWUser',
                          'login:X': self.user.login, 'edits-login:X': u'', 
                          'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'', 
                          }
@@ -84,13 +84,13 @@
         """checking that a manager user can edit itself"""
         self.skip('missing actual gae support, retry latter')
         user = self.user
-        basegroups = [str(eid) for eid, in self.req.execute('EGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
-        groupeids = [eid for eid, in self.req.execute('EGroup G WHERE G name in ("managers", "users")')]
+        basegroups = [str(eid) for eid, in self.req.execute('CWGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
+        groupeids = [eid for eid, in self.req.execute('CWGroup G WHERE G name in ("managers", "users")')]
         groups = [str(eid) for eid in groupeids]
         stateeid = [eid for eid, in self.req.execute('State S WHERE S name "activated"')][0]
         self.req.form = {
             'eid':       user.eid,
-            '__type:'+user.eid:    'EUser',
+            '__type:'+user.eid:    'CWUser',
             'login:'+user.eid:     unicode(user.login),
             'firstname:'+user.eid: u'Th\xe9nault',
             'surname:'+user.eid:   u'Sylvain',
@@ -115,10 +115,10 @@
         user = self.create_user('user')
         cnx = self.login('user')
         req = self.request()
-        #self.assertEquals(self.ctrl.schema['EUser']._groups['read'],
+        #self.assertEquals(self.ctrl.schema['CWUser']._groups['read'],
         #                  ('managers', 'users'))
         req.form = {
-            'eid': user.eid, '__type:'+user.eid: 'EUser',
+            'eid': user.eid, '__type:'+user.eid: 'CWUser',
             '__maineid' : str(user.eid),
             'upassword:'+user.eid: 'tournicoton',
             'upassword-confirm:'+user.eid: 'tournicoton',
@@ -134,10 +134,10 @@
         relations (meaning no changes)
         """
         user = self.user
-        groupeids = [eid for eid, in self.req.execute('EGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
+        groupeids = [eid for eid, in self.req.execute('CWGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
         self.req.form = {
             'eid':       user.eid,
-            '__type:'+user.eid:    'EUser',
+            '__type:'+user.eid:    'CWUser',
             'login:'+user.eid:     unicode(user.login),
             'firstname:'+user.eid: u'Th\xe9nault',
             'surname:'+user.eid:   u'Sylvain',
@@ -158,10 +158,10 @@
         
         
     def test_create_multiple_linked(self):
-        gueid = self.req.execute('EGroup G WHERE G name "users"')[0][0]
+        gueid = self.req.execute('CWGroup G WHERE G name "users"')[0][0]
         self.req.form = {'eid': ['X', 'Y'],
                          
-                         '__type:X': 'EUser',
+                         '__type:X': 'CWUser',
                          '__maineid' : 'X',
                          'login:X': u'adim', 'edits-login:X': u'', 
                          'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'', 
@@ -184,7 +184,7 @@
     def test_edit_multiple_linked(self):
         peid = self.create_user('adim').eid
         self.req.form = {'eid': [peid, 'Y'],
-                         '__type:%s'%peid: 'EUser',
+                         '__type:%s'%peid: 'CWUser',
                          'surname:%s'%peid: u'Di Masci', 'edits-surname:%s'%peid: '',
                          
                          '__type:Y': 'EmailAddress',
@@ -203,7 +203,7 @@
         
         emaileid = email.eid
         self.req.form = {'eid': [peid, emaileid],
-                         '__type:%s'%peid: 'EUser',
+                         '__type:%s'%peid: 'CWUser',
                          'surname:%s'%peid: u'Di Masci', 'edits-surname:%s'%peid: 'Di Masci',
                          '__type:%s'%emaileid: 'EmailAddress',
                          'address:%s'%emaileid: u'adim@logilab.fr', 'edits-address:%s'%emaileid: 'dima@logilab.fr',
@@ -226,13 +226,13 @@
         """        
         user = self.user
         self.req.form = {'__cloned_eid:X': user.eid,
-                         'eid': 'X', '__type:X': 'EUser',
+                         'eid': 'X', '__type:X': 'CWUser',
                          'login:X': u'toto', 'edits-login:X': u'', 
                          'upassword:X': u'toto', 'edits-upassword:X': u'', 
                          }
         self.assertRaises(ValidationError, self.publish, self.req)
         self.req.form = {'__cloned_eid:X': user.eid,
-                         'eid': 'X', '__type:X': 'EUser',
+                         'eid': 'X', '__type:X': 'CWUser',
                          'login:X': u'toto', 'edits-login:X': u'', 
                          'upassword:X': u'toto', 'upassword-confirm:X': u'tutu', 'edits-upassword:X': u'', 
                          }
@@ -241,7 +241,7 @@
 
     def test_req_pending_insert(self):
         """make sure req's pending insertions are taken into account"""
-        tmpgroup = self.add_entity('EGroup', name=u"test")
+        tmpgroup = self.add_entity('CWGroup', name=u"test")
         user = self.user
         self.req.set_session_data('pending_insert', set([(user.eid, 'in_group', tmpgroup.eid)]))
         path, params = self.expect_redirect_publish()
@@ -254,7 +254,7 @@
     def test_req_pending_delete(self):
         """make sure req's pending deletions are taken into account"""
         user = self.user
-        groupeid = self.req.execute('INSERT EGroup G: G name "test", U in_group G WHERE U eid %(x)s',
+        groupeid = self.req.execute('INSERT CWGroup G: G name "test", U in_group G WHERE U eid %(x)s',
                                     {'x': user.eid})[0][0]
         usergroups = [gname for gname, in
                       self.req.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
@@ -273,13 +273,13 @@
         def custom_login_edit(self, formparams, value, relations):
             formparams['login'] = value.upper()
             relations.append('X login %(login)s')
-        EUser.custom_login_edit = custom_login_edit
+        CWUser.custom_login_edit = custom_login_edit
         try:
             user = self.user
             eid = repr(user.eid)
             self.req.form = {
                 'eid': eid,
-                '__type:'+eid:  'EUser',
+                '__type:'+eid:  'CWUser',
                 'login:'+eid: u'foo',
                 'edits-login:'+eid:  unicode(user.login),
                 }
@@ -287,7 +287,7 @@
             rset = self.req.execute('Any L WHERE X eid %(x)s, X login L', {'x': user.eid}, 'x')
             self.assertEquals(rset[0][0], 'FOO')
         finally:
-            del EUser.custom_login_edit
+            del CWUser.custom_login_edit
         
     def test_redirect_apply_button(self):
         redirectrql = rql_for_eid(4012) # whatever
@@ -358,10 +358,10 @@
         
 
     def test_nonregr_multiple_empty_email_addr(self):
-        gueid = self.req.execute('EGroup G WHERE G name "users"')[0][0]
+        gueid = self.req.execute('CWGroup G WHERE G name "users"')[0][0]
         self.req.form = {'eid': ['X', 'Y'],
                          
-                         '__type:X': 'EUser',
+                         '__type:X': 'CWUser',
                          'login:X': u'adim', 'edits-login:X': u'', 
                          'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'', 
                          'in_group:X': gueid, 'edits-in_group:X': INTERNAL_FIELD_VALUE, 
@@ -385,7 +385,7 @@
             self.req.execute('SET P use_email E, P primary_email E WHERE P eid %(p)s, E eid %(e)s',
                          {'p' : p.eid, 'e' : e.eid})
             self.req.form = {'__cloned_eid:X': p.eid,
-                             'eid': 'X', '__type:X': 'EUser',
+                             'eid': 'X', '__type:X': 'CWUser',
                              'login': u'dodo', 'edits-login': u'dodo', 
                              'surname:X': u'Boom', 'edits-surname:X': u'',
                              '__errorurl' : "whatever but required",
@@ -400,7 +400,7 @@
                 self.req.form['rql'] = 'Any X WHERE X eid %s' % p.eid
                 self.req.form['vid'] = 'copy'
                 self.env.app.publish('view', self.req)
-            rset = self.req.execute('EUser P WHERE P surname "Boom"')
+            rset = self.req.execute('CWUser P WHERE P surname "Boom"')
             self.assertEquals(len(rset), 0)
         finally:
             p.__class__.skip_copy_for = old_skips
--- a/goa/test/unittest_metadata.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/test/unittest_metadata.py	Fri Apr 24 19:46:47 2009 +0200
@@ -26,7 +26,7 @@
         GAEBasedTC.setUp(self)
         self.req = self.request()
         self.a = self.add_entity('Article')
-        self.p = self.add_entity('EProperty', pkey=u'ui.language', value=u'en')
+        self.p = self.add_entity('CWProperty', pkey=u'ui.language', value=u'en')
         self.session.commit()
         
     def _test_timestamp(self, entity, attr, sleep=0.1):
@@ -96,9 +96,9 @@
         en = self.execute('Any EN WHERE E name EN, X is E, X eid %(x)s', {'x': self.a.eid}, 'x')[0][0]
         self.assertEquals(en, 'Article')
         en = self.execute('Any EN WHERE E name EN, X is E, X eid %(x)s', {'x': self.p.eid}, 'x')[0][0]
-        self.assertEquals(en, 'EProperty') 
+        self.assertEquals(en, 'CWProperty') 
         en = self.execute('Any EN WHERE E name EN, X is E, X eid %(x)s', {'x': self.req.user.eid}, 'x')[0][0]
-        self.assertEquals(en, 'EUser')
+        self.assertEquals(en, 'CWUser')
 
         
 if __name__ == '__main__':
--- a/goa/test/unittest_rql.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/test/unittest_rql.py	Fri Apr 24 19:46:47 2009 +0200
@@ -566,13 +566,13 @@
         self.assertEquals(rset.rows, [[article2.eid]])
         
     def test_8_not_relation_final_1(self):
-        rset = self.req.execute('Any G WHERE G is EGroup, NOT G name "guests"')
+        rset = self.req.execute('Any G WHERE G is CWGroup, NOT G name "guests"')
         self._check_rset_size(rset, 2, 1)
         self.assertUnorderedIterableEquals([g.name for g in rset.entities()],
                                            ['users', 'managers'])        
         
     def test_8_not_relation_final_2(self):
-        rset = self.req.execute('Any GN WHERE G is EGroup, NOT G name "guests", G name GN')
+        rset = self.req.execute('Any GN WHERE G is CWGroup, NOT G name "guests", G name GN')
         self._check_rset_size(rset, 2, 1)
         self.assertUnorderedIterableEquals([gn for gn, in rset.rows],
                                            ['users', 'managers'])
--- a/goa/test/unittest_schema.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/test/unittest_schema.py	Fri Apr 24 19:46:47 2009 +0200
@@ -21,8 +21,8 @@
                              set(('Boolean', 'Bytes', 'Date', 'Datetime', 'Float',
                               'Decimal',
                               'Int', 'Interval', 'Password', 'String', 'Time',
-                              'EEType', 'EGroup', 'EPermission', 'EProperty', 'ERType',
-                              'EUser', 'EmailAddress',
+                              'CWEType', 'CWGroup', 'CWPermission', 'CWProperty', 'CWRType',
+                              'CWUser', 'EmailAddress',
                               'RQLExpression', 'State', 'Transition', 'TrInfo',
                               'Article', 'Blog', 'YamsEntity')))
         self.assertSetEquals(set(str(e) for e in schema.relations()),
@@ -66,7 +66,7 @@
                              ('ambiguous_relation', 'talks_about', 'identity'))
 
     def test_yams_imported(self):
-        eschema = self.schema['EProperty']
+        eschema = self.schema['CWProperty']
         # only relations defined in the class are actually ordered
         orels = [str(e) for e in eschema.ordered_relations()]
         orels, others = orels[:3], orels[3:]
@@ -87,7 +87,7 @@
                              ('Blog', 'Article'))
 
     def test_euser(self):
-        eschema = self.schema['EUser']
+        eschema = self.schema['CWUser']
         # XXX pretend to have some relations it has not
         self.assertEquals([str(e) for e in eschema.ordered_relations()],
                           ['login', 'firstname', 'surname', 'last_login_time',
--- a/goa/testlib.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/goa/testlib.py	Fri Apr 24 19:46:47 2009 +0200
@@ -177,7 +177,7 @@
         
     def create_user(self, login, groups=('users',), req=None):
         assert not self.config['use-google-auth']
-        user = self.add_entity('EUser', upassword=str(login), login=unicode(login))
+        user = self.add_entity('CWUser', upassword=str(login), login=unicode(login))
         cu = self.session.cursor()
         cu.execute('SET X in_group G WHERE X eid %%(x)s, G name IN(%s)'
                     % ','.join(repr(g) for g in groups),
--- a/i18n/en.po	Wed Apr 22 09:45:54 2009 +0200
+++ b/i18n/en.po	Fri Apr 24 19:46:47 2009 +0200
@@ -227,70 +227,70 @@
 msgid "Do you want to delete the following element(s) ?"
 msgstr ""
 
-msgid "ECache"
-msgstr ""
-
-msgid "ECache_plural"
-msgstr ""
-
-msgid "EConstraint"
+msgid "CWCache"
+msgstr ""
+
+msgid "CWCache_plural"
+msgstr ""
+
+msgid "CWConstraint"
 msgstr "Constraint"
 
-msgid "EConstraintType"
+msgid "CWConstraintType"
 msgstr "Constraint type"
 
-msgid "EConstraintType_plural"
+msgid "CWConstraintType_plural"
 msgstr "Constraint types"
 
-msgid "EConstraint_plural"
+msgid "CWConstraint_plural"
 msgstr "Constraints"
 
-msgid "EEType"
+msgid "CWEType"
 msgstr "Entity type"
 
-msgid "EEType_plural"
+msgid "CWEType_plural"
 msgstr "Entity types"
 
-msgid "EFRDef"
+msgid "CWAttribute"
 msgstr "Attribute"
 
-msgid "EFRDef_plural"
+msgid "CWAttribute_plural"
 msgstr "Attributes"
 
-msgid "EGroup"
+msgid "CWGroup"
 msgstr "Group"
 
-msgid "EGroup_plural"
+msgid "CWGroup_plural"
 msgstr "Groups"
 
-msgid "ENFRDef"
+msgid "CWRelation"
 msgstr "Relation"
 
-msgid "ENFRDef_plural"
+msgid "CWRelation_plural"
 msgstr "Relations"
 
-msgid "EPermission"
+msgid "CWPermission"
 msgstr "Permission"
 
-msgid "EPermission_plural"
+msgid "CWPermission_plural"
 msgstr "Permissions"
 
-msgid "EProperty"
+msgid "CWProperty"
 msgstr "Property"
 
-msgid "EProperty_plural"
+msgid "CWProperty_plural"
 msgstr "Properties"
 
-msgid "ERType"
+msgid "CWRType"
 msgstr "Relation type"
 
-msgid "ERType_plural"
+msgid "CWRType_plural"
 msgstr "Relation types"
 
-msgid "EUser"
+msgid "CWUser"
 msgstr "User"
 
-msgid "EUser_plural"
+msgid "CWUser_plural"
 msgstr "Users"
 
 msgid "Email body: "
@@ -335,37 +335,37 @@
 msgid "New Card"
 msgstr "New card"
 
-msgid "New ECache"
-msgstr ""
-
-msgid "New EConstraint"
+msgid "New CWCache"
+msgstr ""
+
+msgid "New CWConstraint"
 msgstr "New constraint"
 
-msgid "New EConstraintType"
+msgid "New CWConstraintType"
 msgstr "New constraint type"
 
-msgid "New EEType"
+msgid "New CWEType"
 msgstr "New entity type"
 
-msgid "New EFRDef"
+msgid "New CWAttribute"
 msgstr "New attribute"
 
-msgid "New EGroup"
+msgid "New CWGroup"
 msgstr "New group"
 
-msgid "New ENFRDef"
+msgid "New CWRelation"
 msgstr "New relation"
 
-msgid "New EPermission"
+msgid "New CWPermission"
 msgstr "New permission"
 
-msgid "New EProperty"
+msgid "New CWProperty"
 msgstr "New property"
 
-msgid "New ERType"
+msgid "New CWRType"
 msgstr "New relation type"
 
-msgid "New EUser"
+msgid "New CWUser"
 msgstr "New user"
 
 msgid "New EmailAddress"
@@ -474,37 +474,37 @@
 msgid "This Card"
 msgstr "This card"
 
-msgid "This ECache"
-msgstr ""
-
-msgid "This EConstraint"
+msgid "This CWCache"
+msgstr ""
+
+msgid "This CWConstraint"
 msgstr "This constraint"
 
-msgid "This EConstraintType"
+msgid "This CWConstraintType"
 msgstr "This constraint type"
 
-msgid "This EEType"
+msgid "This CWEType"
 msgstr "This entity type"
 
-msgid "This EFRDef"
+msgid "This CWAttribute"
 msgstr "This attribute"
 
-msgid "This EGroup"
+msgid "This CWGroup"
 msgstr "This group"
 
-msgid "This ENFRDef"
+msgid "This CWRelation"
 msgstr "This relation"
 
-msgid "This EPermission"
+msgid "This CWPermission"
 msgstr "This permission"
 
-msgid "This EProperty"
+msgid "This CWProperty"
 msgstr "This property"
 
-msgid "This ERType"
+msgid "This CWRType"
 msgstr "This relation type"
 
-msgid "This EUser"
+msgid "This CWUser"
 msgstr "This user"
 
 msgid "This EmailAddress"
@@ -646,6 +646,12 @@
 msgid "actions_delete_description"
 msgstr ""
 
+msgid "actions_download_as_owl"
+msgstr ""
+
+msgid "actions_download_as_owl_description"
+msgstr ""
+
 msgid "actions_edit"
 msgstr "modify"
 
@@ -745,49 +751,49 @@
 msgid "add"
 msgstr ""
 
-msgid "add Bookmark bookmarked_by EUser object"
+msgid "add Bookmark bookmarked_by CWUser object"
 msgstr "bookmark"
 
-msgid "add EEType add_permission RQLExpression subject"
+msgid "add CWEType add_permission RQLExpression subject"
 msgstr "rql expression for the add permission"
 
-msgid "add EEType delete_permission RQLExpression subject"
+msgid "add CWEType delete_permission RQLExpression subject"
 msgstr "rql expression for the delete permission"
 
-msgid "add EEType read_permission RQLExpression subject"
+msgid "add CWEType read_permission RQLExpression subject"
 msgstr "rql expression for the read permission"
 
-msgid "add EEType update_permission RQLExpression subject"
+msgid "add CWEType update_permission RQLExpression subject"
 msgstr "rql expression for the update permission"
 
-msgid "add EFRDef constrained_by EConstraint subject"
+msgid "add CWAttribute constrained_by CWConstraint subject"
 msgstr "constraint"
 
-msgid "add EFRDef relation_type ERType object"
+msgid "add CWAttribute relation_type CWRType object"
 msgstr "attribute definition"
 
-msgid "add ENFRDef constrained_by EConstraint subject"
+msgid "add CWRelation constrained_by CWConstraint subject"
 msgstr "constraint"
 
-msgid "add ENFRDef relation_type ERType object"
+msgid "add CWRelation relation_type CWRType object"
 msgstr "relation definition"
 
-msgid "add EProperty for_user EUser object"
+msgid "add CWProperty for_user CWUser object"
 msgstr "property"
 
-msgid "add ERType add_permission RQLExpression subject"
+msgid "add CWRType add_permission RQLExpression subject"
 msgstr "rql expression for the add permission"
 
-msgid "add ERType delete_permission RQLExpression subject"
+msgid "add CWRType delete_permission RQLExpression subject"
 msgstr "rql expression for the delete permission"
 
-msgid "add ERType read_permission RQLExpression subject"
+msgid "add CWRType read_permission RQLExpression subject"
 msgstr "rql expression for the read permission"
 
-msgid "add EUser in_group EGroup object"
+msgid "add CWUser in_group CWGroup object"
 msgstr "user"
 
-msgid "add EUser use_email EmailAddress subject"
+msgid "add CWUser use_email EmailAddress subject"
 msgstr "email address"
 
 msgid "add State allowed_transition Transition object"
@@ -796,7 +802,7 @@
 msgid "add State allowed_transition Transition subject"
 msgstr "allowed transition"
 
-msgid "add State state_of EEType object"
+msgid "add State state_of CWEType object"
 msgstr "state"
 
 msgid "add Transition condition RQLExpression subject"
@@ -808,7 +814,7 @@
 msgid "add Transition destination_state State subject"
 msgstr "destination state"
 
-msgid "add Transition transition_of EEType object"
+msgid "add Transition transition_of CWEType object"
 msgstr "transition"
 
 msgid "add a Bookmark"
@@ -817,37 +823,37 @@
 msgid "add a Card"
 msgstr "add a card"
 
-msgid "add a ECache"
-msgstr ""
-
-msgid "add a EConstraint"
+msgid "add a CWCache"
+msgstr ""
+
+msgid "add a CWConstraint"
 msgstr "add a constraint"
 
-msgid "add a EConstraintType"
+msgid "add a CWConstraintType"
 msgstr "add a constraint type"
 
-msgid "add a EEType"
+msgid "add a CWEType"
 msgstr "add an entity type"
 
-msgid "add a EFRDef"
+msgid "add a CWAttribute"
 msgstr "add an attribute"
 
-msgid "add a EGroup"
+msgid "add a CWGroup"
 msgstr "add a group"
 
-msgid "add a ENFRDef"
+msgid "add a CWRelation"
 msgstr "add a relation"
 
-msgid "add a EPermission"
+msgid "add a CWPermission"
 msgstr "add a permission"
 
-msgid "add a EProperty"
+msgid "add a CWProperty"
 msgstr "add a property"
 
-msgid "add a ERType"
+msgid "add a CWRType"
 msgstr "add a relation type"
 
-msgid "add a EUser"
+msgid "add a CWUser"
 msgstr "add a user"
 
 msgid "add a EmailAddress"
@@ -1342,54 +1348,54 @@
 msgid "created_by_object"
 msgstr "has created"
 
-msgid "creating Bookmark (Bookmark bookmarked_by EUser %(linkto)s)"
+msgid "creating Bookmark (Bookmark bookmarked_by CWUser %(linkto)s)"
 msgstr "creating bookmark for %(linkto)s"
 
-msgid "creating EConstraint (EFRDef %(linkto)s constrained_by EConstraint)"
+msgid "creating CWConstraint (CWAttribute %(linkto)s constrained_by CWConstraint)"
 msgstr "creating constraint for attribute %(linkto)s"
 
-msgid "creating EConstraint (ENFRDef %(linkto)s constrained_by EConstraint)"
+msgid "creating CWConstraint (CWRelation %(linkto)s constrained_by CWConstraint)"
 msgstr "creating constraint for relation %(linkto)s"
 
-msgid "creating EFRDef (EFRDef relation_type ERType %(linkto)s)"
+msgid "creating CWAttribute (CWAttribute relation_type CWRType %(linkto)s)"
 msgstr "creating attribute %(linkto)s"
 
-msgid "creating ENFRDef (ENFRDef relation_type ERType %(linkto)s)"
+msgid "creating CWRelation (CWRelation relation_type CWRType %(linkto)s)"
 msgstr "creating relation %(linkto)s"
 
-msgid "creating EProperty (EProperty for_user EUser %(linkto)s)"
+msgid "creating CWProperty (CWProperty for_user CWUser %(linkto)s)"
 msgstr "creating property for user %(linkto)s"
 
-msgid "creating EUser (EUser in_group EGroup %(linkto)s)"
+msgid "creating CWUser (CWUser in_group CWGroup %(linkto)s)"
 msgstr "creating a new user in group %(linkto)s"
 
-msgid "creating EmailAddress (EUser %(linkto)s use_email EmailAddress)"
+msgid "creating EmailAddress (CWUser %(linkto)s use_email EmailAddress)"
 msgstr "creating email address for user %(linkto)s"
 
-msgid "creating RQLExpression (EEType %(linkto)s add_permission RQLExpression)"
+msgid "creating RQLExpression (CWEType %(linkto)s add_permission RQLExpression)"
 msgstr "creating rql expression for add permission on %(linkto)s"
 
 msgid ""
-"creating RQLExpression (EEType %(linkto)s delete_permission RQLExpression)"
+"creating RQLExpression (CWEType %(linkto)s delete_permission RQLExpression)"
 msgstr "creating rql expression for delete permission on %(linkto)s"
 
 msgid ""
-"creating RQLExpression (EEType %(linkto)s read_permission RQLExpression)"
+"creating RQLExpression (CWEType %(linkto)s read_permission RQLExpression)"
 msgstr "creating rql expression for read permission on %(linkto)s"
 
 msgid ""
-"creating RQLExpression (EEType %(linkto)s update_permission RQLExpression)"
+"creating RQLExpression (CWEType %(linkto)s update_permission RQLExpression)"
 msgstr "creating rql expression for update permission on %(linkto)s"
 
-msgid "creating RQLExpression (ERType %(linkto)s add_permission RQLExpression)"
+msgid "creating RQLExpression (CWRType %(linkto)s add_permission RQLExpression)"
 msgstr "creating rql expression for add permission on relations %(linkto)s"
 
 msgid ""
-"creating RQLExpression (ERType %(linkto)s delete_permission RQLExpression)"
+"creating RQLExpression (CWRType %(linkto)s delete_permission RQLExpression)"
 msgstr "creating rql expression for delete permission on relations %(linkto)s"
 
 msgid ""
-"creating RQLExpression (ERType %(linkto)s read_permission RQLExpression)"
+"creating RQLExpression (CWRType %(linkto)s read_permission RQLExpression)"
 msgstr "creating rql expression for read permission on relations %(linkto)s"
 
 msgid "creating RQLExpression (Transition %(linkto)s condition RQLExpression)"
@@ -1398,7 +1404,7 @@
 msgid "creating State (State allowed_transition Transition %(linkto)s)"
 msgstr "creating a state able to trigger transition %(linkto)s"
 
-msgid "creating State (State state_of EEType %(linkto)s)"
+msgid "creating State (State state_of CWEType %(linkto)s)"
 msgstr "creating state for the %(linkto)s entity type"
 
 msgid "creating State (Transition %(linkto)s destination_state State)"
@@ -1410,7 +1416,7 @@
 msgid "creating Transition (Transition destination_state State %(linkto)s)"
 msgstr "creating transition leading to state %(linkto)s"
 
-msgid "creating Transition (Transition transition_of EEType %(linkto)s)"
+msgid "creating Transition (Transition transition_of CWEType %(linkto)s)"
 msgstr "creating transition for the %(linkto)s entity type"
 
 msgid "creation"
@@ -1586,6 +1592,9 @@
 msgid "download icon"
 msgstr ""
 
+msgid "download schema as owl"
+msgstr ""
+
 msgid "edit bookmarks"
 msgstr ""
 
@@ -2039,6 +2048,11 @@
 msgid "link a transition to one or more entity type"
 msgstr ""
 
+msgid ""
+"link a transition to one or more rql expression allowing to go through this "
+"transition"
+msgstr ""
+
 msgid "link to each item in"
 msgstr ""
 
@@ -2282,6 +2296,9 @@
 msgid "pkey"
 msgstr "key"
 
+msgid "planned_delivery"
+msgstr "planned delivery"
+
 msgid "please correct errors below"
 msgstr ""
 
@@ -2349,37 +2366,37 @@
 msgid "remove this Card"
 msgstr "remove this card"
 
-msgid "remove this ECache"
-msgstr ""
-
-msgid "remove this EConstraint"
+msgid "remove this CWCache"
+msgstr ""
+
+msgid "remove this CWConstraint"
 msgstr "remove this constraint"
 
-msgid "remove this EConstraintType"
+msgid "remove this CWConstraintType"
 msgstr "remove this constraint type"
 
-msgid "remove this EEType"
+msgid "remove this CWEType"
 msgstr "remove this entity type"
 
-msgid "remove this EFRDef"
+msgid "remove this CWAttribute"
 msgstr "remove this attribute"
 
-msgid "remove this EGroup"
+msgid "remove this CWGroup"
 msgstr "remove this group"
 
-msgid "remove this ENFRDef"
+msgid "remove this CWRelation"
 msgstr "remove this relation"
 
-msgid "remove this EPermission"
+msgid "remove this CWPermission"
 msgstr "remove this permission"
 
-msgid "remove this EProperty"
+msgid "remove this CWProperty"
 msgstr "remove this property"
 
-msgid "remove this ERType"
+msgid "remove this CWRType"
 msgstr "remove this relation type"
 
-msgid "remove this EUser"
+msgid "remove this CWUser"
 msgstr "remove this user"
 
 msgid "remove this EmailAddress"
--- a/i18n/es.po	Wed Apr 22 09:45:54 2009 +0200
+++ b/i18n/es.po	Fri Apr 24 19:46:47 2009 +0200
@@ -232,70 +232,70 @@
 msgid "Do you want to delete the following element(s) ?"
 msgstr "Desea suprimir el(los) elemento(s) siguiente(s)"
 
-msgid "ECache"
+msgid "CWCache"
 msgstr "Memoria Cache"
 
-msgid "ECache_plural"
+msgid "CWCache_plural"
 msgstr "Memorias Caches"
 
-msgid "EConstraint"
+msgid "CWConstraint"
 msgstr "Condición"
 
-msgid "EConstraintType"
+msgid "CWConstraintType"
 msgstr "Tipo de condición"
 
-msgid "EConstraintType_plural"
+msgid "CWConstraintType_plural"
 msgstr "Tipos de condición"
 
-msgid "EConstraint_plural"
+msgid "CWConstraint_plural"
 msgstr "Condiciones"
 
-msgid "EEType"
+msgid "CWEType"
 msgstr "Tipo de entidades"
 
-msgid "EEType_plural"
+msgid "CWEType_plural"
 msgstr "Tipos de entidades"
 
-msgid "EFRDef"
+msgid "CWAttribute"
 msgstr "Atributo"
 
-msgid "EFRDef_plural"
+msgid "CWAttribute_plural"
 msgstr "Atributos"
 
-msgid "EGroup"
+msgid "CWGroup"
 msgstr "Groupo"
 
-msgid "EGroup_plural"
+msgid "CWGroup_plural"
 msgstr "Groupos"
 
-msgid "ENFRDef"
+msgid "CWRelation"
 msgstr "Relación"
 
-msgid "ENFRDef_plural"
+msgid "CWRelation_plural"
 msgstr "Relaciones"
 
-msgid "EPermission"
+msgid "CWPermission"
 msgstr "Autorización"
 
-msgid "EPermission_plural"
+msgid "CWPermission_plural"
 msgstr "Autorizaciones"
 
-msgid "EProperty"
+msgid "CWProperty"
 msgstr "Propiedad"
 
-msgid "EProperty_plural"
+msgid "CWProperty_plural"
 msgstr "Propiedades"
 
-msgid "ERType"
+msgid "CWRType"
 msgstr "Tipo de relación"
 
-msgid "ERType_plural"
+msgid "CWRType_plural"
 msgstr "Tipos de relación"
 
-msgid "EUser"
+msgid "CWUser"
 msgstr "Usuario"
 
-msgid "EUser_plural"
+msgid "CWUser_plural"
 msgstr "Usuarios"
 
 msgid "Email body: "
@@ -340,37 +340,37 @@
 msgid "New Card"
 msgstr "Nueva ficha"
 
-msgid "New ECache"
+msgid "New CWCache"
 msgstr "Nueva memoria cache"
 
-msgid "New EConstraint"
+msgid "New CWConstraint"
 msgstr "Nueva condición"
 
-msgid "New EConstraintType"
+msgid "New CWConstraintType"
 msgstr "Nuevo tipo de condición"
 
-msgid "New EEType"
+msgid "New CWEType"
 msgstr "Nuevo tipo de entidad"
 
-msgid "New EFRDef"
+msgid "New CWAttribute"
 msgstr "Nueva definición de relación final"
 
-msgid "New EGroup"
+msgid "New CWGroup"
 msgstr "Nuevo grupo"
 
-msgid "New ENFRDef"
+msgid "New CWRelation"
 msgstr "Nueva definición de relación final"
 
-msgid "New EPermission"
+msgid "New CWPermission"
 msgstr "Nueva autorización"
 
-msgid "New EProperty"
+msgid "New CWProperty"
 msgstr "Nueva Propiedad"
 
-msgid "New ERType"
+msgid "New CWRType"
 msgstr "Nuevo tipo de relación"
 
-msgid "New EUser"
+msgid "New CWUser"
 msgstr "Nuevo usuario"
 
 msgid "New EmailAddress"
@@ -479,37 +479,37 @@
 msgid "This Card"
 msgstr "Esta Ficha"
 
-msgid "This ECache"
+msgid "This CWCache"
 msgstr "Esta Memoria Cache"
 
-msgid "This EConstraint"
+msgid "This CWConstraint"
 msgstr "Esta condición"
 
-msgid "This EConstraintType"
+msgid "This CWConstraintType"
 msgstr "Este tipo de condición"
 
-msgid "This EEType"
+msgid "This CWEType"
 msgstr "Este tipo de Entidad"
 
-msgid "This EFRDef"
+msgid "This CWAttribute"
 msgstr "Esta definición de relación final"
 
-msgid "This EGroup"
+msgid "This CWGroup"
 msgstr "Este grupo"
 
-msgid "This ENFRDef"
+msgid "This CWRelation"
 msgstr "Esta definición de relación no final"
 
-msgid "This EPermission"
+msgid "This CWPermission"
 msgstr "Esta autorización"
 
-msgid "This EProperty"
+msgid "This CWProperty"
 msgstr "Esta propiedad"
 
-msgid "This ERType"
+msgid "This CWRType"
 msgstr "Este tipo de relación"
 
-msgid "This EUser"
+msgid "This CWUser"
 msgstr "Este usuario"
 
 msgid "This EmailAddress"
@@ -667,6 +667,12 @@
 msgid "actions_delete_description"
 msgstr ""
 
+msgid "actions_download_as_owl"
+msgstr ""
+
+msgid "actions_download_as_owl_description"
+msgstr ""
+
 msgid "actions_edit"
 msgstr "modificar"
 
@@ -766,49 +772,49 @@
 msgid "add"
 msgstr "agregar"
 
-msgid "add Bookmark bookmarked_by EUser object"
+msgid "add Bookmark bookmarked_by CWUser object"
 msgstr ""
 
-msgid "add EEType add_permission RQLExpression subject"
+msgid "add CWEType add_permission RQLExpression subject"
 msgstr "Definir una expresión RQL de agregación"
 
-msgid "add EEType delete_permission RQLExpression subject"
+msgid "add CWEType delete_permission RQLExpression subject"
 msgstr "Definir una expresión RQL de eliminación"
 
-msgid "add EEType read_permission RQLExpression subject"
+msgid "add CWEType read_permission RQLExpression subject"
 msgstr "Definir una expresión RQL de lectura"
 
-msgid "add EEType update_permission RQLExpression subject"
+msgid "add CWEType update_permission RQLExpression subject"
 msgstr "Definir una expresión RQL de actualización"
 
-msgid "add EFRDef constrained_by EConstraint subject"
+msgid "add CWAttribute constrained_by CWConstraint subject"
 msgstr "condición"
 
-msgid "add EFRDef relation_type ERType object"
+msgid "add CWAttribute relation_type CWRType object"
 msgstr "definición de atributo"
 
-msgid "add ENFRDef constrained_by EConstraint subject"
+msgid "add CWRelation constrained_by CWConstraint subject"
 msgstr "condición"
 
-msgid "add ENFRDef relation_type ERType object"
+msgid "add CWRelation relation_type CWRType object"
 msgstr "definición de relación"
 
-msgid "add EProperty for_user EUser object"
+msgid "add CWProperty for_user CWUser object"
 msgstr "propiedad"
 
-msgid "add ERType add_permission RQLExpression subject"
+msgid "add CWRType add_permission RQLExpression subject"
 msgstr "expresión RQL de agregación"
 
-msgid "add ERType delete_permission RQLExpression subject"
+msgid "add CWRType delete_permission RQLExpression subject"
 msgstr "expresión RQL de eliminación"
 
-msgid "add ERType read_permission RQLExpression subject"
+msgid "add CWRType read_permission RQLExpression subject"
 msgstr "expresión RQL de lectura"
 
-msgid "add EUser in_group EGroup object"
+msgid "add CWUser in_group CWGroup object"
 msgstr "usuario"
 
-msgid "add EUser use_email EmailAddress subject"
+msgid "add CWUser use_email EmailAddress subject"
 msgstr "agregar email"
 
 msgid "add State allowed_transition Transition object"
@@ -817,7 +823,7 @@
 msgid "add State allowed_transition Transition subject"
 msgstr "agregar una transición en salida"
 
-msgid "add State state_of EEType object"
+msgid "add State state_of CWEType object"
 msgstr "agregar un estado"
 
 msgid "add Transition condition RQLExpression subject"
@@ -829,7 +835,7 @@
 msgid "add Transition destination_state State subject"
 msgstr "agregar el estado de salida"
 
-msgid "add Transition transition_of EEType object"
+msgid "add Transition transition_of CWEType object"
 msgstr "agregar una transición"
 
 msgid "add a Bookmark"
@@ -838,37 +844,37 @@
 msgid "add a Card"
 msgstr "agregar una ficha"
 
-msgid "add a ECache"
+msgid "add a CWCache"
 msgstr "agregar una memoria cache"
 
-msgid "add a EConstraint"
+msgid "add a CWConstraint"
 msgstr "agregar una condición"
 
-msgid "add a EConstraintType"
+msgid "add a CWConstraintType"
 msgstr "aun tipo de condición"
 
-msgid "add a EEType"
+msgid "add a CWEType"
 msgstr "agregar un tipo de entidad"
 
-msgid "add a EFRDef"
+msgid "add a CWAttribute"
 msgstr "agregar un tipo de relación"
 
-msgid "add a EGroup"
+msgid "add a CWGroup"
 msgstr "agregar un grupo de usuarios"
 
-msgid "add a ENFRDef"
+msgid "add a CWRelation"
 msgstr "agregar una relación"
 
-msgid "add a EPermission"
+msgid "add a CWPermission"
 msgstr "agregar una autorización"
 
-msgid "add a EProperty"
+msgid "add a CWProperty"
 msgstr "agregar una propiedad"
 
-msgid "add a ERType"
+msgid "add a CWRType"
 msgstr "agregar un tipo de relación"
 
-msgid "add a EUser"
+msgid "add a CWUser"
 msgstr "agregar un usuario"
 
 msgid "add a EmailAddress"
@@ -1390,61 +1396,61 @@
 msgid "created_by_object"
 msgstr "ha creado"
 
-msgid "creating Bookmark (Bookmark bookmarked_by EUser %(linkto)s)"
+msgid "creating Bookmark (Bookmark bookmarked_by CWUser %(linkto)s)"
 msgstr ""
 
-msgid "creating EConstraint (EFRDef %(linkto)s constrained_by EConstraint)"
+msgid "creating CWConstraint (CWAttribute %(linkto)s constrained_by CWConstraint)"
 msgstr "creación condicionada por el atributo %(linkto)s"
 
-msgid "creating EConstraint (ENFRDef %(linkto)s constrained_by EConstraint)"
+msgid "creating CWConstraint (CWRelation %(linkto)s constrained_by CWConstraint)"
 msgstr "creación condicionada por la relación %(linkto)s"
 
-msgid "creating EFRDef (EFRDef relation_type ERType %(linkto)s)"
+msgid "creating CWAttribute (CWAttribute relation_type CWRType %(linkto)s)"
 msgstr "creación atributo %(linkto)s"
 
-msgid "creating ENFRDef (ENFRDef relation_type ERType %(linkto)s)"
+msgid "creating CWRelation (CWRelation relation_type CWRType %(linkto)s)"
 msgstr "creación relación %(linkto)s"
 
-msgid "creating EProperty (EProperty for_user EUser %(linkto)s)"
+msgid "creating CWProperty (CWProperty for_user CWUser %(linkto)s)"
 msgstr "creación de una propiedad por el usuario %(linkto)s"
 
-msgid "creating EUser (EUser in_group EGroup %(linkto)s)"
+msgid "creating CWUser (CWUser in_group CWGroup %(linkto)s)"
 msgstr "creación de un usuario para agregar al grupo %(linkto)s"
 
-msgid "creating EmailAddress (EUser %(linkto)s use_email EmailAddress)"
+msgid "creating EmailAddress (CWUser %(linkto)s use_email EmailAddress)"
 msgstr "creación de una dirección electrónica para el usuario %(linkto)s"
 
-msgid "creating RQLExpression (EEType %(linkto)s add_permission RQLExpression)"
+msgid "creating RQLExpression (CWEType %(linkto)s add_permission RQLExpression)"
 msgstr ""
 "creación de una expresión RQL para la autorización de agregar %(linkto)s"
 
 msgid ""
-"creating RQLExpression (EEType %(linkto)s delete_permission RQLExpression)"
+"creating RQLExpression (CWEType %(linkto)s delete_permission RQLExpression)"
 msgstr ""
 "creación de una expresión RQL para la autorización de eliminar %(linkto)s"
 
 msgid ""
-"creating RQLExpression (EEType %(linkto)s read_permission RQLExpression)"
+"creating RQLExpression (CWEType %(linkto)s read_permission RQLExpression)"
 msgstr "creación de una expresión RQL para la autorización de leer %(linkto)s"
 
 msgid ""
-"creating RQLExpression (EEType %(linkto)s update_permission RQLExpression)"
+"creating RQLExpression (CWEType %(linkto)s update_permission RQLExpression)"
 msgstr ""
 "creación de una expresión RQL para la autorización de actualizar %(linkto)s"
 
-msgid "creating RQLExpression (ERType %(linkto)s add_permission RQLExpression)"
+msgid "creating RQLExpression (CWRType %(linkto)s add_permission RQLExpression)"
 msgstr ""
 "creación de una expresión RQL para la autorización de agregar relaciones %"
 "(linkto)s"
 
 msgid ""
-"creating RQLExpression (ERType %(linkto)s delete_permission RQLExpression)"
+"creating RQLExpression (CWRType %(linkto)s delete_permission RQLExpression)"
 msgstr ""
 "creación de una expresión RQL para autorizar la eliminación de relaciones %"
 "(linkto)s"
 
 msgid ""
-"creating RQLExpression (ERType %(linkto)s read_permission RQLExpression)"
+"creating RQLExpression (CWRType %(linkto)s read_permission RQLExpression)"
 msgstr ""
 "creación de una expresión RQL para autorizar la lectura de relaciones %"
 "(linkto)s"
@@ -1455,7 +1461,7 @@
 msgid "creating State (State allowed_transition Transition %(linkto)s)"
 msgstr "creación de un estado que pueda ir hacia la transición %(linkto)s"
 
-msgid "creating State (State state_of EEType %(linkto)s)"
+msgid "creating State (State state_of CWEType %(linkto)s)"
 msgstr "creación de un estado por el tipo %(linkto)s"
 
 msgid "creating State (Transition %(linkto)s destination_state State)"
@@ -1467,7 +1473,7 @@
 msgid "creating Transition (Transition destination_state State %(linkto)s)"
 msgstr "creación de un transición hacia el estado %(linkto)s"
 
-msgid "creating Transition (Transition transition_of EEType %(linkto)s)"
+msgid "creating Transition (Transition transition_of CWEType %(linkto)s)"
 msgstr "creación de una transición para el tipo %(linkto)s"
 
 msgid "creation"
@@ -1658,6 +1664,9 @@
 msgid "download icon"
 msgstr "ícono de descarga"
 
+msgid "download schema as owl"
+msgstr ""
+
 msgid "edit bookmarks"
 msgstr "editar los atajos"
 
@@ -2132,6 +2141,11 @@
 msgid "link a transition to one or more entity type"
 msgstr "lie une transition ‡ un ou plusieurs types d'entitÈs"
 
+msgid ""
+"link a transition to one or more rql expression allowing to go through this "
+"transition"
+msgstr ""
+
 msgid "link to each item in"
 msgstr "lier vers chaque ÈlÈment dans"
 
@@ -2375,6 +2389,9 @@
 msgid "pkey"
 msgstr "clÈ"
 
+msgid "planned_delivery"
+msgstr ""
+
 msgid "please correct errors below"
 msgstr "veuillez corriger les erreurs ci-dessous"
 
@@ -2442,37 +2459,37 @@
 msgid "remove this Card"
 msgstr "supprimer cette fiche"
 
-msgid "remove this ECache"
+msgid "remove this CWCache"
 msgstr "supprimer ce cache applicatif"
 
-msgid "remove this EConstraint"
+msgid "remove this CWConstraint"
 msgstr "supprimer cette contrainte"
 
-msgid "remove this EConstraintType"
+msgid "remove this CWConstraintType"
 msgstr "supprimer ce type de contrainte"
 
-msgid "remove this EEType"
+msgid "remove this CWEType"
 msgstr "supprimer ce type d'entitÈ"
 
-msgid "remove this EFRDef"
+msgid "remove this CWAttribute"
 msgstr "supprimer cet attribut"
 
-msgid "remove this EGroup"
+msgid "remove this CWGroup"
 msgstr "supprimer ce groupe"
 
-msgid "remove this ENFRDef"
+msgid "remove this CWRelation"
 msgstr "supprimer cette relation"
 
-msgid "remove this EPermission"
+msgid "remove this CWPermission"
 msgstr "supprimer cette permission"
 
-msgid "remove this EProperty"
+msgid "remove this CWProperty"
 msgstr "supprimer cette propriÈtÈ"
 
-msgid "remove this ERType"
+msgid "remove this CWRType"
 msgstr "supprimer cette dÈfinition de relation"
 
-msgid "remove this EUser"
+msgid "remove this CWUser"
 msgstr "supprimer cet utilisateur"
 
 msgid "remove this EmailAddress"
--- a/i18n/fr.po	Wed Apr 22 09:45:54 2009 +0200
+++ b/i18n/fr.po	Fri Apr 24 19:46:47 2009 +0200
@@ -232,70 +232,70 @@
 msgid "Do you want to delete the following element(s) ?"
 msgstr "Voulez vous supprimer le(s) élément(s) suivant(s)"
 
-msgid "ECache"
+msgid "CWCache"
 msgstr "Cache applicatif"
 
-msgid "ECache_plural"
+msgid "CWCache_plural"
 msgstr "Caches applicatifs"
 
-msgid "EConstraint"
+msgid "CWConstraint"
 msgstr "Contrainte"
 
-msgid "EConstraintType"
+msgid "CWConstraintType"
 msgstr "Type de contrainte"
 
-msgid "EConstraintType_plural"
+msgid "CWConstraintType_plural"
 msgstr "Types de contrainte"
 
-msgid "EConstraint_plural"
+msgid "CWConstraint_plural"
 msgstr "Contraintes"
 
-msgid "EEType"
+msgid "CWEType"
 msgstr "Type d'entité"
 
-msgid "EEType_plural"
+msgid "CWEType_plural"
 msgstr "Types d'entité"
 
-msgid "EFRDef"
+msgid "CWAttribute"
 msgstr "Attribut"
 
-msgid "EFRDef_plural"
+msgid "CWAttribute_plural"
 msgstr "Attributs"
 
-msgid "EGroup"
+msgid "CWGroup"
 msgstr "Groupe"
 
-msgid "EGroup_plural"
+msgid "CWGroup_plural"
 msgstr "Groupes"
 
-msgid "ENFRDef"
+msgid "CWRelation"
 msgstr "Relation"
 
-msgid "ENFRDef_plural"
+msgid "CWRelation_plural"
 msgstr "Relations"
 
-msgid "EPermission"
+msgid "CWPermission"
 msgstr "Permission"
 
-msgid "EPermission_plural"
+msgid "CWPermission_plural"
 msgstr "Permissions"
 
-msgid "EProperty"
+msgid "CWProperty"
 msgstr "Propriété"
 
-msgid "EProperty_plural"
+msgid "CWProperty_plural"
 msgstr "Propriétés"
 
-msgid "ERType"
+msgid "CWRType"
 msgstr "Type de relation"
 
-msgid "ERType_plural"
+msgid "CWRType_plural"
 msgstr "Types de relation"
 
-msgid "EUser"
+msgid "CWUser"
 msgstr "Utilisateur"
 
-msgid "EUser_plural"
+msgid "CWUser_plural"
 msgstr "Utilisateurs"
 
 msgid "Email body: "
@@ -340,37 +340,37 @@
 msgid "New Card"
 msgstr "Nouvelle fiche"
 
-msgid "New ECache"
+msgid "New CWCache"
 msgstr "Nouveau cache applicatif"
 
-msgid "New EConstraint"
+msgid "New CWConstraint"
 msgstr "Nouvelle contrainte"
 
-msgid "New EConstraintType"
+msgid "New CWConstraintType"
 msgstr "Nouveau type de contrainte"
 
-msgid "New EEType"
+msgid "New CWEType"
 msgstr "Nouveau type d'entité"
 
-msgid "New EFRDef"
+msgid "New CWAttribute"
 msgstr "Nouvelle définition de relation finale"
 
-msgid "New EGroup"
+msgid "New CWGroup"
 msgstr "Nouveau groupe"
 
-msgid "New ENFRDef"
+msgid "New CWRelation"
 msgstr "Nouvelle définition de relation non finale"
 
-msgid "New EPermission"
+msgid "New CWPermission"
 msgstr "Nouvelle permission"
 
-msgid "New EProperty"
+msgid "New CWProperty"
 msgstr "Nouvelle propriété"
 
-msgid "New ERType"
+msgid "New CWRType"
 msgstr "Nouveau type de relation"
 
-msgid "New EUser"
+msgid "New CWUser"
 msgstr "Nouvel utilisateur"
 
 msgid "New EmailAddress"
@@ -479,37 +479,37 @@
 msgid "This Card"
 msgstr "Cette fiche"
 
-msgid "This ECache"
+msgid "This CWCache"
 msgstr "Ce cache applicatif"
 
-msgid "This EConstraint"
+msgid "This CWConstraint"
 msgstr "Cette contrainte"
 
-msgid "This EConstraintType"
+msgid "This CWConstraintType"
 msgstr "Ce type de contrainte"
 
-msgid "This EEType"
+msgid "This CWEType"
 msgstr "Ce type d'entité"
 
-msgid "This EFRDef"
+msgid "This CWAttribute"
 msgstr "Cette définition de relation finale"
 
-msgid "This EGroup"
+msgid "This CWGroup"
 msgstr "Ce groupe"
 
-msgid "This ENFRDef"
+msgid "This CWRelation"
 msgstr "Cette définition de relation non finale"
 
-msgid "This EPermission"
+msgid "This CWPermission"
 msgstr "Cette permission"
 
-msgid "This EProperty"
+msgid "This CWProperty"
 msgstr "Cette propriété"
 
-msgid "This ERType"
+msgid "This CWRType"
 msgstr "Ce type de relation"
 
-msgid "This EUser"
+msgid "This CWUser"
 msgstr "Cet utilisateur"
 
 msgid "This EmailAddress"
@@ -669,6 +669,12 @@
 msgid "actions_delete_description"
 msgstr ""
 
+msgid "actions_download_as_owl"
+msgstr ""
+
+msgid "actions_download_as_owl_description"
+msgstr ""
+
 msgid "actions_edit"
 msgstr "modifier"
 
@@ -768,49 +774,49 @@
 msgid "add"
 msgstr "ajouter"
 
-msgid "add Bookmark bookmarked_by EUser object"
+msgid "add Bookmark bookmarked_by CWUser object"
 msgstr "signet"
 
-msgid "add EEType add_permission RQLExpression subject"
+msgid "add CWEType add_permission RQLExpression subject"
 msgstr "définir une expression RQL d'ajout"
 
-msgid "add EEType delete_permission RQLExpression subject"
+msgid "add CWEType delete_permission RQLExpression subject"
 msgstr "définir une expression RQL de suppression"
 
-msgid "add EEType read_permission RQLExpression subject"
+msgid "add CWEType read_permission RQLExpression subject"
 msgstr "définir une expression RQL de lecture"
 
-msgid "add EEType update_permission RQLExpression subject"
+msgid "add CWEType update_permission RQLExpression subject"
 msgstr "définir une expression RQL de mise à jour"
 
-msgid "add EFRDef constrained_by EConstraint subject"
+msgid "add CWAttribute constrained_by CWConstraint subject"
 msgstr "contrainte"
 
-msgid "add EFRDef relation_type ERType object"
+msgid "add CWAttribute relation_type CWRType object"
 msgstr "définition d'attribut"
 
-msgid "add ENFRDef constrained_by EConstraint subject"
+msgid "add CWRelation constrained_by CWConstraint subject"
 msgstr "contrainte"
 
-msgid "add ENFRDef relation_type ERType object"
+msgid "add CWRelation relation_type CWRType object"
 msgstr "définition de relation"
 
-msgid "add EProperty for_user EUser object"
+msgid "add CWProperty for_user CWUser object"
 msgstr "propriété"
 
-msgid "add ERType add_permission RQLExpression subject"
+msgid "add CWRType add_permission RQLExpression subject"
 msgstr "expression RQL d'ajout"
 
-msgid "add ERType delete_permission RQLExpression subject"
+msgid "add CWRType delete_permission RQLExpression subject"
 msgstr "expression RQL de suppression"
 
-msgid "add ERType read_permission RQLExpression subject"
+msgid "add CWRType read_permission RQLExpression subject"
 msgstr "expression RQL de lecture"
 
-msgid "add EUser in_group EGroup object"
+msgid "add CWUser in_group CWGroup object"
 msgstr "utilisateur"
 
-msgid "add EUser use_email EmailAddress subject"
+msgid "add CWUser use_email EmailAddress subject"
 msgstr "ajouter une addresse email"
 
 msgid "add State allowed_transition Transition object"
@@ -819,7 +825,7 @@
 msgid "add State allowed_transition Transition subject"
 msgstr "ajouter une transition en sortie"
 
-msgid "add State state_of EEType object"
+msgid "add State state_of CWEType object"
 msgstr "ajouter un état"
 
 msgid "add Transition condition RQLExpression subject"
@@ -831,7 +837,7 @@
 msgid "add Transition destination_state State subject"
 msgstr "ajouter l'état de sortie"
 
-msgid "add Transition transition_of EEType object"
+msgid "add Transition transition_of CWEType object"
 msgstr "ajouter une transition"
 
 msgid "add a Bookmark"
@@ -840,37 +846,37 @@
 msgid "add a Card"
 msgstr "ajouter une fiche"
 
-msgid "add a ECache"
+msgid "add a CWCache"
 msgstr "ajouter un cache applicatif"
 
-msgid "add a EConstraint"
+msgid "add a CWConstraint"
 msgstr "ajouter une contrainte"
 
-msgid "add a EConstraintType"
+msgid "add a CWConstraintType"
 msgstr "ajouter un type de contrainte"
 
-msgid "add a EEType"
+msgid "add a CWEType"
 msgstr "ajouter un type d'entité"
 
-msgid "add a EFRDef"
+msgid "add a CWAttribute"
 msgstr "ajouter un type de relation"
 
-msgid "add a EGroup"
+msgid "add a CWGroup"
 msgstr "ajouter un groupe d'utilisateurs"
 
-msgid "add a ENFRDef"
+msgid "add a CWRelation"
 msgstr "ajouter une relation"
 
-msgid "add a EPermission"
+msgid "add a CWPermission"
 msgstr "ajouter une permission"
 
-msgid "add a EProperty"
+msgid "add a CWProperty"
 msgstr "ajouter une propriété"
 
-msgid "add a ERType"
+msgid "add a CWRType"
 msgstr "ajouter un type de relation"
 
-msgid "add a EUser"
+msgid "add a CWUser"
 msgstr "ajouter un utilisateur"
 
 msgid "add a EmailAddress"
@@ -1392,60 +1398,60 @@
 msgid "created_by_object"
 msgstr "a créé"
 
-msgid "creating Bookmark (Bookmark bookmarked_by EUser %(linkto)s)"
+msgid "creating Bookmark (Bookmark bookmarked_by CWUser %(linkto)s)"
 msgstr "création d'un signet pour %(linkto)s"
 
-msgid "creating EConstraint (EFRDef %(linkto)s constrained_by EConstraint)"
+msgid "creating CWConstraint (CWAttribute %(linkto)s constrained_by CWConstraint)"
 msgstr "création d'une contrainte pour l'attribut %(linkto)s"
 
-msgid "creating EConstraint (ENFRDef %(linkto)s constrained_by EConstraint)"
+msgid "creating CWConstraint (CWRelation %(linkto)s constrained_by CWConstraint)"
 msgstr "création d'une contrainte pour la relation %(linkto)s"
 
-msgid "creating EFRDef (EFRDef relation_type ERType %(linkto)s)"
+msgid "creating CWAttribute (CWAttribute relation_type CWRType %(linkto)s)"
 msgstr "création d'un attribut %(linkto)s"
 
-msgid "creating ENFRDef (ENFRDef relation_type ERType %(linkto)s)"
+msgid "creating CWRelation (CWRelation relation_type CWRType %(linkto)s)"
 msgstr "création relation %(linkto)s"
 
-msgid "creating EProperty (EProperty for_user EUser %(linkto)s)"
+msgid "creating CWProperty (CWProperty for_user CWUser %(linkto)s)"
 msgstr "création d'une propriété pour l'utilisateur %(linkto)s"
 
-msgid "creating EUser (EUser in_group EGroup %(linkto)s)"
+msgid "creating CWUser (CWUser in_group CWGroup %(linkto)s)"
 msgstr "création d'un utilisateur à rajouter au groupe %(linkto)s"
 
-msgid "creating EmailAddress (EUser %(linkto)s use_email EmailAddress)"
+msgid "creating EmailAddress (CWUser %(linkto)s use_email EmailAddress)"
 msgstr "création d'une adresse électronique pour l'utilisateur %(linkto)s"
 
-msgid "creating RQLExpression (EEType %(linkto)s add_permission RQLExpression)"
+msgid "creating RQLExpression (CWEType %(linkto)s add_permission RQLExpression)"
 msgstr "création d'une expression RQL pour la permission d'ajout de %(linkto)s"
 
 msgid ""
-"creating RQLExpression (EEType %(linkto)s delete_permission RQLExpression)"
+"creating RQLExpression (CWEType %(linkto)s delete_permission RQLExpression)"
 msgstr ""
 "création d'une expression RQL pour la permission de suppression de %(linkto)s"
 
 msgid ""
-"creating RQLExpression (EEType %(linkto)s read_permission RQLExpression)"
+"creating RQLExpression (CWEType %(linkto)s read_permission RQLExpression)"
 msgstr "création d'une expression RQL pour la permission de lire %(linkto)s"
 
 msgid ""
-"creating RQLExpression (EEType %(linkto)s update_permission RQLExpression)"
+"creating RQLExpression (CWEType %(linkto)s update_permission RQLExpression)"
 msgstr ""
 "création d'une expression RQL pour la permission de mise à jour de %(linkto)s"
 
-msgid "creating RQLExpression (ERType %(linkto)s add_permission RQLExpression)"
+msgid "creating RQLExpression (CWRType %(linkto)s add_permission RQLExpression)"
 msgstr ""
 "création d'une expression RQL pour la permission d'ajout des relations %"
 "(linkto)s"
 
 msgid ""
-"creating RQLExpression (ERType %(linkto)s delete_permission RQLExpression)"
+"creating RQLExpression (CWRType %(linkto)s delete_permission RQLExpression)"
 msgstr ""
 "création d'une expression RQL pour la permission de suppression des "
 "relations %(linkto)s"
 
 msgid ""
-"creating RQLExpression (ERType %(linkto)s read_permission RQLExpression)"
+"creating RQLExpression (CWRType %(linkto)s read_permission RQLExpression)"
 msgstr ""
 "création d'une expression RQL pour la permission de lire les relations %"
 "(linkto)s"
@@ -1456,7 +1462,7 @@
 msgid "creating State (State allowed_transition Transition %(linkto)s)"
 msgstr "création d'un état pouvant aller vers la transition %(linkto)s"
 
-msgid "creating State (State state_of EEType %(linkto)s)"
+msgid "creating State (State state_of CWEType %(linkto)s)"
 msgstr "création d'un état pour le type %(linkto)s"
 
 msgid "creating State (Transition %(linkto)s destination_state State)"
@@ -1468,7 +1474,7 @@
 msgid "creating Transition (Transition destination_state State %(linkto)s)"
 msgstr "création d'une transition vers l'état %(linkto)s"
 
-msgid "creating Transition (Transition transition_of EEType %(linkto)s)"
+msgid "creating Transition (Transition transition_of CWEType %(linkto)s)"
 msgstr "création d'une transition pour le type %(linkto)s"
 
 msgid "creation"
@@ -1658,6 +1664,9 @@
 msgid "download icon"
 msgstr "icône de téléchargement"
 
+msgid "download schema as owl"
+msgstr ""
+
 msgid "edit bookmarks"
 msgstr "éditer les signets"
 
@@ -2133,6 +2142,11 @@
 msgid "link a transition to one or more entity type"
 msgstr "lie une transition à un ou plusieurs types d'entités"
 
+msgid ""
+"link a transition to one or more rql expression allowing to go through this "
+"transition"
+msgstr ""
+
 msgid "link to each item in"
 msgstr "lier vers chaque élément dans"
 
@@ -2379,6 +2393,9 @@
 msgid "pkey"
 msgstr "clé"
 
+msgid "planned_delivery"
+msgstr "livraison prévue"
+
 msgid "please correct errors below"
 msgstr "veuillez corriger les erreurs ci-dessous"
 
@@ -2446,37 +2463,37 @@
 msgid "remove this Card"
 msgstr "supprimer cette fiche"
 
-msgid "remove this ECache"
+msgid "remove this CWCache"
 msgstr "supprimer ce cache applicatif"
 
-msgid "remove this EConstraint"
+msgid "remove this CWConstraint"
 msgstr "supprimer cette contrainte"
 
-msgid "remove this EConstraintType"
+msgid "remove this CWConstraintType"
 msgstr "supprimer ce type de contrainte"
 
-msgid "remove this EEType"
+msgid "remove this CWEType"
 msgstr "supprimer ce type d'entité"
 
-msgid "remove this EFRDef"
+msgid "remove this CWAttribute"
 msgstr "supprimer cet attribut"
 
-msgid "remove this EGroup"
+msgid "remove this CWGroup"
 msgstr "supprimer ce groupe"
 
-msgid "remove this ENFRDef"
+msgid "remove this CWRelation"
 msgstr "supprimer cette relation"
 
-msgid "remove this EPermission"
+msgid "remove this CWPermission"
 msgstr "supprimer cette permission"
 
-msgid "remove this EProperty"
+msgid "remove this CWProperty"
 msgstr "supprimer cette propriété"
 
-msgid "remove this ERType"
+msgid "remove this CWRType"
 msgstr "supprimer cette définition de relation"
 
-msgid "remove this EUser"
+msgid "remove this CWUser"
 msgstr "supprimer cet utilisateur"
 
 msgid "remove this EmailAddress"
--- a/misc/migration/2.42.1_Any.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/misc/migration/2.42.1_Any.py	Fri Apr 24 19:46:47 2009 +0200
@@ -14,5 +14,5 @@
 
 if 'inline_view' in schema:
     # inline_view attribute should have been deleted for a while now....
-    drop_attribute('ENFRDef', 'inline_view')
+    drop_attribute('CWRelation', 'inline_view')
     
--- a/misc/migration/2.44.0_Any.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/misc/migration/2.44.0_Any.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,11 +1,11 @@
-change_relation_props('EFRDef', 'cardinality', 'String', internationalizable=True)
-change_relation_props('ENFRDef', 'cardinality', 'String', internationalizable=True)
+change_relation_props('CWAttribute', 'cardinality', 'String', internationalizable=True)
+change_relation_props('CWRelation', 'cardinality', 'String', internationalizable=True)
 
-drop_relation_definition('EPermission', 'require_state', 'State')
+drop_relation_definition('CWPermission', 'require_state', 'State')
 
 if confirm('cleanup require_permission relation'):
     try:
-        newrschema = newschema.rschema('require_permission')
+        newrschema = fsschema.rschema('require_permission')
     except KeyError:
         newrschema = None
     for rsubj, robj in schema.rschema('require_permission').rdefs():
--- a/misc/migration/2.48.8_Any.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/misc/migration/2.48.8_Any.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,2 +1,2 @@
-for etype in ('ERType', 'EFRDef', 'ENFRDef', 'EConstraint', 'EConstraintType'):
+for etype in ('CWRType', 'CWAttribute', 'CWRelation', 'CWConstraint', 'CWConstraintType'):
     synchronize_permissions(etype)
--- a/misc/migration/2.99.0_Any.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/misc/migration/2.99.0_Any.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,6 +1,6 @@
 from cubicweb import CW_MIGRATION_MAP
 
-for pk, in rql('Any K WHERE X is EProperty, X pkey IN (%s), X pkey K'
+for pk, in rql('Any K WHERE X is CWProperty, X pkey IN (%s), X pkey K'
                % ','.join("'system.version.%s'" % cube for cube in CW_MIGRATION_MAP),
                ask_confirm=False):
     cube = pk.split('.')[-1]
@@ -9,4 +9,4 @@
         {'oldk': pk, 'newk': newk}, ask_confirm=False)
     print 'renamed', pk, 'to', newk
 
-add_entity_type('ECache')
+add_entity_type('CWCache')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.1.5_Any.py	Fri Apr 24 19:46:47 2009 +0200
@@ -0,0 +1,1 @@
+synchronize_permissions('condition')
--- a/misc/migration/3.2.0_Any.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/misc/migration/3.2.0_Any.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,3 +1,3 @@
-rql('SET X value "main-template" WHERE X is EProperty, '
+rql('SET X value "main-template" WHERE X is CWProperty, '
     'X pkey "ui.main-template", X value "main"')
 checkpoint()
--- a/misc/migration/bootstrapmigration_repository.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/misc/migration/bootstrapmigration_repository.py	Fri Apr 24 19:46:47 2009 +0200
@@ -3,27 +3,27 @@
 it should only include low level schema changes
 
 :organization: Logilab
-:copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 """
 
 if applcubicwebversion < (2, 47, 0) and cubicwebversion >= (2, 47, 0):
     from cubicweb.server import schemaserial
     schemaserial.HAS_FULLTEXT_CONTAINER = False
-    cnx.set_shared_data('do-not-insert-is_instance_of', True)
-    add_attribute('ERType', 'fulltext_container')
+    session.set_shared_data('do-not-insert-is_instance_of', True)
+    add_attribute('CWRType', 'fulltext_container')
     schemaserial.HAS_FULLTEXT_CONTAINER = True
 
 
  
 if applcubicwebversion < (2, 50, 0) and cubicwebversion >= (2, 50, 0):
-    cnx.set_shared_data('do-not-insert-is_instance_of', True)
+    session.set_shared_data('do-not-insert-is_instance_of', True)
     add_relation_type('is_instance_of')
     # fill the relation using an efficient sql query instead of using rql
     sql('INSERT INTO is_instance_of_relation '
 	'  SELECT * from is_relation')
     checkpoint()
-    cnx.set_shared_data('do-not-insert-is_instance_of', False)
+    session.set_shared_data('do-not-insert-is_instance_of', False)
 
 if applcubicwebversion < (2, 42, 0) and cubicwebversion >= (2, 42, 0):
     sql('ALTER TABLE entities ADD COLUMN mtime TIMESTAMP')
--- a/misc/migration/postcreate.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/misc/migration/postcreate.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,22 +1,22 @@
 """cubicweb post creation script, set user's workflow"""
 
-activatedeid = add_state(_('activated'), 'EUser', initial=True)
-deactivatedeid = add_state(_('deactivated'), 'EUser')
-add_transition(_('deactivate'), 'EUser',
+activatedeid = add_state(_('activated'), 'CWUser', initial=True)
+deactivatedeid = add_state(_('deactivated'), 'CWUser')
+add_transition(_('deactivate'), 'CWUser',
                (activatedeid,), deactivatedeid,
                requiredgroups=('managers',))
-add_transition(_('activate'), 'EUser',
+add_transition(_('activate'), 'CWUser',
                (deactivatedeid,), activatedeid,
                requiredgroups=('managers',))
 
 # need this since we already have at least one user in the database (the default admin)
-rql('SET X in_state S WHERE X is EUser, S eid %s' % activatedeid)
+rql('SET X in_state S WHERE X is CWUser, S eid %s' % activatedeid)
 
 # create anonymous user if all-in-one config and anonymous user has been specified
 if hasattr(config, 'anonymous_user'):
     anonlogin, anonpwd = config.anonymous_user()
     if anonlogin:
-        rql('INSERT EUser X: X login %(login)s, X upassword %(pwd)s,'
+        rql('INSERT CWUser X: X login %(login)s, X upassword %(pwd)s,'
             'X in_state S, X in_group G WHERE G name "guests", S name "activated"',
             {'login': unicode(anonlogin), 'pwd': anonpwd})
 
@@ -30,11 +30,11 @@
         default = cfg.option_default(optname, optdict)
         # only record values differing from default
         if value != default:
-            rql('INSERT EProperty X: X pkey %(k)s, X value %(v)s', {'k': key, 'v': value})
+            rql('INSERT CWProperty X: X pkey %(k)s, X value %(v)s', {'k': key, 'v': value})
 
 # add PERM_USE_TEMPLATE_FORMAT permission
 from cubicweb.schema import PERM_USE_TEMPLATE_FORMAT
-eid = add_entity('EPermission', name=PERM_USE_TEMPLATE_FORMAT,
+eid = add_entity('CWPermission', name=PERM_USE_TEMPLATE_FORMAT,
                  label=_('use template languages'))
 rql('SET X require_group G WHERE G name "managers", X eid %(x)s',
     {'x': eid}, 'x')    
--- a/rset.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/rset.py	Fri Apr 24 19:46:47 2009 +0200
@@ -51,7 +51,9 @@
         # set by the cursor which returned this resultset
         self.vreg = None
         self.req = None
-   
+        # actions cache
+        self._rsetactions = None
+        
     def __str__(self):
         if not self.rows:
             return '<empty resultset %s>' % self.rql
@@ -70,9 +72,19 @@
                                                  '\n'.join('%s (%s)' % (r, d)
                                                            for r, d in zip(rows, self.description)))
 
-    @cached
-    def possible_actions(self):
-        return self.vreg.possible_vobjects('actions', self.req, self)
+    def possible_actions(self, **kwargs):
+        if self._rsetactions is None:
+            self._rsetactions = {}
+        if kwargs:
+            key = tuple(sorted(kwargs.iteritems()))
+        else:
+            key = None
+        try:
+            return self._rsetactions[key]
+        except KeyError:
+            actions = self.vreg.possible_vobjects('actions', self.req, self, **kwargs)
+            self._rsetactions[key] = actions
+            return actions
     
     def __len__(self):
         """returns the result set's size"""
@@ -368,6 +380,9 @@
             pass
         # build entity instance
         etype = self.description[row][col]
+        if etype == 'EUser':
+            import traceback
+            traceback.printstack()
         entity = self.vreg.etype_class(etype)(req, self, row, col)
         entity.set_eid(eid)
         # cache entity
--- a/rtags.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/rtags.py	Fri Apr 24 19:46:47 2009 +0200
@@ -17,21 +17,21 @@
     should use rtags / etype_rtags / add_rtag api. Otherwise, a single tag is
     associated to each key, and you should use rtag / etype_rtag / set_rtag api.
     """
-    
+
     def __init__(self, use_set=False):
         self.use_set = use_set
         self._tagdefs = {}
-        
+
     def set_rtag(self, tag, rtype, role, stype='*', otype='*'):
         assert not self.use_set
         assert role in ('subject', 'object'), role
         self._tagdefs[(str(rtype), role, str(stype), str(otype))] = tag
-        
+
     def del_rtag(self, rtype, role, stype='*', otype='*'):
         assert not self.use_set
         assert role in ('subject', 'object'), role
         del self._tagdefs[(str(rtype), role, str(stype), str(otype))]
-        
+
     def rtag(self, rtype, role, stype='*', otype='*'):
         assert not self.use_set
         for key in reversed(self._get_keys(rtype, role, stype, otype)):
@@ -40,18 +40,18 @@
             except KeyError:
                 continue
         return None
-        
+
     def etype_rtag(self, etype, rtype, role, ttype='*'):
         if role == 'subject':
             return self.rtag(rtype, role, etype, ttype)
         return self.rtag(rtype, role, ttype, etype)
-        
+
     def add_rtag(self, tag, rtype, role, stype='*', otype='*'):
         assert self.use_set
         assert role in ('subject', 'object'), role
         rtags = self._tagdefs.setdefault((rtype, role, stype, otype), set())
         rtags.add(tag)
-        
+
     def rtags(self, rtype, role, stype='*', otype='*'):
         assert self.use_set
         rtags = set()
@@ -61,13 +61,13 @@
             except KeyError:
                 continue
         return rtags
-        
+
     def etype_rtags(self, etype, rtype, role, ttype='*'):
         if role == 'subject':
             return self.rtags(rtype, role, etype, ttype)
         return self.rtags(rtype, role, ttype, etype)
 
-    def _get_keys(self, rtype, role, stype, otype): 
+    def _get_keys(self, rtype, role, stype, otype):
         assert role in ('subject', 'object'), role
         keys = [(rtype, role, '*', '*'),
                 (rtype, role, '*', otype),
@@ -78,9 +78,9 @@
             if stype == '*':
                 keys.remove((rtype, role, '*', otype))
             if otype == '*':
-                keys.remove((rtype, role, stype, '*'))            
+                keys.remove((rtype, role, stype, '*'))
         return keys
-    
+
     # dict compat
     def __getitem__(self, key):
         if isinstance(key, basestring):
--- a/schema.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/schema.py	Fri Apr 24 19:46:47 2009 +0200
@@ -27,7 +27,7 @@
 # XXX <3.2 bw compat
 from yams import schema
 schema.use_py_datetime()
-nodes.use_py_datetime() 
+nodes.use_py_datetime()
 
 _ = unicode
 
@@ -43,7 +43,7 @@
 def bw_normalize_etype(etype):
     if etype in ETYPE_NAME_MAP:
         msg = '%s has been renamed to %s, please update your code' % (
-            etype, ETYPE_NAME_MAP[etype])            
+            etype, ETYPE_NAME_MAP[etype])
         warn(msg, DeprecationWarning, stacklevel=4)
         etype = ETYPE_NAME_MAP[etype]
     return etype
@@ -78,12 +78,12 @@
 class RichString(ybo.String):
     """Convenience RichString attribute type
     The follwing declaration::
-      
+
       class Card(EntityType):
           content = RichString(fulltextindexed=True, default_format='text/rest')
-          
+
     is equivalent to::
-      
+
       class Card(EntityType):
           content_format = String(meta=True, internationalizable=True,
                                  default='text/rest', constraints=[format_constraint])
@@ -106,7 +106,7 @@
                                     constraints=rdef.format_constraints)
         yams_add_relation(relations, format_attrdef, name+'_format', insertidx)
     yams_add_relation(relations, rdef, name, insertidx)
-    
+
 def display_name(req, key, form=''):
     """return a internationalized string for the key (schema entity or relation
     name) in a given form
@@ -258,19 +258,19 @@
             eid = getattr(edef, 'eid', None)
         self.eid = eid
         # take care: no _groups attribute when deep-copying
-        if getattr(self, '_groups', None): 
+        if getattr(self, '_groups', None):
             for groups in self._groups.itervalues():
                 for group_or_rqlexpr in groups:
                     if isinstance(group_or_rqlexpr, RRQLExpression):
                         msg = "can't use RRQLExpression on an entity type, use an ERQLExpression (%s)"
                         raise BadSchemaDefinition(msg % self.type)
-            
+
     def attribute_definitions(self):
         """return an iterator on attribute definitions
-        
+
         attribute relations are a subset of subject relations where the
         object's type is a final entity
-        
+
         an attribute definition is a 2-uple :
         * name of the relation
         * schema of the destination entity type
@@ -280,7 +280,7 @@
             if rschema.type == 'has_text':
                 continue
             yield rschema, attrschema
-            
+
     def add_subject_relation(self, rschema):
         """register the relation schema as possible subject relation"""
         super(CubicWebEntitySchema, self).add_subject_relation(rschema)
@@ -289,7 +289,7 @@
     def del_subject_relation(self, rtype):
         super(CubicWebEntitySchema, self).del_subject_relation(rtype)
         self._update_has_text(False)
-        
+
     def _update_has_text(self, need_has_text=None):
         may_need_has_text, has_has_text = False, False
         for rschema in self.subject_relations():
@@ -317,11 +317,11 @@
             self.schema.add_relation_def(rdef)
         elif not need_has_text and has_has_text:
             self.schema.del_relation_def(self.type, 'has_text', 'String')
-            
+
     def schema_entity(self):
         """return True if this entity type is used to build the schema"""
         return self.type in self.schema.schema_entity_types()
-    
+
     def check_perm(self, session, action, eid=None):
         # NB: session may be a server session or a request object
         user = session.user
@@ -337,17 +337,17 @@
         # else if there is some rql expressions, check them
         if any(rqlexpr.check(session, eid)
                for rqlexpr in self.get_rqlexprs(action)):
-            return        
+            return
         raise Unauthorized(action, str(self))
 
     def rql_expression(self, expression, mainvars=None, eid=None):
         """rql expression factory"""
         return ERQLExpression(expression, mainvars, eid)
-    
+
 class CubicWebRelationSchema(RelationSchema):
     RelationSchema._RPROPERTIES['eid'] = None
     _perms_checked = False
-    
+
     def __init__(self, schema=None, rdef=None, eid=None, **kwargs):
         if rdef is not None:
             # if this relation is inlined
@@ -356,8 +356,8 @@
         if eid is None and rdef is not None:
             eid = getattr(rdef, 'eid', None)
         self.eid = eid
-                    
-        
+
+
     def update(self, subjschema, objschema, rdef):
         super(CubicWebRelationSchema, self).update(subjschema, objschema, rdef)
         if not self._perms_checked and self._groups:
@@ -377,7 +377,7 @@
                             newrqlexprs.append(ERQLExpression(rqlexpr.expression,
                                                               rqlexpr.mainvars,
                                                               rqlexpr.eid))
-                            self.set_rqlexprs(action, newrqlexprs) 
+                            self.set_rqlexprs(action, newrqlexprs)
                         else:
                             msg = "can't use RRQLExpression on a final relation "\
                                   "type (eg attribute relation), use an ERQLExpression (%s)"
@@ -388,16 +388,16 @@
                               "a RRQLExpression (%s)"
                         raise BadSchemaDefinition(msg % self.type)
             self._perms_checked = True
-            
+
     def cardinality(self, subjtype, objtype, target):
         card = self.rproperty(subjtype, objtype, 'cardinality')
         return (target == 'subject' and card[0]) or \
                (target == 'object' and card[1])
-    
+
     def schema_relation(self):
         return self.type in ('relation_type', 'from_entity', 'to_entity',
                              'constrained_by', 'cstrtype')
-    
+
     def physical_mode(self):
         """return an appropriate mode for physical storage of this relation type:
         * 'subjectinline' if every possible subject cardinalities are 1 or ?
@@ -413,7 +413,7 @@
         # in an allowed group, if so that's enough internal sessions should
         # always stop there
         if session.user.matching_groups(self.get_groups(action)):
-            return 
+            return
         # else if there is some rql expressions, check them
         if any(rqlexpr.check(session, *args, **kwargs)
                for rqlexpr in self.get_rqlexprs(action)):
@@ -426,7 +426,7 @@
             return ERQLExpression(expression, mainvars, eid)
         return RRQLExpression(expression, mainvars, eid)
 
-    
+
 class CubicWebSchema(Schema):
     """set of entities and relations schema defining the possible data sets
     used in an application
@@ -434,11 +434,11 @@
 
     :type name: str
     :ivar name: name of the schema, usually the application identifier
-    
+
     :type base: str
     :ivar base: path of the directory where the schema is defined
     """
-    reading_from_database = False    
+    reading_from_database = False
     entity_class = CubicWebEntitySchema
     relation_class = CubicWebRelationSchema
 
@@ -455,15 +455,15 @@
         rschema = self.add_relation_type(ybo.RelationType('identity', meta=True))
         rschema.final = False
         rschema.set_default_groups()
-        
+
     def schema_entity_types(self):
         """return the list of entity types used to build the schema"""
-        return frozenset(('EEType', 'ERType', 'EFRDef', 'ENFRDef',
-                          'EConstraint', 'EConstraintType', 'RQLExpression',
+        return frozenset(('CWEType', 'CWRType', 'CWAttribute', 'CWRelation',
+                          'CWConstraint', 'CWConstraintType', 'RQLExpression',
                           # XXX those are not really "schema" entity types
                           #     but we usually don't want them as @* targets
-                          'EProperty', 'EPermission', 'State', 'Transition'))
-        
+                          'CWProperty', 'CWPermission', 'State', 'Transition'))
+
     def add_entity_type(self, edef):
         edef.name = edef.name.encode()
         edef.name = bw_normalize_etype(edef.name)
@@ -478,13 +478,13 @@
             self.add_relation_def(rdef)
         self._eid_index[eschema.eid] = eschema
         return eschema
-        
+
     def add_relation_type(self, rdef):
         rdef.name = rdef.name.lower().encode()
         rschema = super(CubicWebSchema, self).add_relation_type(rdef)
         self._eid_index[rschema.eid] = rschema
         return rschema
-    
+
     def add_relation_def(self, rdef):
         """build a part of a relation schema
         (i.e. add a relation between two specific entity's types)
@@ -511,18 +511,18 @@
                                              self.eschema(rdef.object))
             except AttributeError:
                 pass # not a serialized schema
-    
+
     def del_relation_type(self, rtype):
         rschema = self.rschema(rtype)
         self._eid_index.pop(rschema.eid, None)
         super(CubicWebSchema, self).del_relation_type(rtype)
-    
+
     def del_relation_def(self, subjtype, rtype, objtype):
         for k, v in self._eid_index.items():
             if v == (subjtype, rtype, objtype):
                 del self._eid_index[k]
         super(CubicWebSchema, self).del_relation_def(subjtype, rtype, objtype)
-        
+
     def del_entity_type(self, etype):
         eschema = self.eschema(etype)
         self._eid_index.pop(eschema.eid, None)
@@ -531,7 +531,7 @@
         if 'has_text' in eschema.subject_relations():
             self.del_relation_def(etype, 'has_text', 'String')
         super(CubicWebSchema, self).del_entity_type(etype)
-        
+
     def schema_by_eid(self, eid):
         return self._eid_index[eid]
 
@@ -543,22 +543,22 @@
 
     limit the proposed values to a set of entities returned by a rql query,
     but this is not enforced at the repository level
-    
+
      restriction is additional rql restriction that will be added to
      a predefined query, where the S and O variables respectivly represent
      the subject and the object of the relation
     """
-    
+
     def __init__(self, restriction):
         self.restriction = restriction
 
     def serialize(self):
         return self.restriction
-    
+
     def deserialize(cls, value):
         return cls(value)
     deserialize = classmethod(deserialize)
-    
+
     def check(self, entity, rtype, value):
         """return true if the value satisfy the constraint, else false"""
         # implemented as a hook in the repository
@@ -568,7 +568,7 @@
         """raise ValidationError if the relation doesn't satisfy the constraint
         """
         pass # this is a vocabulary constraint, not enforce
-    
+
     def __str__(self):
         return self.restriction
 
@@ -586,7 +586,7 @@
                                       ('s', 'o'), build_descr=False)
     def error(self, eid, rtype, msg):
         raise ValidationError(eid, {rtype: msg})
-        
+
     def repo_check(self, session, eidfrom, rtype, eidto):
         """raise ValidationError if the relation doesn't satisfy the constraint
         """
@@ -608,12 +608,12 @@
             #     eidfrom or eidto (from user interface point of view)
             self.error(eidfrom, rtype, 'unique constraint %s failed' % self)
 
-    
+
 def split_expression(rqlstring):
     for expr in rqlstring.split(','):
         for word in expr.split():
             yield word
-            
+
 def normalize_expression(rqlstring):
     """normalize an rql expression to ease schema synchronization (avoid
     suppressing and reinserting an expression if only a space has been added/removed
@@ -637,19 +637,19 @@
             if len(self.rqlst.defined_vars[mainvar].references()) <= 2:
                 LOGGER.warn('You did not use the %s variable in your RQL expression %s',
                             mainvar, self)
-    
+
     def __str__(self):
         return self.full_rql
     def __repr__(self):
         return '%s(%s)' % (self.__class__.__name__, self.full_rql)
-        
+
     def __deepcopy__(self, memo):
         return self.__class__(self.expression, self.mainvars)
     def __getstate__(self):
         return (self.expression, self.mainvars)
     def __setstate__(self, state):
         self.__init__(*state)
-        
+
     @cached
     def transform_has_permission(self):
         found = None
@@ -693,7 +693,7 @@
             rqlst.recover()
             return rql, found, keyarg
         return rqlst.as_string(), None, None
-        
+
     def _check(self, session, **kwargs):
         """return True if the rql expression is matching the given relation
         between fromeid and toeid
@@ -753,7 +753,7 @@
         if self.eid is not None:
             session.local_perm_cache[key] = False
         return False
-    
+
     @property
     def minimal_rql(self):
         return 'Any %s WHERE %s' % (self.mainvars, self.expression)
@@ -778,16 +778,16 @@
         if 'U' in defined:
             rql += ', U eid %(u)s'
         return rql
-    
+
     def check(self, session, eid=None):
         if 'X' in self.rqlst.defined_vars:
             if eid is None:
                 return False
             return self._check(session, x=eid)
         return self._check(session)
-    
+
 PyFileReader.context['ERQLExpression'] = ERQLExpression
-        
+
 class RRQLExpression(RQLExpression):
     def __init__(self, expression, mainvars=None, eid=None):
         if mainvars is None:
@@ -817,7 +817,7 @@
         if 'U' in defined:
             rql += ', U eid %(u)s'
         return rql
-    
+
     def check(self, session, fromeid=None, toeid=None):
         kwargs = {}
         if 'S' in self.rqlst.defined_vars:
@@ -829,7 +829,7 @@
                 return False
             kwargs['o'] = toeid
         return self._check(session, **kwargs)
-        
+
 PyFileReader.context['RRQLExpression'] = RRQLExpression
 
 # workflow extensions #########################################################
@@ -857,7 +857,7 @@
 class WorkflowableEntityType(ybo.EntityType):
     __metaclass__ = workflowable_definition
     abstract = True
-    
+
 PyFileReader.context['WorkflowableEntityType'] = WorkflowableEntityType
 
 # schema loading ##############################################################
@@ -866,7 +866,7 @@
     """cubicweb specific relation file reader, handling additional RQL
     constraints on a relation definition
     """
-    
+
     def handle_constraint(self, rdef, constraint_text):
         """arbitrary constraint is an rql expression for cubicweb"""
         if not rdef.constraints:
@@ -878,7 +878,7 @@
             rdef.inlined = True
         RelationFileReader.process_properties(self, rdef, relation_def)
 
-        
+
 CONSTRAINTS['RQLConstraint'] = RQLConstraint
 CONSTRAINTS['RQLUniqueConstraint'] = RQLUniqueConstraint
 CONSTRAINTS['RQLVocabularyConstraint'] = RQLVocabularyConstraint
@@ -900,13 +900,13 @@
         self.lib_directory = config.schemas_lib_dir()
         return super(BootstrapSchemaLoader, self).load(
             path, config.appid, register_base_types=False, **kwargs)
-    
+
     def _load_definition_files(self, cubes=None):
         # bootstraping, ignore cubes
         for filepath in self.include_schema_files('bootstrap'):
             self.info('loading %s', filepath)
             self.handle_file(filepath)
-        
+
     def unhandled_file(self, filepath):
         """called when a file without handler associated has been found"""
         self.warning('ignoring file %r', filepath)
@@ -932,8 +932,7 @@
         for filepath in (self.include_schema_files('bootstrap')
                          + self.include_schema_files('base')
                          + self.include_schema_files('workflow')
-                         + self.include_schema_files('Bookmark')
-                         + self.include_schema_files('Card')):
+                         + self.include_schema_files('Bookmark')):
             self.info('loading %s', filepath)
             self.handle_file(filepath)
         for cube in cubes:
@@ -948,14 +947,14 @@
 
 class FormatConstraint(StaticVocabularyConstraint):
     need_perm_formats = [_('text/cubicweb-page-template')]
-        
+
     regular_formats = (_('text/rest'),
                        _('text/html'),
                        _('text/plain'),
                        )
     def __init__(self):
         pass
-    
+
     def serialize(self):
         """called to make persistent valuable data of a constraint"""
         return None
@@ -966,18 +965,18 @@
         a `cls` instance
         """
         return cls()
-    
+
     def vocabulary(self, entity=None, req=None):
         if req is None and entity is not None:
             req = entity.req
         if req is not None and req.user.has_permission(PERM_USE_TEMPLATE_FORMAT):
             return self.regular_formats + tuple(self.need_perm_formats)
         return self.regular_formats
-    
+
     def __str__(self):
         return 'value in (%s)' % u', '.join(repr(unicode(word)) for word in self.vocabulary())
-    
-    
+
+
 format_constraint = FormatConstraint()
 CONSTRAINTS['FormatConstraint'] = FormatConstraint
 PyFileReader.context['format_constraint'] = format_constraint
@@ -992,7 +991,7 @@
 def bw_import_erschema(self, ertype, schemamod=None, instantiate=True):
     return orig_import_erschema(self, bw_normalize_etype(ertype), schemamod, instantiate)
 PyFileReader.import_erschema = bw_import_erschema
-    
+
 # XXX itou for some Statement methods
 from rql import stmts
 orig_get_etype = stmts.ScopeNode.get_etype
--- a/schemas/Bookmark.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/schemas/Bookmark.py	Fri Apr 24 19:46:47 2009 +0200
@@ -5,7 +5,7 @@
     path  = String(maxsize=512, required=True,
                    description=_("relative url of the bookmarked page"))
     
-    bookmarked_by = SubjectRelation('EUser',
+    bookmarked_by = SubjectRelation('CWUser',
                                     description=_("users using this bookmark"))
     
 
--- a/schemas/Card.py	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-# from cubicweb.schema import format_constraint
-
-class Card(EntityType):
-    """a card is a textual content used as documentation, reference, procedure reminder"""
-    permissions = {
-        'read':   ('managers', 'users', 'guests'),
-        'add':    ('managers', 'users'),
-        'delete': ('managers', 'owners'),
-        'update': ('managers', 'owners',),
-        }
-    
-    title    = String(required=True, fulltextindexed=True, maxsize=256)
-    synopsis = String(fulltextindexed=True, maxsize=512,
-                      description=_("an abstract for this card"))
-    content = RichString(fulltextindexed=True, default_format='text/rest')
-    wikiid = String(maxsize=64, indexed=True)
--- a/schemas/base.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/schemas/base.py	Fri Apr 24 19:46:47 2009 +0200
@@ -6,10 +6,8 @@
 """
 __docformat__ = "restructuredtext en"
 
-from cubicweb.schema import format_constraint
 
-
-class EUser(WorkflowableEntityType):
+class CWUser(WorkflowableEntityType):
     """define a CubicWeb user"""
     meta = True # XXX backported from old times, shouldn't be there anymore
     permissions = {
@@ -26,12 +24,12 @@
     surname   = String(maxsize=64)
     last_login_time  = Datetime(description=_('last connection date'))
     # allowing an email to be the primary email of multiple entities is necessary for
-    # test at least :-/    
+    # test at least :-/
     primary_email = SubjectRelation('EmailAddress', cardinality='??',
                                     description=_('email address to use for notification'))
     use_email     = SubjectRelation('EmailAddress', cardinality='*?', composite='subject')
 
-    in_group = SubjectRelation('EGroup', cardinality='+*',
+    in_group = SubjectRelation('CWGroup', cardinality='+*',
                                constraints=[RQLConstraint('NOT O name "owners"')],
                                description=_('groups grant permissions to the user'))
 
@@ -44,9 +42,9 @@
         'delete': ('managers', 'owners', ERQLExpression('P use_email X, U has_update_permission P')),
         'update': ('managers', 'owners', ERQLExpression('P use_email X, U has_update_permission P')),
         }
-    
+
     alias   = String(fulltextindexed=True, maxsize=56)
-    address = String(required=True, fulltextindexed=True, 
+    address = String(required=True, fulltextindexed=True,
                      indexed=True, unique=True, maxsize=128)
     canonical = Boolean(default=False,
                         description=_('when multiple addresses are equivalent \
@@ -66,7 +64,7 @@
 class primary_email(RelationType):
     """the prefered email"""
     permissions = use_email.permissions
-    
+
 class identical_to(RelationType):
     """identical_to"""
     symetric = True
@@ -85,22 +83,22 @@
 class in_group(MetaRelationType):
     """core relation indicating a user's groups"""
     meta = False
-    
+
 class owned_by(MetaRelationType):
     """core relation indicating owners of an entity. This relation
     implicitly put the owner into the owners group for the entity
     """
     permissions = {
         'read':   ('managers', 'users', 'guests'),
-        'add':    ('managers', RRQLExpression('S owned_by U'),), 
+        'add':    ('managers', RRQLExpression('S owned_by U'),),
         'delete': ('managers', RRQLExpression('S owned_by U'),),
         }
     # 0..n cardinality for entities created by internal session (no attached user)
     # and to support later deletion of a user which has created some entities
     cardinality = '**'
     subject = '**'
-    object = 'EUser'
-    
+    object = 'CWUser'
+
 class created_by(MetaRelationType):
     """core relation indicating the original creator of an entity"""
     permissions = {
@@ -110,11 +108,11 @@
         }
     # 0..1 cardinality for entities created by internal session (no attached user)
     # and to support later deletion of a user which has created some entities
-    cardinality = '?*' 
+    cardinality = '?*'
     subject = '**'
-    object = 'EUser'
+    object = 'CWUser'
 
-    
+
 class creation_date(MetaAttributeRelationType):
     """creation time of an entity"""
     cardinality = '11'
@@ -126,8 +124,9 @@
     cardinality = '11'
     subject = '**'
     object = 'Datetime'
-    
-class EProperty(EntityType):
+
+
+class CWProperty(EntityType):
     """used for cubicweb configuration. Once a property has been created you
     can't change the key.
     """
@@ -144,8 +143,8 @@
                                 'You must select this first to be able to set '
                                 'value'))
     value = String(internationalizable=True, maxsize=256)
-    
-    for_user = SubjectRelation('EUser', cardinality='?*', composite='object',
+
+    for_user = SubjectRelation('CWUser', cardinality='?*', composite='object',
                                description=_('user for which this property is '
                                              'applying. If this relation is not '
                                              'set, the property is considered as'
@@ -164,17 +163,17 @@
     inlined = True
 
 
-class EPermission(MetaEntityType):
+class CWPermission(MetaEntityType):
     """entity type that may be used to construct some advanced security configuration
     """
     name = String(required=True, indexed=True, internationalizable=True, maxsize=100,
                   description=_('name or identifier of the permission'))
     label = String(required=True, internationalizable=True, maxsize=100,
                    description=_('distinct label to distinguate between other permission entity of the same name'))
-    require_group = SubjectRelation('EGroup', 
+    require_group = SubjectRelation('CWGroup',
                                     description=_('groups to which the permission is granted'))
 
-# explicitly add X require_permission EPermission for each entity that should have
+# explicitly add X require_permission CWPermission for each entity that should have
 # configurable security
 class require_permission(RelationType):
     """link a permission to the entity. This permission should be used in the
@@ -185,7 +184,7 @@
         'add':    ('managers',),
         'delete': ('managers',),
         }
-    
+
 class require_group(MetaRelationType):
     """used to grant a permission to a group"""
     permissions = {
@@ -194,12 +193,13 @@
         'delete': ('managers',),
         }
 
-    
+
 class see_also(RelationType):
     """generic relation to link one entity to another"""
     symetric = True
 
-class ECache(MetaEntityType):
+
+class CWCache(MetaEntityType):
     """a simple cache entity characterized by a name and
     a validity date.
 
@@ -215,6 +215,6 @@
         'delete': ('managers',),
         }
 
-    name = String(required=True, unique=True, indexed=True, 
+    name = String(required=True, unique=True, indexed=True,  maxsize=128,
                   description=_('name of the cache'))
     timestamp = Datetime(default='NOW')
--- a/schemas/bootstrap.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/schemas/bootstrap.py	Fri Apr 24 19:46:47 2009 +0200
@@ -10,18 +10,18 @@
 
 # not restricted since as "is" is handled as other relations, guests need
 # access to this
-class EEType(MetaEntityType):
+class CWEType(MetaEntityType):
     """define an entity type, used to build the application schema"""
     name = String(required=True, indexed=True, internationalizable=True,
                   unique=True, maxsize=64)
-    description = RichString(internationalizable=True, 
+    description = RichString(internationalizable=True,
                              description=_('semantic description of this entity type'))
     meta = Boolean(description=_('is it an application entity type or not ?'))
     # necessary to filter using RQL
     final = Boolean(description=_('automatic'))
 
 
-class ERType(MetaEntityType):
+class CWRType(MetaEntityType):
     """define a relation type, used to build the application schema"""
     name = String(required=True, indexed=True, internationalizable=True,
                   unique=True, maxsize=64)
@@ -39,61 +39,61 @@
     final = Boolean(description=_('automatic'))
 
 
-class EFRDef(MetaEntityType):
+class CWAttribute(MetaEntityType):
     """define a final relation: link a final relation type from a non final
-    entity to a final entity type. 
+    entity to a final entity type.
 
     used to build the application schema
     """
-    relation_type = SubjectRelation('ERType', cardinality='1*',
+    relation_type = SubjectRelation('CWRType', cardinality='1*',
                                     constraints=[RQLConstraint('O final TRUE')],
                                     composite='object')
-    from_entity = SubjectRelation('EEType', cardinality='1*',
+    from_entity = SubjectRelation('CWEType', cardinality='1*',
                                   constraints=[RQLConstraint('O final FALSE')],
                                   composite='object')
-    to_entity = SubjectRelation('EEType', cardinality='1*',
+    to_entity = SubjectRelation('CWEType', cardinality='1*',
                                 constraints=[RQLConstraint('O final TRUE')],
                                 composite='object')
-    constrained_by = SubjectRelation('EConstraint', cardinality='*1', composite='subject')
-    
+    constrained_by = SubjectRelation('CWConstraint', cardinality='*1', composite='subject')
+
     cardinality = String(maxsize=2, internationalizable=True,
-                         vocabulary=[_('?1'), _('11'), _('??'), _('1?')], 
+                         vocabulary=[_('?1'), _('11'), _('??'), _('1?')],
                          description=_('subject/object cardinality'))
     ordernum = Int(description=('control subject entity\'s relations order'), default=0)
-    
+
     indexed = Boolean(description=_('create an index for quick search on this attribute'))
     fulltextindexed = Boolean(description=_('index this attribute\'s value in the plain text index'))
     internationalizable = Boolean(description=_('is this attribute\'s value translatable'))
     defaultval = String(maxsize=256)
-    
+
     description_format = String(meta=True, internationalizable=True, maxsize=50,
                                 default='text/plain', constraints=[format_constraint])
     description = String(internationalizable=True,
                          description=_('semantic description of this attribute'))
-    
+
 
-CARDINALITY_VOCAB = [_('?*'), _('1*'), _('+*'), _('**'), 
-                     _('?+'), _('1+'), _('++'), _('*+'), 
+CARDINALITY_VOCAB = [_('?*'), _('1*'), _('+*'), _('**'),
+                     _('?+'), _('1+'), _('++'), _('*+'),
                      _('?1'), _('11'), _('+1'), _('*1'),
                      _('??'), _('1?'), _('+?'), _('*?')]
 
-class ENFRDef(MetaEntityType):
+class CWRelation(MetaEntityType):
     """define a non final relation: link a non final relation type from a non
-    final entity to a non final entity type. 
+    final entity to a non final entity type.
 
     used to build the application schema
     """
-    relation_type = SubjectRelation('ERType', cardinality='1*',
+    relation_type = SubjectRelation('CWRType', cardinality='1*',
                                     constraints=[RQLConstraint('O final FALSE')],
                                     composite='object')
-    from_entity = SubjectRelation('EEType', cardinality='1*',
+    from_entity = SubjectRelation('CWEType', cardinality='1*',
                                   constraints=[RQLConstraint('O final FALSE')],
                                   composite='object')
-    to_entity = SubjectRelation('EEType', cardinality='1*',
+    to_entity = SubjectRelation('CWEType', cardinality='1*',
                                 constraints=[RQLConstraint('O final FALSE')],
                                 composite='object')
-    constrained_by = SubjectRelation('EConstraint', cardinality='*1', composite='subject')
-    
+    constrained_by = SubjectRelation('CWConstraint', cardinality='*1', composite='subject')
+
     cardinality = String(maxsize=2, internationalizable=True,
                          vocabulary=CARDINALITY_VOCAB,
                          description=_('subject/object cardinality'))
@@ -105,12 +105,12 @@
                                      'deleted.'),
                        vocabulary=('', _('subject'), _('object')),
                        maxsize=8, default=None)
-    
+
     description_format = String(meta=True, internationalizable=True, maxsize=50,
                                 default='text/plain', constraints=[format_constraint])
     description = String(internationalizable=True,
                          description=_('semantic description of this relation'))
-    
+
 
 # not restricted since it has to be read when checking allowed transitions
 class RQLExpression(MetaEntityType):
@@ -120,7 +120,7 @@
                       description=_('name of the main variables which should be '
                                     'used in the selection if necessary (comma '
                                     'separated)'))
-    expression = String(required=True, 
+    expression = String(required=True,
                         description=_('restriction part of a rql query. '
                                       'For entity rql expression, X and U are '
                                       'predefined respectivly to the current object and to '
@@ -129,45 +129,45 @@
                                       'relation\'subject, object and to '
                                       'the request user. '))
 
-    read_permission = ObjectRelation(('EEType', 'ERType'), cardinality='+?', composite='subject',
+    read_permission = ObjectRelation(('CWEType', 'CWRType'), cardinality='+?', composite='subject',
                                       description=_('rql expression allowing to read entities/relations of this type'))
-    add_permission = ObjectRelation(('EEType', 'ERType'), cardinality='*?', composite='subject',
+    add_permission = ObjectRelation(('CWEType', 'CWRType'), cardinality='*?', composite='subject',
                                      description=_('rql expression allowing to add entities/relations of this type'))
-    delete_permission = ObjectRelation(('EEType', 'ERType'), cardinality='*?', composite='subject',
+    delete_permission = ObjectRelation(('CWEType', 'CWRType'), cardinality='*?', composite='subject',
                                         description=_('rql expression allowing to delete entities/relations of this type'))
-    update_permission = ObjectRelation('EEType', cardinality='*?', composite='subject',
+    update_permission = ObjectRelation('CWEType', cardinality='*?', composite='subject',
                                         description=_('rql expression allowing to update entities of this type'))
-    
+
 
-class EConstraint(MetaEntityType):
+class CWConstraint(MetaEntityType):
     """define a schema constraint"""
-    cstrtype = SubjectRelation('EConstraintType', cardinality='1*')
+    cstrtype = SubjectRelation('CWConstraintType', cardinality='1*')
     value = String(description=_('depends on the constraint type'))
 
 
-class EConstraintType(MetaEntityType):
+class CWConstraintType(MetaEntityType):
     """define a schema constraint type"""
     name = String(required=True, indexed=True, internationalizable=True,
                   unique=True, maxsize=64)
 
 
 # not restricted since it has to be read when checking allowed transitions
-class EGroup(MetaEntityType):
+class CWGroup(MetaEntityType):
     """define a CubicWeb users group"""
     name = String(required=True, indexed=True, internationalizable=True,
                   unique=True, maxsize=64)
 
-    read_permission = ObjectRelation(('EEType', 'ERType'), cardinality='+*',
+    read_permission = ObjectRelation(('CWEType', 'CWRType'), cardinality='+*',
                                       description=_('groups allowed to read entities/relations of this type'))
-    add_permission = ObjectRelation(('EEType', 'ERType'),
+    add_permission = ObjectRelation(('CWEType', 'CWRType'),
                                      description=_('groups allowed to add entities/relations of this type'))
-    delete_permission = ObjectRelation(('EEType', 'ERType'),
+    delete_permission = ObjectRelation(('CWEType', 'CWRType'),
                                         description=_('groups allowed to delete entities/relations of this type'))
-    update_permission = ObjectRelation('EEType',
+    update_permission = ObjectRelation('CWEType',
                                         description=_('groups allowed to update entities of this type'))
-    
-    
-    
+
+
+
 class relation_type(MetaRelationType):
     """link a relation definition to its relation type"""
     inlined = True
@@ -179,7 +179,7 @@
     inlined = True
 class constrained_by(MetaRelationType):
     """constraints applying on this relation"""
-    
+
 class cstrtype(MetaRelationType):
     """constraint factory"""
     inlined = True
@@ -214,7 +214,7 @@
         }
     cardinality = '1*'
     subject = '**'
-    object = 'EEType'
+    object = 'CWEType'
 
 class is_instance_of(MetaRelationType):
     """core relation indicating the types (including specialized types)
@@ -229,7 +229,7 @@
         }
     cardinality = '+*'
     subject = '**'
-    object = 'EEType'
+    object = 'CWEType'
 
 class specializes(MetaRelationType):
     name = 'specializes'
@@ -239,5 +239,5 @@
         'delete': ('managers',),
         }
     cardinality = '?*'
-    subject = 'EEType'
-    object = 'EEType'
+    subject = 'CWEType'
+    object = 'CWEType'
--- a/schemas/workflow.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/schemas/workflow.py	Fri Apr 24 19:46:47 2009 +0200
@@ -14,14 +14,14 @@
     description = RichString(fulltextindexed=True, default_format='text/rest',
                              description=_('semantic description of this state'))
     
-    state_of = SubjectRelation('EEType', cardinality='+*',
+    state_of = SubjectRelation('CWEType', cardinality='+*',
                     description=_('entity types which may use this state'),
                     constraints=[RQLConstraint('O final FALSE')])
     allowed_transition = SubjectRelation('Transition', cardinality='**',
                                          constraints=[RQLConstraint('S state_of ET, O transition_of ET')],
                                          description=_('allowed transitions from this state'))
     
-    initial_state = ObjectRelation('EEType', cardinality='?*',
+    initial_state = ObjectRelation('CWEType', cardinality='?*',
                                    # S initial_state O, O state_of S
                                    constraints=[RQLConstraint('O state_of S')],
                                    description=_('initial state for entities of this type'))
@@ -44,10 +44,10 @@
                                               'that will respectivly represents '
                                               'the current entity and the current user'))
     
-    require_group = SubjectRelation('EGroup', cardinality='**',
+    require_group = SubjectRelation('CWGroup', cardinality='**',
                                     description=_('group in which a user should be to be '
                                                   'allowed to pass this transition'))
-    transition_of = SubjectRelation('EEType', cardinality='+*',
+    transition_of = SubjectRelation('CWEType', cardinality='+*',
                                     description=_('entity types which may use this transition'),
                                     constraints=[RQLConstraint('O final FALSE')])
     destination_state = SubjectRelation('State', cardinality='?*',
@@ -101,7 +101,7 @@
     """indicate the current state of an entity"""
     meta = True
     # not inlined intentionnaly since when using ldap sources, user'state
-    # has to be stored outside the EUser table
+    # has to be stored outside the CWUser table
     
     # add/delete perms given to managers/users, after what most of the job
     # is done by workflow enforcment
--- a/selectors.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/selectors.py	Fri Apr 24 19:46:47 2009 +0200
@@ -33,7 +33,7 @@
     selectors.TRACED_OIDS = ('calendar',)
     self.view('calendar', myrset)
     selectors.TRACED_OIDS = ()
- 
+
 
 :organization: Logilab
 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
@@ -97,11 +97,11 @@
     >>> with traced_selection( ('oid1', 'oid2') ):
     ...     # some code in which you want to debug selectors
     ...     # for objects with id 'oid1' and 'oid2'
-    
+
     """
     def __init__(self, traced='all'):
         self.traced = traced
-        
+
     def __enter__(self):
         global TRACED_OIDS
         TRACED_OIDS = self.traced
@@ -112,12 +112,34 @@
         return traceback is None
 
 
+def score_interface(cls_or_inst, cls, iface):
+    """Return true if the give object (maybe an instance or class) implements
+    the interface.
+    """
+    if getattr(iface, '__registry__', None) == 'etypes':
+        # adjust score if the interface is an entity class
+        parents = cls_or_inst.parent_classes()
+        if iface is cls:
+            return len(parents) + 4
+        if iface is parents[-1]: # Any
+            return 1
+        for index, etype in enumerate(reversed(parents[:-1])):
+            basecls = vreg.etype_class(etype)
+            if iface is basecls:
+                return index + 3
+        return 0
+    if implements_iface(cls_or_inst, iface):
+        # implenting an interface takes precedence other special Any interface
+        return 2
+    return 0
+
+
 # abstract selectors ##########################################################
 
 class PartialSelectorMixIn(object):
     """convenience mix-in for selectors that will look into the containing
     class to find missing information.
-    
+
     cf. `cubicweb.web.action.LinkToEntityAction` for instance
     """
     def __call__(self, cls, *args, **kwargs):
@@ -135,7 +157,7 @@
     def __str__(self):
         return '%s(%s)' % (self.__class__.__name__,
                            ','.join(str(s) for s in self.expected_ifaces))
-    
+
     def score_interfaces(self, cls_or_inst, cls):
         score = 0
         vreg, eschema = cls_or_inst.vreg, cls_or_inst.e_schema
@@ -146,24 +168,7 @@
                     iface = vreg.etype_class(iface)
                 except KeyError:
                     continue # entity type not in the schema
-            if implements_iface(cls_or_inst, iface):
-                if getattr(iface, '__registry__', None) == 'etypes':
-                    # adjust score if the interface is an entity class
-                    if iface is cls:
-                        score += len(eschema.ancestors()) + 4
-                    else: 
-                        parents = [e.type for e in eschema.ancestors()]
-                        for index, etype in enumerate(reversed(parents)):
-                            basecls = vreg.etype_class(etype)
-                            if iface is basecls:
-                                score += index + 3
-                                break
-                        else: # Any
-                            score += 1
-                else:
-                    # implenting an interface takes precedence other special Any
-                    # interface
-                    score += 2
+            score += score_interface(cls_or_inst, cls, iface)
         return score
 
 
@@ -182,7 +187,7 @@
     """
     def __init__(self, once_is_enough=False):
         self.once_is_enough = once_is_enough
-    
+
     @lltrace
     def __call__(self, cls, req, rset, row=None, col=0, **kwargs):
         if not rset:
@@ -208,7 +213,7 @@
         if etype in BASE_TYPES:
             return 0
         return self.score_class(cls.vreg.etype_class(etype), req)
-        
+
     def score_class(self, eclass, req):
         raise NotImplementedError()
 
@@ -231,7 +236,7 @@
     note: None values (resulting from some outer join in the query) are not
           considered.
     """
-    
+
     @lltrace
     def __call__(self, cls, req, rset, row=None, col=0, **kwargs):
         if not rset and not kwargs.get('entity'):
@@ -260,7 +265,7 @@
             return self.score_entity(rset.get_entity(row, col))
         except NotAnEntity:
             return 0
-                                 
+
     def score_entity(self, entity):
         raise NotImplementedError()
 
@@ -297,7 +302,7 @@
     if rset is not None and rset.rowcount:
         return 1
     return 0
-    
+
 @objectify_selector
 @lltrace
 def empty_rset(cls, req, rset, *args, **kwargs):
@@ -336,7 +341,7 @@
 @lltrace
 def paginated_rset(cls, req, rset, *args, **kwargs):
     """accept result set with more lines than the page size.
-    
+
     Page size is searched in (respecting order):
     * a page_size argument
     * a page_size form parameters
@@ -437,7 +442,7 @@
 class match_search_state(Selector):
     """accept if the current request search state is in one of the expected
     states given to the initializer
-    
+
     :param expected: either 'normal' or 'linksearch' (eg searching for an
                      object to create a relation with another)
     """
@@ -448,7 +453,7 @@
     def __str__(self):
         return '%s(%s)' % (self.__class__.__name__,
                            ','.join(sorted(str(s) for s in self.expected)))
-        
+
     @lltrace
     def __call__(self, cls, req, rset, row=None, col=0, **kwargs):
         try:
@@ -462,7 +467,7 @@
 class match_form_params(match_search_state):
     """accept if parameters specified as initializer arguments are specified
     in request's form parameters
-    
+
     :param *expected: parameters (eg `basestring`) which are expected to be
                       found in request's form parameters
     """
@@ -481,7 +486,7 @@
 class match_kwargs(match_search_state):
     """accept if parameters specified as initializer arguments are specified
     in named arguments given to the selector
-    
+
     :param *expected: parameters (eg `basestring`) which are expected to be
                       found in named arguments (kwargs)
     """
@@ -497,7 +502,7 @@
 class match_user_groups(match_search_state):
     """accept if logged users is in at least one of the given groups. Returned
     score is the number of groups in which the user is.
-    
+
     If the special 'owners' group is given:
     * if row is specified check the entity at the given row/col is owned by the
       logged user
@@ -507,7 +512,7 @@
     :param *required_groups: name of groups (`basestring`) in which the logged
                              user should be
     """
-    
+
     @lltrace
     def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
         user = req.user
@@ -545,7 +550,7 @@
     def __init__(self, registry, oid):
         self.registry = registry
         self.oid = oid
-        
+
     def __call__(self, cls, req, rset, *args, **kwargs):
         try:
             cls.vreg.select_object(self.registry, self.oid, req, rset, *args, **kwargs)
@@ -567,7 +572,7 @@
                              or an entity type (e.g. `basestring`) in which case
                              the associated class will be searched in the
                              registry (at selection time)
-                             
+
     note: when interface is an entity class, the score will reflect class
           proximity so the most specific object'll be selected
     """
@@ -584,11 +589,11 @@
                              or an entity type (e.g. `basestring`) in which case
                              the associated class will be searched in the
                              registry (at selection time)
-                             
+
     note: when interface is an entity class, the score will reflect class
           proximity so the most specific object'll be selected
     """
-    
+
     @lltrace
     def __call__(self, cls, req, *args, **kwargs):
         try:
@@ -612,10 +617,10 @@
                              or an entity type (e.g. `basestring`) in which case
                              the associated class will be searched in the
                              registry (at selection time)
-                             
+
     note: when interface is an entity class, the score will reflect class
           proximity so the most specific object'll be selected
-    """    
+    """
     def score_entity(self, entity):
         return self.score_interfaces(entity, entity.__class__)
 
@@ -650,7 +655,7 @@
             return 0
         score = super(relation_possible, self).__call__(cls, req, *args, **kwargs)
         return score
-        
+
     def score_class(self, eclass, req):
         eschema = eclass.e_schema
         try:
@@ -679,12 +684,12 @@
     for this selector are:
 
     - `rtype`: same as `rtype` parameter of the `relation_possible` selector
-    
+
     - `role`: this attribute will be passed to the `cubicweb.role` function
       to determine the role of class in the relation
 
     - `etype` (optional): the entity type on the other side of the relation
-    
+
     :param action: a relation schema action (one of 'read', 'add', 'delete')
                    which must be granted to the logged user, else a 0 score will
                    be returned
@@ -702,19 +707,19 @@
 class may_add_relation(EntitySelector):
     """accept if the relation can be added to an entity found in the result set
     by the logged user.
-    
+
     See `EntitySelector` documentation for behaviour when row is not specified.
 
     :param rtype: a relation type (`basestring`)
     :param role: the role of the result set entity in the relation. 'subject' or
                  'object', default to 'subject'.
     """
-    
+
     def __init__(self, rtype, role='subject', once_is_enough=False):
         super(may_add_relation, self).__init__(once_is_enough)
         self.rtype = rtype
         self.role = role
-        
+
     def score_entity(self, entity):
         rschema = entity.schema.rschema(self.rtype)
         if self.role == 'subject':
@@ -733,10 +738,10 @@
     for this selector are:
 
     - `rtype`: same as `rtype` parameter of the `relation_possible` selector
-    
+
     - `role`: this attribute will be passed to the `cubicweb.role` function
       to determine the role of class in the relation.
-    
+
     :param action: a relation schema action (one of 'read', 'add', 'delete')
                    which must be granted to the logged user, else a 0 score will
                    be returned
@@ -748,12 +753,12 @@
         self.rtype = cls.rtype
         self.role = role(cls)
 
-    
+
 class has_related_entities(EntitySelector):
     """accept if entity found in the result set has some linked entities using
     the specified relation (optionaly filtered according to the specified target
     type). Checks first if the relation is possible.
-    
+
     See `EntitySelector` documentation for behaviour when row is not specified.
 
     :param rtype: a relation type (`basestring`)
@@ -768,7 +773,7 @@
         self.rtype = rtype
         self.role = role
         self.target_etype = target_etype
-    
+
     def score_entity(self, entity):
         relpossel = relation_possible(self.rtype, self.role, self.target_etype)
         if not relpossel.score_class(entity.__class__, entity.req):
@@ -787,12 +792,12 @@
     for this selector are:
 
     - `rtype`: same as `rtype` parameter of the `relation_possible` selector
-    
+
     - `role`: this attribute will be passed to the `cubicweb.role` function
       to determine the role of class in the relation.
 
     - `etype` (optional): the entity type on the other side of the relation
-    
+
     :param action: a relation schema action (one of 'read', 'add', 'delete')
                    which must be granted to the logged user, else a 0 score will
                    be returned
@@ -817,13 +822,13 @@
 
     note: None values (resulting from some outer join in the query) are not
           considered.
-    
+
     :param action: an entity schema action (eg 'read'/'add'/'delete'/'update')
     """
     def __init__(self, action, once_is_enough=False):
         super(has_permission, self).__init__(once_is_enough)
         self.action = action
-        
+
     @lltrace
     def __call__(self, cls, req, rset, row=None, col=0, **kwargs):
         if rset is None:
@@ -832,7 +837,7 @@
         action = self.action
         if row is None:
             score = 0
-            need_local_check = [] 
+            need_local_check = []
             geteschema = cls.schema.eschema
             for etype in rset.column_types(0):
                 if etype in BASE_TYPES:
@@ -857,7 +862,7 @@
                 score += 1
             return score
         return self.score(req, rset, row, col)
-    
+
     def score_entity(self, entity):
         if entity.has_perm(self.action):
             return 1
@@ -882,7 +887,7 @@
     """accept if an arbitrary rql return some results for an eid found in the
     result set. Returned score is the number of items returned by the rql
     condition.
-    
+
     See `EntitySelector` documentation for behaviour when row is not specified.
 
     :param expression: basestring containing an rql expression, which should use
@@ -899,7 +904,7 @@
         else:
             rql = 'Any X WHERE X eid %%(x)s, %s' % expression
         self.rql = rql
-        
+
     def score(self, req, rset, row, col):
         try:
             return len(req.execute(self.rql, {'x': rset[row][col],
@@ -907,32 +912,32 @@
         except Unauthorized:
             return 0
 
-        
+
 class but_etype(EntitySelector):
     """accept if the given entity types are not found in the result set.
 
     See `EntitySelector` documentation for behaviour when row is not specified.
-    
+
     :param *etypes: entity types (`basestring`) which should be refused
     """
     def __init__(self, *etypes):
         super(but_etype, self).__init__()
         self.but_etypes = etypes
-        
+
     def score(self, req, rset, row, col):
         if rset.description[row][col] in self.but_etypes:
             return 0
         return 1
 
-                
+
 class score_entity(EntitySelector):
     """accept if some arbitrary function return a positive score for an entity
     found in the result set.
-    
+
     See `EntitySelector` documentation for behaviour when row is not specified.
 
     :param scorefunc: callable expected to take an entity as argument and to
-                      return a score >= 0 
+                      return a score >= 0
     """
     def __init__(self, scorefunc, once_is_enough=False):
         super(score_entity, self).__init__(once_is_enough)
@@ -1017,7 +1022,7 @@
 
 rqlcondition_selector = deprecated_function(chainall(non_final_entity(), one_line_rset, _rql_condition,
                          name='rql_condition'))
-    
+
 def but_etype_selector(cls, req, rset, row=None, col=0, **kwargs):
     return but_etype(cls.etype)(cls, req, rset, row, col)
 but_etype_selector = deprecated_function(but_etype_selector)
@@ -1074,7 +1079,7 @@
         warn(msg, DeprecationWarning)
         return registered(cls, vreg)
     return _deprecate
-    
+
 @unbind_method
 def require_group_compat(registered):
     def plug_selector(cls, vreg):
@@ -1118,7 +1123,7 @@
             cls.__select__ &= rql_condition(cls.condition)
         return cls
     return plug_selector
-     
+
 @unbind_method
 def has_relation_compat(registered):
     def plug_selector(cls, vreg):
--- a/server/__init__.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/__init__.py	Fri Apr 24 19:46:47 2009 +0200
@@ -93,10 +93,10 @@
     print 'inserting default user and groups'
     needisfix = []
     for group in BASEGROUPS:
-        rset = session.execute('INSERT EGroup X: X name %(name)s',
+        rset = session.execute('INSERT CWGroup X: X name %(name)s',
                                {'name': unicode(group)})
         needisfix.append( (rset.rows[0][0], rset.description[0][0]) )
-    rset = session.execute('INSERT EUser X: X login %(login)s, X upassword %(pwd)s',
+    rset = session.execute('INSERT CWUser X: X login %(login)s, X upassword %(pwd)s',
                            {'login': login, 'pwd': pwd})
     needisfix.append( (rset.rows[0][0], rset.description[0][0]) )
     session.execute('SET U in_group G WHERE G name "managers"')
@@ -116,10 +116,10 @@
         handler.session.unsafe_execute('SET X is_instance_of E WHERE X eid %(x)s, E name %(name)s',
                                        {'x': eid, 'name': etype}, 'x')
     # insert versions
-    handler.cmd_add_entity('EProperty', pkey=u'system.version.cubicweb',
+    handler.cmd_add_entity('CWProperty', pkey=u'system.version.cubicweb',
                            value=unicode(config.cubicweb_version()))
     for cube in config.cubes():
-        handler.cmd_add_entity('EProperty', 
+        handler.cmd_add_entity('CWProperty', 
                                pkey=u'system.version.%s' % cube.lower(),
                                value=unicode(config.cube_version(cube)))
     # yoo !
--- a/server/checkintegrity.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/checkintegrity.py	Fri Apr 24 19:46:47 2009 +0200
@@ -111,7 +111,7 @@
                           'VocabularyConstraint', 'RQLConstraint',
                           'RQLVocabularyConstraint')
     rql = ('Any COUNT(X),RN,EN,ECTN GROUPBY RN,EN,ECTN ORDERBY 1 '
-           'WHERE X is EConstraint, R constrained_by X, '
+           'WHERE X is CWConstraint, R constrained_by X, '
            'R relation_type RT, R from_entity ET, RT name RN, '
            'ET name EN, X cstrtype ECT, ECT name ECTN')
     for count, rn, en, cstrname in session.execute(rql):
@@ -252,7 +252,7 @@
                     print >> sys.stderr, ' [FIXED]'
                 else:
                     print >> sys.stderr
-    cursor = session.system_sql('SELECT MIN(%s) FROM %sEUser;' % (eidcolumn,
+    cursor = session.system_sql('SELECT MIN(%s) FROM %sCWUser;' % (eidcolumn,
                                                                   SQL_PREFIX))
     default_user_eid = cursor.fetchone()[0]
     assert default_user_eid is not None, 'no user defined !'
--- a/server/hooks.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/hooks.py	Fri Apr 24 19:46:47 2009 +0200
@@ -125,8 +125,8 @@
     hm.register_hook(fti_update_after_delete_relation, 'after_delete_relation', '')
     if 'is' in hm.schema:
         hm.register_hook(setis_after_add_entity, 'after_add_entity', '')
-    if 'EUser' in hm.schema:
-        hm.register_hook(setowner_after_add_user, 'after_add_entity', 'EUser')
+    if 'CWUser' in hm.schema:
+        hm.register_hook(setowner_after_add_user, 'after_add_entity', 'CWUser')
             
 # core hooks ##################################################################
     
@@ -282,7 +282,7 @@
 
 def _register_core_hooks(hm):
     hm.register_hook(handle_composite_before_del_relation, 'before_delete_relation', '')
-    hm.register_hook(before_del_group, 'before_delete_entity', 'EGroup')
+    hm.register_hook(before_del_group, 'before_delete_entity', 'CWGroup')
     
     #hm.register_hook(cstrcheck_before_update_entity, 'before_update_entity', '')
     hm.register_hook(cardinalitycheck_after_add_entity, 'after_add_entity', '')
@@ -362,7 +362,7 @@
     
 def _register_usergroup_hooks(hm):
     """register user/group related hooks on the hooks manager"""
-    hm.register_hook(after_del_user, 'after_delete_entity', 'EUser')
+    hm.register_hook(after_del_user, 'after_delete_entity', 'CWUser')
     hm.register_hook(after_add_in_group, 'after_add_relation', 'in_group')
     hm.register_hook(after_del_in_group, 'after_delete_relation', 'in_group')
 
@@ -442,10 +442,10 @@
                                  str(eschema))
 
 
-# EProperty hooks #############################################################
+# CWProperty hooks #############################################################
 
 
-class DelEPropertyOp(Operation):
+class DelCWPropertyOp(Operation):
     """a user's custom properties has been deleted"""
     
     def commit_event(self):
@@ -455,14 +455,14 @@
         except KeyError:
             self.error('%s has no associated value', self.key)
 
-class ChangeEPropertyOp(Operation):
+class ChangeCWPropertyOp(Operation):
     """a user's custom properties has been added/changed"""
         
     def commit_event(self):
         """the observed connections pool has been commited"""
         self.epropdict[self.key] = self.value
 
-class AddEPropertyOp(Operation):
+class AddCWPropertyOp(Operation):
     """a user's custom properties has been added/changed"""
         
     def commit_event(self):
@@ -470,7 +470,7 @@
         eprop = self.eprop
         if not eprop.for_user:
             self.repo.vreg.eprop_values[eprop.pkey] = eprop.value
-        # if for_user is set, update is handled by a ChangeEPropertyOp operation
+        # if for_user is set, update is handled by a ChangeCWPropertyOp operation
 
 def after_add_eproperty(session, entity):
     key, value = entity.pkey, entity.value
@@ -484,7 +484,7 @@
         session.unsafe_execute('SET P for_user U WHERE P eid %(x)s,U eid %(u)s',
                                {'x': entity.eid, 'u': session.user.eid}, 'x')
     else:
-        AddEPropertyOp(session, eprop=entity)
+        AddCWPropertyOp(session, eprop=entity)
         
 def after_update_eproperty(session, entity):
     key, value = entity.pkey, entity.value
@@ -496,11 +496,11 @@
         raise ValidationError(entity.eid, {'value': session._(str(ex))})
     if entity.for_user:
         for session_ in get_user_sessions(session.repo, entity.for_user[0].eid):
-            ChangeEPropertyOp(session, epropdict=session_.user.properties,
+            ChangeCWPropertyOp(session, epropdict=session_.user.properties,
                               key=key, value=value)
     else:
         # site wide properties
-        ChangeEPropertyOp(session, epropdict=session.vreg.eprop_values,
+        ChangeCWPropertyOp(session, epropdict=session.vreg.eprop_values,
                           key=key, value=value)
         
 def before_del_eproperty(session, eid):
@@ -511,10 +511,10 @@
     else:
         key = session.execute('Any K WHERE P eid %(x)s, P pkey K',
                               {'x': eid}, 'x')[0][0]
-        DelEPropertyOp(session, epropdict=session.vreg.eprop_values, key=key)
+        DelCWPropertyOp(session, epropdict=session.vreg.eprop_values, key=key)
 
 def after_add_for_user(session, fromeid, rtype, toeid):
-    if not session.describe(fromeid)[0] == 'EProperty':
+    if not session.describe(fromeid)[0] == 'CWProperty':
         return
     key, value = session.execute('Any K,V WHERE P eid %(x)s,P pkey K,P value V',
                                  {'x': fromeid}, 'x')[0]
@@ -522,7 +522,7 @@
         raise ValidationError(fromeid,
                               {'for_user': session._("site-wide property can't be set for user")})
     for session_ in get_user_sessions(session.repo, toeid):
-        ChangeEPropertyOp(session, epropdict=session_.user.properties,
+        ChangeCWPropertyOp(session, epropdict=session_.user.properties,
                           key=key, value=value)
         
 def before_del_for_user(session, fromeid, rtype, toeid):
@@ -530,12 +530,12 @@
                           {'x': fromeid}, 'x')[0][0]
     relation_deleted(session, fromeid, rtype, toeid)
     for session_ in get_user_sessions(session.repo, toeid):
-        DelEPropertyOp(session, epropdict=session_.user.properties, key=key)
+        DelCWPropertyOp(session, epropdict=session_.user.properties, key=key)
 
 def _register_eproperty_hooks(hm):
     """register workflow related hooks on the hooks manager"""
-    hm.register_hook(after_add_eproperty, 'after_add_entity', 'EProperty')
-    hm.register_hook(after_update_eproperty, 'after_update_entity', 'EProperty')
-    hm.register_hook(before_del_eproperty, 'before_delete_entity', 'EProperty')
+    hm.register_hook(after_add_eproperty, 'after_add_entity', 'CWProperty')
+    hm.register_hook(after_update_eproperty, 'after_update_entity', 'CWProperty')
+    hm.register_hook(before_del_eproperty, 'before_delete_entity', 'CWProperty')
     hm.register_hook(after_add_for_user, 'after_add_relation', 'for_user')
     hm.register_hook(before_del_for_user, 'before_delete_relation', 'for_user')
--- a/server/migractions.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/migractions.py	Fri Apr 24 19:46:47 2009 +0200
@@ -21,13 +21,15 @@
 from os.path import join, exists
 from datetime import datetime
 
+from logilab.common.deprecation import deprecated_function, obsolete
 from logilab.common.decorators import cached
 from logilab.common.adbh import get_adv_func_helper
 
 from yams.constraints import SizeConstraint
 from yams.schema2sql import eschema2sql, rschema2sql
 
-from cubicweb import AuthenticationError
+from cubicweb import AuthenticationError, ETYPE_NAME_MAP
+from cubicweb.schema import CubicWebRelationSchema
 from cubicweb.dbapi import get_repository, repo_connect
 from cubicweb.common.migration import MigrationHelper, yes
 
@@ -38,43 +40,7 @@
 except ImportError: # LAX
     pass
 
-def set_sql_prefix(prefix):
-    """3.1.5 migration function: allow to unset/reset SQL_PREFIX"""
-    for module in ('checkintegrity', 'migractions', 'schemahooks',
-                   'sources.rql2sql', 'sources.native'):
-        try:
-            sys.modules['cubicweb.server.%s' % module].SQL_PREFIX = prefix
-            print 'changed SQL_PREFIX for %s' % module
-        except KeyError:
-            pass
-        
-def update_database(repo):
-    """3.1.3 migration function: update database schema by adding SQL_PREFIX to
-    entity type tables and columns
-    """
-    pool = repo._get_pool()
-    source = repo.system_source
-    sqlcu = pool['system']
-    for etype in repo.schema.entities():
-        if etype.is_final():
-            continue
-        try:
-            sqlcu.execute('ALTER TABLE %s RENAME TO cw_%s' % (etype, etype))
-            print 'renamed %s table for source %s' % (etype, uri)
-        except:
-            pass
-        for rschema in etype.subject_relations():
-            if rschema == 'has_text':
-                continue
-            if rschema.is_final() or rschema.inlined:
-                sqlcu.execute('ALTER TABLE cw_%s RENAME %s TO cw_%s'
-                              % (etype, rschema, rschema))
-                print 'renamed %s.%s column for source %s' % (
-                    etype, rschema, uri)
-    pool.commit()
-    repo._free_pool(pool)
 
-        
 class ServerMigrationHelper(MigrationHelper):
     """specific migration helper for server side  migration scripts,
     providind actions related to schema/data migration
@@ -99,23 +65,13 @@
 
     @cached
     def repo_connect(self):
-        try:
-            self.repo = get_repository(method='inmemory', config=self.config)
-        except:
-            import traceback
-            traceback.print_exc()
-            print '3.1.5 migration'
-            # XXX 3.1.5 migration
-            set_sql_prefix('')
-            self.repo = get_repository(method='inmemory', config=self.config)
-            update_database(self.repo)
-            set_sql_prefix('cw_')
+        self.repo = get_repository(method='inmemory', config=self.config)
         return self.repo
-    
+
     def shutdown(self):
         if self.repo is not None:
             self.repo.shutdown()
-        
+
     def rewrite_vcconfiguration(self):
         """write current installed versions (of cubicweb software
         and of each used cube) into the database
@@ -125,7 +81,7 @@
             pkgversion = self.config.cube_version(pkg)
             self.cmd_set_property('system.version.%s' % pkg.lower(), pkgversion)
         self.commit()
-        
+
     def backup_database(self, backupfile=None, askconfirm=True):
         config = self.config
         source = config.sources()['system']
@@ -157,7 +113,7 @@
                 print 'database backup:', backupfile
                 restrict_perms_to_user(backupfile, self.info)
                 break
-        
+
     def restore_database(self, backupfile, drop=True):
         config = self.config
         source = config.sources()['system']
@@ -183,7 +139,7 @@
                     else:
                         break
             print 'database restored'
-        
+
     def migrate(self, vcconf, toupgrade, options):
         if not options.fs_only:
             if options.backup_db is None:
@@ -191,7 +147,7 @@
             elif options.backup_db:
                 self.backup_database(askconfirm=False)
         super(ServerMigrationHelper, self).migrate(vcconf, toupgrade, options)
-    
+
     def process_script(self, migrscript, funcname=None, *args, **kwargs):
         """execute a migration script
         in interactive mode,  display the migration script path, ask for
@@ -203,7 +159,7 @@
         else:
             return super(ServerMigrationHelper, self).process_script(
                 migrscript, funcname, *args, **kwargs)
-        
+
     @property
     def cnx(self):
         """lazy connection"""
@@ -238,7 +194,7 @@
     @property
     def session(self):
         return self.repo._get_session(self.cnx.sessionid)
-    
+
     @property
     @cached
     def rqlcursor(self):
@@ -247,15 +203,15 @@
         # some query while no pool is set on the session (eg on entity attribute
         # access for instance)
         return self.cnx.cursor()
-    
+
     def commit(self):
         if hasattr(self, '_cnx'):
             self._cnx.commit()
-            
+
     def rollback(self):
         if hasattr(self, '_cnx'):
             self._cnx.rollback()
-                   
+
     def rqlexecall(self, rqliter, cachekey=None, ask_confirm=True):
         for rql, kwargs in rqliter:
             self.rqlexec(rql, kwargs, cachekey, ask_confirm)
@@ -269,12 +225,12 @@
                         'rql': self.rqlexec,
                         'rqliter': self.rqliter,
                         'schema': self.repo.schema,
-                        # XXX deprecate
-                        'newschema': self.fs_schema,
                         'fsschema': self.fs_schema,
-                        'cnx': self.cnx,
                         'session' : self.session,
                         'repo' : self.repo,
+                        'synchronize_schema': deprecated_function(self.sync_schema_props_perms),
+                        'synchronize_eschema': deprecated_function(self.sync_schema_props_perms),
+                        'synchronize_rschema': deprecated_function(self.sync_schema_props_perms),
                         })
         return context
 
@@ -282,9 +238,9 @@
     def group_mapping(self):
         """cached group mapping"""
         return ss.group_mapping(self.rqlcursor)
-        
+
     def exec_event_script(self, event, cubepath=None, funcname=None,
-                          *args, **kwargs):            
+                          *args, **kwargs):
         if cubepath:
             apc = join(cubepath, 'migration', '%s.py' % event)
         else:
@@ -309,312 +265,10 @@
                     self.repo.hm.register_hook(setowner_after_add_entity,
                                                'after_add_entity', '')
                     self.reactivate_verification_hooks()
-    
-    # base actions ############################################################
-
-    def checkpoint(self):
-        """checkpoint action"""
-        if self.confirm('commit now ?', shell=False):
-            self.commit()
-
-    def cmd_add_cube(self, cube, update_database=True):
-        self.cmd_add_cubes( (cube,), update_database)
-    
-    def cmd_add_cubes(self, cubes, update_database=True):
-        """update_database is telling if the database schema should be updated
-        or if only the relevant eproperty should be inserted (for the case where
-        a cube has been extracted from an existing application, so the
-        cube schema is already in there)
-        """
-        newcubes = super(ServerMigrationHelper, self).cmd_add_cubes(cubes)
-        if not newcubes:
-            return
-        for pack in newcubes:
-            self.cmd_set_property('system.version.'+pack,
-                                  self.config.cube_version(pack))
-        if not update_database:
-            self.commit()
-            return
-        newcubes_schema = self.config.load_schema(construction_mode='non-strict')
-        new = set()
-        # execute pre-create files
-        for pack in reversed(newcubes):
-            self.exec_event_script('precreate', self.config.cube_dir(pack))
-        # add new entity and relation types
-        for rschema in newcubes_schema.relations():
-            if not rschema in self.repo.schema:
-                self.cmd_add_relation_type(rschema.type)
-                new.add(rschema.type)
-        for eschema in newcubes_schema.entities():
-            if not eschema in self.repo.schema:
-                self.cmd_add_entity_type(eschema.type)
-                new.add(eschema.type)
-        # check if attributes has been added to existing entities
-        for rschema in newcubes_schema.relations():
-            existingschema = self.repo.schema.rschema(rschema.type)
-            for (fromtype, totype) in rschema.iter_rdefs():
-                if existingschema.has_rdef(fromtype, totype):
-                    continue
-                # check we should actually add the relation definition
-                if not (fromtype in new or totype in new or rschema in new):
-                    continue
-                self.cmd_add_relation_definition(str(fromtype), rschema.type, 
-                                                 str(totype))
-        # execute post-create files
-        for pack in reversed(newcubes):
-            self.exec_event_script('postcreate', self.config.cube_dir(pack))
-            self.commit()        
-                
-    def cmd_remove_cube(self, cube):
-        removedcubes = super(ServerMigrationHelper, self).cmd_remove_cube(cube)
-        if not removedcubes:
-            return
-        fsschema = self.fs_schema
-        removedcubes_schema = self.config.load_schema(construction_mode='non-strict')
-        reposchema = self.repo.schema
-        # execute pre-remove files
-        for pack in reversed(removedcubes):
-            self.exec_event_script('preremove', self.config.cube_dir(pack))
-        # remove cubes'entity and relation types
-        for rschema in fsschema.relations():
-            if not rschema in removedcubes_schema and rschema in reposchema:
-                self.cmd_drop_relation_type(rschema.type)
-        for eschema in fsschema.entities():
-            if not eschema in removedcubes_schema and eschema in reposchema:
-                self.cmd_drop_entity_type(eschema.type)
-        for rschema in fsschema.relations():
-            if rschema in removedcubes_schema and rschema in reposchema: 
-                # check if attributes/relations has been added to entities from 
-                # other cubes
-                for fromtype, totype in rschema.iter_rdefs():
-                    if not removedcubes_schema[rschema.type].has_rdef(fromtype, totype) and \
-                           reposchema[rschema.type].has_rdef(fromtype, totype):
-                        self.cmd_drop_relation_definition(
-                            str(fromtype), rschema.type, str(totype))
-        # execute post-remove files
-        for pack in reversed(removedcubes):
-            self.exec_event_script('postremove', self.config.cube_dir(pack))
-            self.rqlexec('DELETE EProperty X WHERE X pkey %(pk)s',
-                         {'pk': u'system.version.'+pack}, ask_confirm=False)
-            self.commit()
-            
-    # schema migration actions ################################################
-    
-    def cmd_add_attribute(self, etype, attrname, attrtype=None, commit=True):
-        """add a new attribute on the given entity type"""
-        if attrtype is None:
-            rschema = self.fs_schema.rschema(attrname)
-            attrtype = rschema.objects(etype)[0]
-        self.cmd_add_relation_definition(etype, attrname, attrtype, commit=commit)
-        
-    def cmd_drop_attribute(self, etype, attrname, commit=True):
-        """drop an existing attribute from the given entity type
-        
-        `attrname` is a string giving the name of the attribute to drop
-        """
-        rschema = self.repo.schema.rschema(attrname)
-        attrtype = rschema.objects(etype)[0]
-        self.cmd_drop_relation_definition(etype, attrname, attrtype, commit=commit)
 
-    def cmd_rename_attribute(self, etype, oldname, newname, commit=True):
-        """rename an existing attribute of the given entity type
-        
-        `oldname` is a string giving the name of the existing attribute
-        `newname` is a string giving the name of the renamed attribute
-        """
-        eschema = self.fs_schema.eschema(etype)
-        attrtype = eschema.destination(newname)
-        # have to commit this first step anyway to get the definition
-        # actually in the schema
-        self.cmd_add_attribute(etype, newname, attrtype, commit=True)
-        # skipp NULL values if the attribute is required
-        rql = 'SET X %s VAL WHERE X is %s, X %s VAL' % (newname, etype, oldname)
-        card = eschema.rproperty(newname, 'cardinality')[0]
-        if card == '1':
-            rql += ', NOT X %s NULL' % oldname
-        self.rqlexec(rql, ask_confirm=self.verbosity>=2)
-        self.cmd_drop_attribute(etype, oldname, commit=commit)
-            
-    def cmd_add_entity_type(self, etype, auto=True, commit=True):
-        """register a new entity type
-        
-        in auto mode, automatically register entity's relation where the
-        targeted type is known
-        """
-        applschema = self.repo.schema
-        if etype in applschema:
-            eschema = applschema[etype]
-            if eschema.is_final():
-                applschema.del_entity_type(etype)
-        else:
-            eschema = self.fs_schema.eschema(etype)
-        confirm = self.verbosity >= 2
-        # register the entity into EEType
-        self.rqlexecall(ss.eschema2rql(eschema), ask_confirm=confirm)
-        # add specializes relation if needed
-        self.rqlexecall(ss.eschemaspecialize2rql(eschema), ask_confirm=confirm)
-        # register groups / permissions for the entity
-        self.rqlexecall(ss.erperms2rql(eschema, self.group_mapping()),
-                        ask_confirm=confirm)
-        # register entity's attributes
-        for rschema, attrschema in eschema.attribute_definitions():
-            # ignore those meta relations, they will be automatically added
-            if rschema.type in ('eid', 'creation_date', 'modification_date'):
-                continue
-            if not rschema.type in applschema:
-                # need to add the relation type and to commit to get it
-                # actually in the schema
-                self.cmd_add_relation_type(rschema.type, False, commit=True)
-            # register relation definition
-            self.rqlexecall(ss.rdef2rql(rschema, etype, attrschema.type),
-                            ask_confirm=confirm)
-        if auto:
-            # we have commit here to get relation types actually in the schema
-            self.commit()
-            added = []
-            for rschema in eschema.subject_relations():
-                # attribute relation have already been processed and
-                # 'owned_by'/'created_by' will be automatically added
-                if rschema.final or rschema.type in ('owned_by', 'created_by', 'is', 'is_instance_of'): 
-                    continue
-                rtypeadded = rschema.type in applschema
-                for targetschema in rschema.objects(etype):
-                    # ignore relations where the targeted type is not in the
-                    # current application schema
-                    targettype = targetschema.type
-                    if not targettype in applschema and targettype != etype:
-                        continue
-                    if not rtypeadded:
-                        # need to add the relation type and to commit to get it
-                        # actually in the schema
-                        added.append(rschema.type)
-                        self.cmd_add_relation_type(rschema.type, False, commit=True)
-                        rtypeadded = True
-                    # register relation definition
-                    # remember this two avoid adding twice non symetric relation
-                    # such as "Emailthread forked_from Emailthread"
-                    added.append((etype, rschema.type, targettype))
-                    self.rqlexecall(ss.rdef2rql(rschema, etype, targettype),
-                                    ask_confirm=confirm)
-            for rschema in eschema.object_relations():
-                rtypeadded = rschema.type in applschema or rschema.type in added
-                for targetschema in rschema.subjects(etype):
-                    # ignore relations where the targeted type is not in the
-                    # current application schema
-                    targettype = targetschema.type
-                    # don't check targettype != etype since in this case the
-                    # relation has already been added as a subject relation
-                    if not targettype in applschema:
-                        continue
-                    if not rtypeadded:
-                        # need to add the relation type and to commit to get it
-                        # actually in the schema
-                        self.cmd_add_relation_type(rschema.type, False, commit=True)
-                        rtypeadded = True
-                    elif (targettype, rschema.type, etype) in added:
-                        continue
-                    # register relation definition
-                    self.rqlexecall(ss.rdef2rql(rschema, targettype, etype),
-                                    ask_confirm=confirm)
-        if commit:
-            self.commit()
-                
-    def cmd_drop_entity_type(self, etype, commit=True):
-        """unregister an existing entity type
-        
-        This will trigger deletion of necessary relation types and definitions
-        """
-        # XXX what if we delete an entity type which is specialized by other types
-        # unregister the entity from EEType
-        self.rqlexec('DELETE EEType X WHERE X name %(etype)s', {'etype': etype},
-                     ask_confirm=self.verbosity>=2)
-        if commit:
-            self.commit()
+    # schema synchronization internals ########################################
 
-    def cmd_rename_entity_type(self, oldname, newname, commit=True):
-        """rename an existing entity type in the persistent schema
-        
-        `oldname` is a string giving the name of the existing entity type
-        `newname` is a string giving the name of the renamed entity type
-        """
-        self.rqlexec('SET ET name %(newname)s WHERE ET is EEType, ET name %(oldname)s',
-                     {'newname' : unicode(newname), 'oldname' : oldname})
-        if commit:
-            self.commit()
-        
-    def cmd_add_relation_type(self, rtype, addrdef=True, commit=True):
-        """register a new relation type named `rtype`, as described in the
-        schema description file.
-
-        `addrdef` is a boolean value; when True, it will also add all relations
-        of the type just added found in the schema definition file. Note that it
-        implies an intermediate "commit" which commits the relation type
-        creation (but not the relation definitions themselves, for which
-        committing depends on the `commit` argument value).
-        
-        """
-        rschema = self.fs_schema.rschema(rtype)
-        # register the relation into ERType and insert necessary relation
-        # definitions
-        self.rqlexecall(ss.rschema2rql(rschema, addrdef=False),
-                        ask_confirm=self.verbosity>=2)
-        # register groups / permissions for the relation
-        self.rqlexecall(ss.erperms2rql(rschema, self.group_mapping()),
-                        ask_confirm=self.verbosity>=2)
-        if addrdef:
-            self.commit()
-            self.rqlexecall(ss.rdef2rql(rschema),
-                            ask_confirm=self.verbosity>=2)
-        if commit:
-            self.commit()
-        
-    def cmd_drop_relation_type(self, rtype, commit=True):
-        """unregister an existing relation type"""
-        # unregister the relation from ERType
-        self.rqlexec('DELETE ERType X WHERE X name %r' % rtype,
-                     ask_confirm=self.verbosity>=2)
-        if commit:
-            self.commit()
-        
-    def cmd_rename_relation(self, oldname, newname, commit=True):
-        """rename an existing relation
-        
-        `oldname` is a string giving the name of the existing relation
-        `newname` is a string giving the name of the renamed relation
-        """
-        self.cmd_add_relation_type(newname, commit=True)
-        self.rqlexec('SET X %s Y WHERE X %s Y' % (newname, oldname),
-                     ask_confirm=self.verbosity>=2)
-        self.cmd_drop_relation_type(oldname, commit=commit)
-
-    def cmd_add_relation_definition(self, subjtype, rtype, objtype, commit=True):
-        """register a new relation definition, from its definition found in the
-        schema definition file
-        """
-        rschema = self.fs_schema.rschema(rtype)
-        if not rtype in self.repo.schema:
-            self.cmd_add_relation_type(rtype, addrdef=False, commit=True)
-        self.rqlexecall(ss.rdef2rql(rschema, subjtype, objtype),
-                        ask_confirm=self.verbosity>=2)
-        if commit:
-            self.commit()
-        
-    def cmd_drop_relation_definition(self, subjtype, rtype, objtype, commit=True):
-        """unregister an existing relation definition"""
-        rschema = self.repo.schema.rschema(rtype)
-        # unregister the definition from EFRDef or ENFRDef
-        if rschema.is_final():
-            etype = 'EFRDef'
-        else:
-            etype = 'ENFRDef'
-        rql = ('DELETE %s X WHERE X from_entity FE, FE name "%s",'
-               'X relation_type RT, RT name "%s", X to_entity TE, TE name "%s"')
-        self.rqlexec(rql % (etype, subjtype, rtype, objtype),
-                     ask_confirm=self.verbosity>=2)
-        if commit:
-            self.commit()
-        
-    def cmd_synchronize_permissions(self, ertype, commit=True):
+    def _synchronize_permissions(self, ertype):
         """permission synchronization for an entity or relation type"""
         if ertype in ('eid', 'has_text', 'identity'):
             return
@@ -678,20 +332,17 @@
                                  {'expr': expr, 'exprtype': exprtype,
                                   'vars': expression.mainvars, 'x': teid}, 'x',
                                  ask_confirm=False)
-        if commit:
-            self.commit()
-        
-    def cmd_synchronize_rschema(self, rtype, syncrdefs=True, syncperms=True,
-                                commit=True):
+
+    def _synchronize_rschema(self, rtype, syncrdefs=True, syncperms=True):
         """synchronize properties of the persistent relation schema against its
         current definition:
-        
+
         * description
         * symetric, meta
         * inlined
         * relation definitions if `syncrdefs`
         * permissions if `syncperms`
-        
+
         physical schema changes should be handled by repository's schema hooks
         """
         rtype = str(rtype)
@@ -706,17 +357,14 @@
             for subj, obj in rschema.iter_rdefs():
                 if not reporschema.has_rdef(subj, obj):
                     continue
-                self.cmd_synchronize_rdef_schema(subj, rschema, obj,
-                                                 commit=False)
+                self._synchronize_rdef_schema(subj, rschema, obj)
         if syncperms:
-            self.cmd_synchronize_permissions(rtype, commit=False)
-        if commit:
-            self.commit()
-                
-    def cmd_synchronize_eschema(self, etype, syncperms=True, commit=True):
+            self._synchronize_permissions(rtype)
+
+    def _synchronize_eschema(self, etype, syncperms=True):
         """synchronize properties of the persistent entity schema against
         its current definition:
-        
+
         * description
         * internationalizable, fulltextindexed, indexed, meta
         * relations from/to this entity
@@ -734,11 +382,11 @@
         repospschema = repoeschema.specializes()
         espschema = eschema.specializes()
         if repospschema and not espschema:
-            self.rqlexec('DELETE X specializes Y WHERE X is EEType, X name %(x)s',
+            self.rqlexec('DELETE X specializes Y WHERE X is CWEType, X name %(x)s',
                          {'x': str(repoeschema)})
         elif not repospschema and espschema:
-            self.rqlexec('SET X specializes Y WHERE X is EEType, X name %(x)s, '
-                         'Y is EEType, Y name %(y)s',
+            self.rqlexec('SET X specializes Y WHERE X is CWEType, X name %(x)s, '
+                         'Y is CWEType, Y name %(y)s',
                          {'x': str(repoeschema), 'y': str(espschema)})
         self.rqlexecall(ss.updateeschema2rql(eschema),
                         ask_confirm=self.verbosity >= 2)
@@ -751,22 +399,18 @@
                 if not rschema in repoeschema.object_relations():
                     continue
                 subjtypes, objtypes = targettypes, [etype]
-            self.cmd_synchronize_rschema(rschema, syncperms=syncperms,
-                                         syncrdefs=False, commit=False)
+            self._synchronize_rschema(rschema, syncperms=syncperms,
+                                      syncrdefs=False)
             reporschema = self.repo.schema.rschema(rschema)
             for subj in subjtypes:
                 for obj in objtypes:
                     if not reporschema.has_rdef(subj, obj):
                         continue
-                    self.cmd_synchronize_rdef_schema(subj, rschema, obj,
-                                                     commit=False)
+                    self._synchronize_rdef_schema(subj, rschema, obj)
         if syncperms:
-            self.cmd_synchronize_permissions(etype, commit=False)
-        if commit:
-            self.commit()
+            self._synchronize_permissions(etype)
 
-    def cmd_synchronize_rdef_schema(self, subjtype, rtype, objtype,
-                                    commit=True):
+    def _synchronize_rdef_schema(self, subjtype, rtype, objtype):
         """synchronize properties of the persistent relation definition schema
         against its current definition:
         * order and other properties
@@ -800,7 +444,7 @@
                 self.rqlexec('DELETE X constrained_by C WHERE C eid %(x)s',
                              {'x': cstr.eid}, 'x',
                              ask_confirm=confirm)
-                self.rqlexec('DELETE EConstraint C WHERE C eid %(x)s',
+                self.rqlexec('DELETE CWConstraint C WHERE C eid %(x)s',
                              {'x': cstr.eid}, 'x',
                              ask_confirm=confirm)
             else:
@@ -814,24 +458,349 @@
             self.rqlexecall(ss.constraint2rql(rschema, subjtype, objtype,
                                               newcstr),
                             ask_confirm=confirm)
+
+    # base actions ############################################################
+
+    def checkpoint(self):
+        """checkpoint action"""
+        if self.confirm('commit now ?', shell=False):
+            self.commit()
+
+    def cmd_add_cube(self, cube, update_database=True):
+        self.cmd_add_cubes( (cube,), update_database)
+
+    def cmd_add_cubes(self, cubes, update_database=True):
+        """update_database is telling if the database schema should be updated
+        or if only the relevant eproperty should be inserted (for the case where
+        a cube has been extracted from an existing application, so the
+        cube schema is already in there)
+        """
+        newcubes = super(ServerMigrationHelper, self).cmd_add_cubes(cubes)
+        if not newcubes:
+            return
+        for pack in newcubes:
+            self.cmd_set_property('system.version.'+pack,
+                                  self.config.cube_version(pack))
+        if not update_database:
+            self.commit()
+            return
+        newcubes_schema = self.config.load_schema(construction_mode='non-strict')
+        new = set()
+        # execute pre-create files
+        for pack in reversed(newcubes):
+            self.exec_event_script('precreate', self.config.cube_dir(pack))
+        # add new entity and relation types
+        for rschema in newcubes_schema.relations():
+            if not rschema in self.repo.schema:
+                self.cmd_add_relation_type(rschema.type)
+                new.add(rschema.type)
+        for eschema in newcubes_schema.entities():
+            if not eschema in self.repo.schema:
+                self.cmd_add_entity_type(eschema.type)
+                new.add(eschema.type)
+        # check if attributes has been added to existing entities
+        for rschema in newcubes_schema.relations():
+            existingschema = self.repo.schema.rschema(rschema.type)
+            for (fromtype, totype) in rschema.iter_rdefs():
+                if existingschema.has_rdef(fromtype, totype):
+                    continue
+                # check we should actually add the relation definition
+                if not (fromtype in new or totype in new or rschema in new):
+                    continue
+                self.cmd_add_relation_definition(str(fromtype), rschema.type,
+                                                 str(totype))
+        # execute post-create files
+        for pack in reversed(newcubes):
+            self.exec_event_script('postcreate', self.config.cube_dir(pack))
+            self.commit()
+
+    def cmd_remove_cube(self, cube):
+        removedcubes = super(ServerMigrationHelper, self).cmd_remove_cube(cube)
+        if not removedcubes:
+            return
+        fsschema = self.fs_schema
+        removedcubes_schema = self.config.load_schema(construction_mode='non-strict')
+        reposchema = self.repo.schema
+        # execute pre-remove files
+        for pack in reversed(removedcubes):
+            self.exec_event_script('preremove', self.config.cube_dir(pack))
+        # remove cubes'entity and relation types
+        for rschema in fsschema.relations():
+            if not rschema in removedcubes_schema and rschema in reposchema:
+                self.cmd_drop_relation_type(rschema.type)
+        for eschema in fsschema.entities():
+            if not eschema in removedcubes_schema and eschema in reposchema:
+                self.cmd_drop_entity_type(eschema.type)
+        for rschema in fsschema.relations():
+            if rschema in removedcubes_schema and rschema in reposchema:
+                # check if attributes/relations has been added to entities from
+                # other cubes
+                for fromtype, totype in rschema.iter_rdefs():
+                    if not removedcubes_schema[rschema.type].has_rdef(fromtype, totype) and \
+                           reposchema[rschema.type].has_rdef(fromtype, totype):
+                        self.cmd_drop_relation_definition(
+                            str(fromtype), rschema.type, str(totype))
+        # execute post-remove files
+        for pack in reversed(removedcubes):
+            self.exec_event_script('postremove', self.config.cube_dir(pack))
+            self.rqlexec('DELETE CWProperty X WHERE X pkey %(pk)s',
+                         {'pk': u'system.version.'+pack}, ask_confirm=False)
+            self.commit()
+
+    # schema migration actions ################################################
+
+    def cmd_add_attribute(self, etype, attrname, attrtype=None, commit=True):
+        """add a new attribute on the given entity type"""
+        if attrtype is None:
+            rschema = self.fs_schema.rschema(attrname)
+            attrtype = rschema.objects(etype)[0]
+        self.cmd_add_relation_definition(etype, attrname, attrtype, commit=commit)
+
+    def cmd_drop_attribute(self, etype, attrname, commit=True):
+        """drop an existing attribute from the given entity type
+
+        `attrname` is a string giving the name of the attribute to drop
+        """
+        rschema = self.repo.schema.rschema(attrname)
+        attrtype = rschema.objects(etype)[0]
+        self.cmd_drop_relation_definition(etype, attrname, attrtype, commit=commit)
+
+    def cmd_rename_attribute(self, etype, oldname, newname, commit=True):
+        """rename an existing attribute of the given entity type
+
+        `oldname` is a string giving the name of the existing attribute
+        `newname` is a string giving the name of the renamed attribute
+        """
+        eschema = self.fs_schema.eschema(etype)
+        attrtype = eschema.destination(newname)
+        # have to commit this first step anyway to get the definition
+        # actually in the schema
+        self.cmd_add_attribute(etype, newname, attrtype, commit=True)
+        # skipp NULL values if the attribute is required
+        rql = 'SET X %s VAL WHERE X is %s, X %s VAL' % (newname, etype, oldname)
+        card = eschema.rproperty(newname, 'cardinality')[0]
+        if card == '1':
+            rql += ', NOT X %s NULL' % oldname
+        self.rqlexec(rql, ask_confirm=self.verbosity>=2)
+        self.cmd_drop_attribute(etype, oldname, commit=commit)
+
+    def cmd_add_entity_type(self, etype, auto=True, commit=True):
+        """register a new entity type
+
+        in auto mode, automatically register entity's relation where the
+        targeted type is known
+        """
+        applschema = self.repo.schema
+        if etype in applschema:
+            eschema = applschema[etype]
+            if eschema.is_final():
+                applschema.del_entity_type(etype)
+        else:
+            eschema = self.fs_schema.eschema(etype)
+        confirm = self.verbosity >= 2
+        # register the entity into CWEType
+        self.rqlexecall(ss.eschema2rql(eschema), ask_confirm=confirm)
+        # add specializes relation if needed
+        self.rqlexecall(ss.eschemaspecialize2rql(eschema), ask_confirm=confirm)
+        # register groups / permissions for the entity
+        self.rqlexecall(ss.erperms2rql(eschema, self.group_mapping()),
+                        ask_confirm=confirm)
+        # register entity's attributes
+        for rschema, attrschema in eschema.attribute_definitions():
+            # ignore those meta relations, they will be automatically added
+            if rschema.type in ('eid', 'creation_date', 'modification_date'):
+                continue
+            if not rschema.type in applschema:
+                # need to add the relation type and to commit to get it
+                # actually in the schema
+                self.cmd_add_relation_type(rschema.type, False, commit=True)
+            # register relation definition
+            self.rqlexecall(ss.rdef2rql(rschema, etype, attrschema.type),
+                            ask_confirm=confirm)
+        if auto:
+            # we have commit here to get relation types actually in the schema
+            self.commit()
+            added = []
+            for rschema in eschema.subject_relations():
+                # attribute relation have already been processed and
+                # 'owned_by'/'created_by' will be automatically added
+                if rschema.final or rschema.type in ('owned_by', 'created_by', 'is', 'is_instance_of'):
+                    continue
+                rtypeadded = rschema.type in applschema
+                for targetschema in rschema.objects(etype):
+                    # ignore relations where the targeted type is not in the
+                    # current application schema
+                    targettype = targetschema.type
+                    if not targettype in applschema and targettype != etype:
+                        continue
+                    if not rtypeadded:
+                        # need to add the relation type and to commit to get it
+                        # actually in the schema
+                        added.append(rschema.type)
+                        self.cmd_add_relation_type(rschema.type, False, commit=True)
+                        rtypeadded = True
+                    # register relation definition
+                    # remember this two avoid adding twice non symetric relation
+                    # such as "Emailthread forked_from Emailthread"
+                    added.append((etype, rschema.type, targettype))
+                    self.rqlexecall(ss.rdef2rql(rschema, etype, targettype),
+                                    ask_confirm=confirm)
+            for rschema in eschema.object_relations():
+                rtypeadded = rschema.type in applschema or rschema.type in added
+                for targetschema in rschema.subjects(etype):
+                    # ignore relations where the targeted type is not in the
+                    # current application schema
+                    targettype = targetschema.type
+                    # don't check targettype != etype since in this case the
+                    # relation has already been added as a subject relation
+                    if not targettype in applschema:
+                        continue
+                    if not rtypeadded:
+                        # need to add the relation type and to commit to get it
+                        # actually in the schema
+                        self.cmd_add_relation_type(rschema.type, False, commit=True)
+                        rtypeadded = True
+                    elif (targettype, rschema.type, etype) in added:
+                        continue
+                    # register relation definition
+                    self.rqlexecall(ss.rdef2rql(rschema, targettype, etype),
+                                    ask_confirm=confirm)
         if commit:
             self.commit()
-        
-    def cmd_synchronize_schema(self, syncperms=True, commit=True):
+
+    def cmd_drop_entity_type(self, etype, commit=True):
+        """unregister an existing entity type
+
+        This will trigger deletion of necessary relation types and definitions
+        """
+        # XXX what if we delete an entity type which is specialized by other types
+        # unregister the entity from CWEType
+        self.rqlexec('DELETE CWEType X WHERE X name %(etype)s', {'etype': etype},
+                     ask_confirm=self.verbosity>=2)
+        if commit:
+            self.commit()
+
+    def cmd_rename_entity_type(self, oldname, newname, commit=True):
+        """rename an existing entity type in the persistent schema
+
+        `oldname` is a string giving the name of the existing entity type
+        `newname` is a string giving the name of the renamed entity type
+        """
+        self.rqlexec('SET ET name %(newname)s WHERE ET is CWEType, ET name %(oldname)s',
+                     {'newname' : unicode(newname), 'oldname' : oldname})
+        if commit:
+            self.commit()
+
+    def cmd_add_relation_type(self, rtype, addrdef=True, commit=True):
+        """register a new relation type named `rtype`, as described in the
+        schema description file.
+
+        `addrdef` is a boolean value; when True, it will also add all relations
+        of the type just added found in the schema definition file. Note that it
+        implies an intermediate "commit" which commits the relation type
+        creation (but not the relation definitions themselves, for which
+        committing depends on the `commit` argument value).
+
+        """
+        rschema = self.fs_schema.rschema(rtype)
+        # register the relation into CWRType and insert necessary relation
+        # definitions
+        self.rqlexecall(ss.rschema2rql(rschema, addrdef=False),
+                        ask_confirm=self.verbosity>=2)
+        # register groups / permissions for the relation
+        self.rqlexecall(ss.erperms2rql(rschema, self.group_mapping()),
+                        ask_confirm=self.verbosity>=2)
+        if addrdef:
+            self.commit()
+            self.rqlexecall(ss.rdef2rql(rschema),
+                            ask_confirm=self.verbosity>=2)
+        if commit:
+            self.commit()
+
+    def cmd_drop_relation_type(self, rtype, commit=True):
+        """unregister an existing relation type"""
+        # unregister the relation from CWRType
+        self.rqlexec('DELETE CWRType X WHERE X name %r' % rtype,
+                     ask_confirm=self.verbosity>=2)
+        if commit:
+            self.commit()
+
+    def cmd_rename_relation(self, oldname, newname, commit=True):
+        """rename an existing relation
+
+        `oldname` is a string giving the name of the existing relation
+        `newname` is a string giving the name of the renamed relation
+        """
+        self.cmd_add_relation_type(newname, commit=True)
+        self.rqlexec('SET X %s Y WHERE X %s Y' % (newname, oldname),
+                     ask_confirm=self.verbosity>=2)
+        self.cmd_drop_relation_type(oldname, commit=commit)
+
+    def cmd_add_relation_definition(self, subjtype, rtype, objtype, commit=True):
+        """register a new relation definition, from its definition found in the
+        schema definition file
+        """
+        rschema = self.fs_schema.rschema(rtype)
+        if not rtype in self.repo.schema:
+            self.cmd_add_relation_type(rtype, addrdef=False, commit=True)
+        self.rqlexecall(ss.rdef2rql(rschema, subjtype, objtype),
+                        ask_confirm=self.verbosity>=2)
+        if commit:
+            self.commit()
+
+    def cmd_drop_relation_definition(self, subjtype, rtype, objtype, commit=True):
+        """unregister an existing relation definition"""
+        rschema = self.repo.schema.rschema(rtype)
+        # unregister the definition from CWAttribute or CWRelation
+        if rschema.is_final():
+            etype = 'CWAttribute'
+        else:
+            etype = 'CWRelation'
+        rql = ('DELETE %s X WHERE X from_entity FE, FE name "%s",'
+               'X relation_type RT, RT name "%s", X to_entity TE, TE name "%s"')
+        self.rqlexec(rql % (etype, subjtype, rtype, objtype),
+                     ask_confirm=self.verbosity>=2)
+        if commit:
+            self.commit()
+
+    def cmd_sync_schema_props_perms(self, ertype=None, syncperms=True,
+                                    syncprops=True, syncrdefs=True, commit=True):
         """synchronize the persistent schema against the current definition
         schema.
-        
+
         It will synch common stuff between the definition schema and the
         actual persistent schema, it won't add/remove any entity or relation.
         """
-        for etype in self.repo.schema.entities():
-            self.cmd_synchronize_eschema(etype, syncperms=syncperms, commit=False)
+        assert syncperms or syncprops, 'nothing to do'
+        if ertype is not None:
+            if isinstance(ertype, (tuple, list)):
+                assert len(ertype) == 3, 'not a relation definition'
+                assert syncprops, 'can\'t update permission for a relation definition'
+                self._synchronize_rdef_schema(*ertype)
+            elif syncprops:
+                erschema = self.repo.schema[ertype]
+                if isinstance(erschema, CubicWebRelationSchema):
+                    self._synchronize_rschema(erschema, syncperms=syncperms,
+                                              syncrdefs=syncrdefs)
+                else:
+                    self._synchronize_eschema(erschema, syncperms=syncperms)
+            else:
+                self._synchronize_permissions(ertype)
+        else:
+            for etype in self.repo.schema.entities():
+                if syncprops:
+                    self._synchronize_eschema(etype, syncperms=syncperms)
+                else:
+                    self._synchronize_permissions(etype)
         if commit:
             self.commit()
-                
+
     def cmd_change_relation_props(self, subjtype, rtype, objtype,
                                   commit=True, **kwargs):
-        """change some properties of a relation definition"""
+        """change some properties of a relation definition
+
+        you usually want to use sync_schema_props_perms instead.
+        """
         assert kwargs
         restriction = []
         if subjtype and subjtype != 'Any':
@@ -854,7 +823,9 @@
     def cmd_set_size_constraint(self, etype, rtype, size, commit=True):
         """set change size constraint of a string attribute
 
-        if size is None any size constraint will be removed
+        if size is None any size constraint will be removed.
+
+        you usually want to use sync_schema_props_perms instead.
         """
         oldvalue = None
         for constr in self.repo.schema.eschema(etype).constraints(rtype):
@@ -863,7 +834,7 @@
         if oldvalue == size:
             return
         if oldvalue is None and not size is None:
-            ceid = self.rqlexec('INSERT EConstraint C: C value %(v)s, C cstrtype CT '
+            ceid = self.rqlexec('INSERT CWConstraint C: C value %(v)s, C cstrtype CT '
                                 'WHERE CT name "SizeConstraint"',
                                 {'v': SizeConstraint(size).serialize()},
                                 ask_confirm=self.verbosity>=2)[0][0]
@@ -883,12 +854,16 @@
                              'S name "%s", R name "%s"' % (etype, rtype),
                              ask_confirm=self.verbosity>=2)
                 # cleanup unused constraints
-                self.rqlexec('DELETE EConstraint C WHERE NOT X constrained_by C')
+                self.rqlexec('DELETE CWConstraint C WHERE NOT X constrained_by C')
         if commit:
             self.commit()
-    
+
+    @obsolete('use sync_schema_props_perms(ertype, syncprops=False)')
+    def cmd_synchronize_permissions(self, ertype, commit=True):
+        self.cmd_sync_schema_props_perms(ertype, syncprops=False, commit=commit)
+
     # Workflows handling ######################################################
-    
+
     def cmd_add_state(self, name, stateof, initial=False, commit=False, **kwargs):
         """method to ease workflow definition: add a state for one or more
         entity type(s)
@@ -906,7 +881,7 @@
         if commit:
             self.commit()
         return stateeid
-    
+
     def cmd_add_transition(self, name, transitionof, fromstates, tostate,
                            requiredgroups=(), conditions=(), commit=False, **kwargs):
         """method to ease workflow definition: add a transition for one or more
@@ -963,27 +938,27 @@
         entity.change_state(entity.wf_state(statename).eid)
         if commit:
             self.commit()
-        
-    # EProperty handling ######################################################
+
+    # CWProperty handling ######################################################
 
     def cmd_property_value(self, pkey):
-        rql = 'Any V WHERE X is EProperty, X pkey %(k)s, X value V'
+        rql = 'Any V WHERE X is CWProperty, X pkey %(k)s, X value V'
         rset = self.rqlexec(rql, {'k': pkey}, ask_confirm=False)
         return rset[0][0]
 
     def cmd_set_property(self, pkey, value):
         value = unicode(value)
         try:
-            prop = self.rqlexec('EProperty X WHERE X pkey %(k)s', {'k': pkey},
+            prop = self.rqlexec('CWProperty X WHERE X pkey %(k)s', {'k': pkey},
                                 ask_confirm=False).get_entity(0, 0)
         except:
-            self.cmd_add_entity('EProperty', pkey=unicode(pkey), value=value)
+            self.cmd_add_entity('CWProperty', pkey=unicode(pkey), value=value)
         else:
             self.rqlexec('SET X value %(v)s WHERE X pkey %(k)s',
                          {'k': pkey, 'v': value}, ask_confirm=False)
 
     # other data migration commands ###########################################
-        
+
     def cmd_add_entity(self, etype, *args, **kwargs):
         """add a new entity of the given type"""
         rql = 'INSERT %s X' % etype
@@ -1003,10 +978,10 @@
         if commit:
             self.commit()
         return eid
-    
+
     def sqlexec(self, sql, args=None, ask_confirm=True):
         """execute the given sql if confirmed
-        
+
         should only be used for low level stuff undoable with existing higher
         level actions
         """
@@ -1024,7 +999,7 @@
             except:
                 # no result to fetch
                 return
-    
+
     def rqlexec(self, rql, kwargs=None, cachekey=None, ask_confirm=True):
         """rql action"""
         if not isinstance(rql, (tuple, list)):
@@ -1051,7 +1026,7 @@
 
     def cmd_reactivate_verification_hooks(self):
         self.repo.hm.reactivate_verification_hooks()
-        
+
     # broken db commands ######################################################
 
     def cmd_change_attribute_type(self, etype, attr, newtype, commit=True):
@@ -1064,8 +1039,8 @@
         rschema = self.repo.schema.rschema(attr)
         oldtype = rschema.objects(etype)[0]
         rdefeid = rschema.rproperty(etype, oldtype, 'eid')
-        sql = ("UPDATE EFRDef "
-               "SET to_entity=(SELECT eid FROM EEType WHERE name='%s')"
+        sql = ("UPDATE CWAttribute "
+               "SET to_entity=(SELECT eid FROM CWEType WHERE name='%s')"
                "WHERE eid=%s") % (newtype, rdefeid)
         self.sqlexec(sql, ask_confirm=False)
         dbhelper = self.repo.system_source.dbhelper
@@ -1074,7 +1049,7 @@
         self.sqlexec(sql, ask_confirm=False)
         if commit:
             self.commit()
-        
+
     def cmd_add_entity_type_table(self, etype, commit=True):
         """low level method to create the sql table for an existing entity.
         This may be useful on accidental desync between the repository schema
@@ -1088,7 +1063,7 @@
                 self.sqlexec(sql)
         if commit:
             self.commit()
-            
+
     def cmd_add_relation_type_table(self, rtype, commit=True):
         """low level method to create the sql table for an existing relation.
         This may be useful on accidental desync between the repository schema
@@ -1101,7 +1076,7 @@
                 self.sqlexec(sql)
         if commit:
             self.commit()
-            
+
 
 class ForRqlIterator:
     """specific rql iterator to make the loop skipable"""
@@ -1111,10 +1086,10 @@
         self.kwargs = kwargs
         self.ask_confirm = ask_confirm
         self._rsetit = None
-        
+
     def __iter__(self):
         return self
-    
+
     def next(self):
         if self._rsetit is not None:
             return self._rsetit.next()
--- a/server/msplanner.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/msplanner.py	Fri Apr 24 19:46:47 2009 +0200
@@ -33,25 +33,25 @@
 
 Exemples of multi-sources query execution
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-For a system source and a ldap user source (only EUser and its attributes
+For a system source and a ldap user source (only CWUser and its attributes
 is supported, no group or such):
 
-:EUser X:
-1. fetch EUser X from both sources and return concatenation of results
+:CWUser X:
+1. fetch CWUser X from both sources and return concatenation of results
 
-:EUser X WHERE X in_group G, G name 'users':
+:CWUser X WHERE X in_group G, G name 'users':
 * catch 1
-  1. fetch EUser X from both sources, store concatenation of results into a
+  1. fetch CWUser X from both sources, store concatenation of results into a
      temporary table
   2. return the result of TMP X WHERE X in_group G, G name 'users' from the
      system source
 * catch 2
-  1. return the result of EUser X WHERE X in_group G, G name 'users' from system
+  1. return the result of CWUser X WHERE X in_group G, G name 'users' from system
      source, that's enough (optimization of the sql querier will avoid join on
-     EUser, so we will directly get local eids)
+     CWUser, so we will directly get local eids)
     
-:EUser X,L WHERE X in_group G, X login L, G name 'users':
-1. fetch Any X,L WHERE X is EUser, X login L from both sources, store
+:CWUser X,L WHERE X in_group G, X login L, G name 'users':
+1. fetch Any X,L WHERE X is CWUser, X login L from both sources, store
    concatenation of results into a temporary table
 2. return the result of Any X, L WHERE X is TMP, X login LX in_group G,
    G name 'users' from the system source
@@ -59,13 +59,13 @@
 
 :Any X WHERE X owned_by Y:
 * catch 1
-  1. fetch EUser X from both sources, store concatenation of results into a
+  1. fetch CWUser X from both sources, store concatenation of results into a
      temporary table
   2. return the result of Any X WHERE X owned_by Y, Y is TMP from the system
      source
 * catch 2
   1. return the result of Any X WHERE X owned_by Y from system source, that's
-     enough (optimization of the sql querier will avoid join on EUser, so we
+     enough (optimization of the sql querier will avoid join on CWUser, so we
      will directly get local eids)
 
 
@@ -1388,7 +1388,7 @@
             return False
         if not same_scope(var):
             return False
-        if any(v for v, _ in var.stinfo['attrvars'] if not v.name in variables):
+        if any(v for v, _ in var.stinfo['attrvars'] if not v in terms):
             return False
         return True
         
--- a/server/repository.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/repository.py	Fri Apr 24 19:46:47 2009 +0200
@@ -60,7 +60,7 @@
         remove inserted eid from repository type/source cache
         """
         self.repo.clear_caches(self.session.query_data('pendingeids', ()))
-        
+
     def rollback_event(self):
         """the observed connections pool has been rollbacked,
         remove inserted eid from repository type/source cache
@@ -84,7 +84,7 @@
         session.repo.system_source.fti_unindex_entity(session, entity.eid)
         for container in entity.fti_containers():
             session.repo.index_entity(session, container)
-            
+
     def commit_event(self):
         pass
 
@@ -120,14 +120,14 @@
             'DELETE X %s Y WHERE NOT X eid %%(x)s, Y eid %%(y)s' % rtype,
             {'x': eidfrom, 'y': eidto}, 'y')
 
-    
+
 class Repository(object):
     """a repository provides access to a set of persistent storages for
     entities and relations
 
     XXX protect pyro access
     """
-    
+
     def __init__(self, config, vreg=None, debug=False):
         self.config = config
         if vreg is None:
@@ -155,7 +155,7 @@
         for uri, source_config in config.sources().items():
             if uri == 'admin':
                 # not an actual source
-                continue 
+                continue
             source = self.get_source(uri, source_config)
             self.sources_by_uri[uri] = source
             self.sources.append(source)
@@ -180,7 +180,7 @@
             self.warning("set fs application'schema as bootstrap schema")
             config.bootstrap_cubes()
             self.set_bootstrap_schema(self.config.load_schema())
-            # need to load the Any and EUser entity types
+            # need to load the Any and CWUser entity types
             self.vreg.schema = self.schema
             etdirectory = join(CW_SOFTWARE_ROOT, 'entities')
             self.vreg.init_registration([etdirectory])
@@ -194,7 +194,7 @@
             config.bootstrap_cubes()
             self.set_schema(self.config.load_schema())
         if not config.creating:
-            if 'EProperty' in self.schema:
+            if 'CWProperty' in self.schema:
                 self.vreg.init_properties(self.properties())
             # call source's init method to complete their initialisation if
             # needed (for instance looking for persistent configuration using an
@@ -214,16 +214,16 @@
                 source.init_creating()
         # close initialization pool and reopen fresh ones for proper
         # initialization now that we know cubes
-        self._get_pool().close(True) 
+        self._get_pool().close(True)
         for i in xrange(config['connections-pool-size']):
             self._available_pools.put_nowait(ConnectionsPool(self.sources))
-        
+
     # internals ###############################################################
 
     def get_source(self, uri, source_config):
         source_config['uri'] = uri
         return get_source(source_config, self.schema, self)
-        
+
     def set_schema(self, schema, resetvreg=True):
         schema.rebuild_infered_relations()
         self.info('set schema %s %#x', schema.name, id(schema))
@@ -257,11 +257,13 @@
             except BadSchemaDefinition:
                 raise
             except Exception, ex:
-                raise Exception('Is the database initialised ? (cause: %s)' % 
+                import traceback
+                traceback.print_exc()
+                raise Exception('Is the database initialised ? (cause: %s)' %
                                 (ex.args and ex.args[0].strip() or 'unknown')), \
                                 None, sys.exc_info()[-1]
             self.info('set the actual schema')
-            # XXX have to do this since EProperty isn't in the bootstrap schema
+            # XXX have to do this since CWProperty isn't in the bootstrap schema
             #     it'll be redone in set_schema
             self.set_bootstrap_schema(appschema)
             # 2.49 migration
@@ -269,13 +271,13 @@
                 session.set_pool()
                 if not 'template' in file(join(self.config.apphome, 'vc.conf')).read():
                     # remaning from cubicweb < 2.38...
-                    session.execute('DELETE EProperty X WHERE X pkey "system.version.template"')
+                    session.execute('DELETE CWProperty X WHERE X pkey "system.version.template"')
                     session.commit()
         finally:
             session.close()
         self.config.init_cubes(self.get_cubes())
         self.set_schema(appschema)
-        
+
     def set_bootstrap_schema(self, schema):
         """disable hooks when setting a bootstrap schema, but restore
         the configuration for the next time
@@ -293,7 +295,7 @@
         config.schema_hooks = True
         config.notification_hooks = True
         config.application_hooks = True
-            
+
     def start_looping_tasks(self):
         assert isinstance(self._looping_tasks, list), 'already started'
         for i, (interval, func) in enumerate(self._looping_tasks):
@@ -306,7 +308,7 @@
 
     def looping_task(self, interval, func):
         """register a function to be called every `interval` seconds.
-        
+
         looping tasks can only be registered during repository initialization,
         once done this method will fail.
         """
@@ -319,7 +321,7 @@
         """start function in a separated thread"""
         t = RepoThread(func, self._running_threads)
         t.start()
-        
+
     #@locked
     def _get_pool(self):
         try:
@@ -330,7 +332,7 @@
                             'connections) or to much load on the server (in '
                             'which case you can try to set a bigger '
                             'connections pools size)')
-        
+
     def _free_pool(self, pool):
         pool.rollback()
         self._available_pools.put_nowait(pool)
@@ -380,13 +382,13 @@
                       ((hits + misses) * 100) / (hits + misses + nocache))
         except ZeroDivisionError:
             pass
-        
+
     def authenticate_user(self, session, login, password):
         """validate login / password, raise AuthenticationError on failure
-        return associated EUser instance on success
+        return associated CWUser instance on success
         """
         for source in self.sources:
-            if source.support_entity('EUser'):
+            if source.support_entity('CWUser'):
                 try:
                     eid = source.authenticate(session, login, password)
                     break
@@ -401,8 +403,8 @@
         return euser
 
     def _build_user(self, session, eid):
-        """return a EUser entity for user with the given eid"""
-        cls = self.vreg.etype_class('EUser')
+        """return a CWUser entity for user with the given eid"""
+        cls = self.vreg.etype_class('CWUser')
         rql = cls.fetch_rql(session.user, ['X eid %(x)s'])
         rset = session.execute(rql, {'x': eid}, 'x')
         assert len(rset) == 1, rset
@@ -413,9 +415,9 @@
         euser.groups
         euser.properties
         return euser
-        
+
     # public (dbapi) interface ################################################
-            
+
     def get_schema(self):
         """return the application schema. This is a public method, not
         requiring a session id
@@ -447,7 +449,7 @@
         session = self.internal_session()
         try:
             for pk, version in session.execute(
-                'Any K,V WHERE P is EProperty, P value V, P pkey K, '
+                'Any K,V WHERE P is CWProperty, P value V, P pkey K, '
                 'P pkey ~="system.version.%"', build_descr=False):
                 cube = pk.split('.')[-1]
                 # XXX cubicweb migration
@@ -467,7 +469,7 @@
         finally:
             session.close()
         return vcconf
-    
+
     @cached
     def source_defs(self):
         sources = self.config.sources().copy()
@@ -484,7 +486,7 @@
         """return a result set containing system wide properties"""
         session = self.internal_session()
         try:
-            return session.execute('Any K,V WHERE P is EProperty,'
+            return session.execute('Any K,V WHERE P is CWProperty,'
                                    'P pkey K, P value V, NOT P for_user U',
                                    build_descr=False)
         finally:
@@ -499,12 +501,12 @@
         # for consistency, keep same error as unique check hook (although not required)
         errmsg = session._('the value "%s" is already used, use another one')
         try:
-            if (session.execute('EUser X WHERE X login %(login)s', {'login': login})
-                or session.execute('EUser X WHERE X use_email C, C address %(login)s',
+            if (session.execute('CWUser X WHERE X login %(login)s', {'login': login})
+                or session.execute('CWUser X WHERE X use_email C, C address %(login)s',
                                    {'login': login})):
                 raise ValidationError(None, {'login': errmsg % login})
             # we have to create the user
-            user = self.vreg.etype_class('EUser')(session, None)
+            user = self.vreg.etype_class('CWUser')(session, None)
             if isinstance(password, unicode):
                 # password should *always* be utf8 encoded
                 password = password.encode('UTF8')
@@ -524,13 +526,13 @@
         finally:
             session.close()
         return True
-        
+
     def connect(self, login, password, cnxprops=None):
         """open a connection for a given user
 
         base_url may be needed to send mails
         cnxtype indicate if this is a pyro connection or a in-memory connection
-        
+
         raise `AuthenticationError` if the authentication failed
         raise `ConnectionError` if we can't open a connection
         """
@@ -582,7 +584,7 @@
                 raise
         finally:
             session.reset_pool()
-    
+
     def describe(self, sessionid, eid):
         """return a tuple (type, source, extid) for the entity with id <eid>"""
         session = self._get_session(sessionid, setpool=True)
@@ -616,12 +618,12 @@
         self.debug('begin commit for session %s', sessionid)
         try:
             self._get_session(sessionid, setpool=True).commit()
-        except (ValidationError, Unauthorized): 
+        except (ValidationError, Unauthorized):
             raise
         except:
             self.exception('unexpected error')
             raise
-        
+
     def rollback(self, sessionid):
         """commit transaction for the session with the given id"""
         self.debug('begin rollback for session %s', sessionid)
@@ -643,7 +645,7 @@
         session.close()
         del self._sessions[sessionid]
         self.info('closed session %s for user %s', sessionid, session.user.login)
-    
+
     def user_info(self, sessionid, props=None):
         """this method should be used by client to:
         * check session id validity
@@ -657,9 +659,9 @@
                 session.change_property(prop, value)
         user = session.user
         return user.eid, user.login, user.groups, user.properties
-            
+
     # public (inter-repository) interface #####################################
-    
+
     def entities_modified_since(self, etypes, mtime):
         """function designed to be called from an external repository which
         is using this one as a rql source for synchronization, and return a
@@ -681,7 +683,7 @@
             session.close()
 
     # session handling ########################################################
-        
+
     def close_sessions(self):
         """close every opened sessions"""
         for sessionid in self._sessions.keys():
@@ -703,7 +705,7 @@
                 self.close(session.id)
                 nbclosed += 1
         return nbclosed
-    
+
     def internal_session(self, cnxprops=None):
         """return a dbapi like connection/cursor using internal user which
         have every rights on the repository. You'll *have to* commit/rollback
@@ -714,7 +716,7 @@
         session = InternalSession(self, cnxprops)
         session.set_pool()
         return session
-            
+
     def _get_session(self, sessionid, setpool=False):
         """return the user associated to the given session identifier"""
         try:
@@ -729,7 +731,7 @@
     # * correspondance between eid and (type, source)
     # * correspondance between eid and local id (i.e. specific to a given source)
     # * searchable text indexes
-    
+
     def type_and_source_from_eid(self, eid, session=None):
         """return a tuple (type, source, extid) for the entity with id <eid>"""
         try:
@@ -769,15 +771,15 @@
             rqlcache.pop('Any X WHERE X eid %s' % eid, None)
             for source in self.sources:
                 source.clear_eid_cache(eid, etype)
-                
+
     def type_from_eid(self, eid, session=None):
         """return the type of the entity with id <eid>"""
         return self.type_and_source_from_eid(eid, session)[0]
-    
+
     def source_from_eid(self, eid, session=None):
         """return the source for the given entity's eid"""
         return self.sources_by_uri[self.type_and_source_from_eid(eid, session)[1]]
-        
+
     def eid2extid(self, source, eid, session=None):
         """get local id from an eid"""
         etype, uri, extid = self.type_and_source_from_eid(eid, session)
@@ -846,7 +848,7 @@
         except:
             session.rollback(reset_pool)
             raise
-        
+
     def add_info(self, session, entity, source, extid=None, complete=True):
         """add type and source info for an eid into the system table,
         and index the entity with the full text index
@@ -860,11 +862,11 @@
         if self.do_fti:
             FTIndexEntityOp(session, entity=entity)
         CleanupEidTypeCacheOp(session)
-        
+
     def delete_info(self, session, eid):
         self._prepare_delete_info(session, eid)
         self._delete_info(session, eid)
-        
+
     def _prepare_delete_info(self, session, eid):
         """prepare the repository for deletion of an entity:
         * update the fti
@@ -875,7 +877,7 @@
         pending = session.query_data('pendingeids', set(), setdefault=True)
         pending.add(eid)
         CleanupEidTypeCacheOp(session)
-        
+
     def _delete_info(self, session, eid):
         """delete system information on deletion of an entity:
         * delete all relations on this entity
@@ -884,7 +886,7 @@
         etype, uri, extid = self.type_and_source_from_eid(eid, session)
         self._clear_eid_relations(session, etype, eid)
         self.system_source.delete_info(session, eid, etype, uri, extid)
-        
+
     def _clear_eid_relations(self, session, etype, eid):
         """when a entity is deleted, build and execute rql query to delete all
         its relations
@@ -915,7 +917,7 @@
             return
         alreadydone.add(entity.eid)
         self.system_source.fti_index_entity(session, entity)
-        
+
     def locate_relation_source(self, session, subject, rtype, object):
         subjsource = self.source_from_eid(subject, session)
         objsource = self.source_from_eid(object, session)
@@ -926,17 +928,17 @@
         else:
             source = subjsource
         return source
-    
+
     def locate_etype_source(self, etype):
         for source in self.sources:
             if source.support_entity(etype, 1):
                 return source
         else:
             raise ETypeNotSupportedBySources(etype)
-        
+
     def glob_add_entity(self, session, entity):
         """add an entity to the repository
-        
+
         the entity eid should originaly be None and a unique eid is assigned to
         the entity instance
         """
@@ -979,7 +981,7 @@
                 self.hm.call_hooks('after_add_relation', attr, session,
                                     entity.eid, attr, value)
         return entity.eid
-        
+
     def glob_update_entity(self, session, entity):
         """replace an entity in the repository
         the type and the eid of an entity must not be changed
@@ -1049,7 +1051,7 @@
         if source.should_call_hooks:
             self.hm.call_hooks('after_delete_entity', etype, session, eid)
         # don't clear cache here this is done in a hook on commit
-        
+
     def glob_add_relation(self, session, subject, rtype, object):
         """add a relation to the repository"""
         assert subject is not None
@@ -1087,7 +1089,7 @@
 
 
     # pyro handling ###########################################################
-    
+
     def pyro_register(self, host=''):
         """register the repository as a pyro object"""
         from Pyro import core
@@ -1106,7 +1108,7 @@
         self.info(msg, nsgroup, nsid)
         self.pyro_registered = True
         return daemon
-    
+
     def pyro_nameserver(self, host=None, group=None):
         """locate and bind the the name server to the daemon"""
         from Pyro import naming, errors
@@ -1121,25 +1123,25 @@
         return nameserver
 
     # multi-sources planner helpers ###########################################
-    
+
     @cached
     def rel_type_sources(self, rtype):
         return [source for source in self.sources
                 if source.support_relation(rtype)
                 or rtype in source.dont_cross_relations]
-    
+
     @cached
     def can_cross_relation(self, rtype):
         return [source for source in self.sources
                 if source.support_relation(rtype)
                 and rtype in source.cross_relations]
-    
+
     @cached
     def is_multi_sources_relation(self, rtype):
         return any(source for source in self.sources
                    if not source is self.system_source
                    and source.support_relation(rtype))
-    
+
 
 def pyro_unregister(config):
     """unregister the repository from the pyro name server"""
--- a/server/schemahooks.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/schemahooks.py	Fri Apr 24 19:46:47 2009 +0200
@@ -23,8 +23,8 @@
                                      check_internal_entity)
     
 # core entity and relation types which can't be removed
-CORE_ETYPES = list(BASE_TYPES) + ['EEType', 'ERType', 'EUser', 'EGroup',
-                                  'EConstraint', 'EFRDef', 'ENFRDef']
+CORE_ETYPES = list(BASE_TYPES) + ['CWEType', 'CWRType', 'CWUser', 'CWGroup',
+                                  'CWConstraint', 'CWAttribute', 'CWRelation']
 CORE_RTYPES = ['eid', 'creation_date', 'modification_date',
                'login', 'upassword', 'name',
                'is', 'instanceof', 'owned_by', 'created_by', 'in_group',
@@ -134,7 +134,7 @@
 
 # deletion ####################################################################
 
-class DeleteEETypeOp(SchemaOperation):
+class DeleteCWETypeOp(SchemaOperation):
     """actually remove the entity type from the application's schema"""    
     def commit_event(self):
         try:
@@ -145,9 +145,9 @@
             pass
 
 def before_del_eetype(session, eid):
-    """before deleting a EEType entity:
+    """before deleting a CWEType entity:
     * check that we don't remove a core entity type
-    * cascade to delete related EFRDef and ENFRDef entities
+    * cascade to delete related CWAttribute and CWRelation entities
     * instantiate an operation to delete the entity type on commit
     """
     # final entities can't be deleted, don't care about that
@@ -155,7 +155,7 @@
     # delete every entities of this type
     session.unsafe_execute('DELETE %s X' % name)
     DropTableOp(session, table=SQL_PREFIX + name)
-    DeleteEETypeOp(session, name)
+    DeleteCWETypeOp(session, name)
 
 def after_del_eetype(session, eid):
     # workflow cleanup
@@ -163,7 +163,7 @@
     session.execute('DELETE Transition X WHERE NOT X transition_of Y')
 
         
-class DeleteERTypeOp(SchemaOperation):
+class DeleteCWRTypeOp(SchemaOperation):
     """actually remove the relation type from the application's schema"""    
     def commit_event(self):
         try:
@@ -173,18 +173,18 @@
             pass
 
 def before_del_ertype(session, eid):
-    """before deleting a ERType entity:
+    """before deleting a CWRType entity:
     * check that we don't remove a core relation type
-    * cascade to delete related EFRDef and ENFRDef entities
+    * cascade to delete related CWAttribute and CWRelation entities
     * instantiate an operation to delete the relation type on commit
     """
     name = check_internal_entity(session, eid, CORE_RTYPES)
     # delete relation definitions using this relation type
-    session.execute('DELETE EFRDef X WHERE X relation_type Y, Y eid %(x)s',
+    session.execute('DELETE CWAttribute X WHERE X relation_type Y, Y eid %(x)s',
                     {'x': eid})
-    session.execute('DELETE ENFRDef X WHERE X relation_type Y, Y eid %(x)s',
+    session.execute('DELETE CWRelation X WHERE X relation_type Y, Y eid %(x)s',
                     {'x': eid})
-    DeleteERTypeOp(session, name)
+    DeleteCWRTypeOp(session, name)
 
     
 class DelErdefOp(SchemaOperation):
@@ -198,7 +198,7 @@
             pass
         
 def after_del_relation_type(session, rdefeid, rtype, rteid):
-    """before deleting a EFRDef or ENFRDef entity:
+    """before deleting a CWAttribute or CWRelation entity:
     * if this is a final or inlined relation definition, instantiate an
       operation to drop necessary column, else if this is the last instance
       of a non final relation, instantiate an operation to drop necessary
@@ -210,9 +210,9 @@
     pendings = session.query_data('pendingeids', ())
     # first delete existing relation if necessary
     if rschema.is_final():
-        rdeftype = 'EFRDef'
+        rdeftype = 'CWAttribute'
     else:
-        rdeftype = 'ENFRDef'
+        rdeftype = 'CWRelation'
         if not (subjschema.eid in pendings or objschema.eid in pendings):
             session.execute('DELETE X %s Y WHERE X is %s, Y is %s'
                             % (rschema, subjschema, objschema))
@@ -235,13 +235,13 @@
         DropTableOp(session, table='%s_relation' % rschema.type)
     # if this is the last instance, drop associated relation type
     if lastrel and not rteid in pendings:
-        execute('DELETE ERType X WHERE X eid %(x)s', {'x': rteid}, 'x')
+        execute('DELETE CWRType X WHERE X eid %(x)s', {'x': rteid}, 'x')
     DelErdefOp(session, (subjschema, rschema, objschema))
 
         
 # addition ####################################################################
 
-class AddEETypeOp(EarlySchemaOperation):
+class AddCWETypeOp(EarlySchemaOperation):
     """actually add the entity type to the application's schema"""    
     eid = None # make pylint happy
     def commit_event(self):
@@ -249,7 +249,7 @@
         eschema.eid = self.eid
         
 def before_add_eetype(session, entity):
-    """before adding a EEType entity:
+    """before adding a CWEType entity:
     * check that we are not using an existing entity type,
     """
     name = entity['name']
@@ -258,11 +258,11 @@
         raise RepositoryError('an entity type %s already exists' % name)
 
 def after_add_eetype(session, entity):
-    """after adding a EEType entity:
+    """after adding a CWEType entity:
     * create the necessary table
     * set creation_date and modification_date by creating the necessary
-      EFRDef entities
-    * add owned_by relation by creating the necessary ENFRDef entity
+      CWAttribute entities
+    * add owned_by relation by creating the necessary CWRelation entity
     * register an operation to add the entity type to the application's
       schema on commit
     """
@@ -297,13 +297,13 @@
     # register operation to modify the schema on commit
     # this have to be done before adding other relations definitions
     # or permission settings
-    AddEETypeOp(session, etype, eid=entity.eid)
+    AddCWETypeOp(session, etype, eid=entity.eid)
     # add meta creation_date, modification_date and owned_by relations
     for rql, kwargs in relrqls:
         session.execute(rql, kwargs)
 
 
-class AddERTypeOp(EarlySchemaOperation):
+class AddCWRTypeOp(EarlySchemaOperation):
     """actually add the relation type to the application's schema"""    
     eid = None # make pylint happy
     def commit_event(self):
@@ -312,7 +312,7 @@
         rschema.eid = self.eid
         
 def before_add_ertype(session, entity):
-    """before adding a ERType entity:
+    """before adding a CWRType entity:
     * check that we are not using an existing relation type,
     * register an operation to add the relation type to the application's
       schema on commit
@@ -324,12 +324,12 @@
         raise RepositoryError('a relation type %s already exists' % name)
     
 def after_add_ertype(session, entity):
-    """after a ERType entity has been added:
+    """after a CWRType entity has been added:
     * register an operation to add the relation type to the application's
       schema on commit
     We don't know yeat this point if a table is necessary
     """
-    AddERTypeOp(session, RelationType(name=entity['name'],
+    AddCWRTypeOp(session, RelationType(name=entity['name'],
                                       description=entity.get('description'),
                                       meta=entity.get('meta', False),
                                       inlined=entity.get('inlined', False),
@@ -356,8 +356,8 @@
     }
 
 
-class AddEFRDefPreCommitOp(PreCommitOperation):
-    """an attribute relation (EFRDef) has been added:
+class AddCWAttributePreCommitOp(PreCommitOperation):
+    """an attribute relation (CWAttribute) has been added:
     * add the necessary column
     * set default on this column if any and possible
     * register an operation to add the relation definition to the
@@ -439,10 +439,10 @@
         AddErdefOp(session, rdef)
 
 def after_add_efrdef(session, entity):
-    AddEFRDefPreCommitOp(session, entity=entity)
+    AddCWAttributePreCommitOp(session, entity=entity)
 
 
-class AddENFRDefPreCommitOp(PreCommitOperation):
+class AddCWRelationPreCommitOp(PreCommitOperation):
     """an actual relation has been added:
     * if this is an inlined relation, add the necessary column
       else if it's the first instance of this relation type, add the
@@ -510,7 +510,7 @@
                 session.add_query_data('createdtables', rtype)
                 
 def after_add_enfrdef(session, entity):
-    AddENFRDefPreCommitOp(session, entity=entity)
+    AddCWRelationPreCommitOp(session, entity=entity)
 
 
 # update ######################################################################
@@ -846,7 +846,7 @@
 def after_add_permission(session, subject, rtype, object):
     """added entity/relation *_permission, need to update schema"""
     perm = rtype.split('_', 1)[0]
-    if session.describe(object)[0] == 'EGroup':
+    if session.describe(object)[0] == 'CWGroup':
         AddGroupPermissionOp(session, perm, subject, object)
     else: # RQLExpression
         expr = session.execute('Any EXPR WHERE X eid %(x)s, X expression EXPR',
@@ -906,7 +906,7 @@
     if subject in session.query_data('pendingeids', ()):
         return
     perm = rtype.split('_', 1)[0]
-    if session.describe(object)[0] == 'EGroup':
+    if session.describe(object)[0] == 'CWGroup':
         DelGroupPermissionOp(session, perm, subject, object)
     else: # RQLExpression
         expr = session.execute('Any EXPR WHERE X eid %(x)s, X expression EXPR',
@@ -925,28 +925,28 @@
     """register schema related hooks on the hooks manager"""
     # schema synchronisation #####################
     # before/after add
-    hm.register_hook(before_add_eetype, 'before_add_entity', 'EEType')
-    hm.register_hook(before_add_ertype, 'before_add_entity', 'ERType')
-    hm.register_hook(after_add_eetype, 'after_add_entity', 'EEType')
-    hm.register_hook(after_add_ertype, 'after_add_entity', 'ERType')
-    hm.register_hook(after_add_efrdef, 'after_add_entity', 'EFRDef')
-    hm.register_hook(after_add_enfrdef, 'after_add_entity', 'ENFRDef')
+    hm.register_hook(before_add_eetype, 'before_add_entity', 'CWEType')
+    hm.register_hook(before_add_ertype, 'before_add_entity', 'CWRType')
+    hm.register_hook(after_add_eetype, 'after_add_entity', 'CWEType')
+    hm.register_hook(after_add_ertype, 'after_add_entity', 'CWRType')
+    hm.register_hook(after_add_efrdef, 'after_add_entity', 'CWAttribute')
+    hm.register_hook(after_add_enfrdef, 'after_add_entity', 'CWRelation')
     # before/after update
-    hm.register_hook(before_update_eetype, 'before_update_entity', 'EEType')
-    hm.register_hook(before_update_ertype, 'before_update_entity', 'ERType')
-    hm.register_hook(after_update_ertype, 'after_update_entity', 'ERType')
-    hm.register_hook(after_update_erdef, 'after_update_entity', 'EFRDef')
-    hm.register_hook(after_update_erdef, 'after_update_entity', 'ENFRDef')
+    hm.register_hook(before_update_eetype, 'before_update_entity', 'CWEType')
+    hm.register_hook(before_update_ertype, 'before_update_entity', 'CWRType')
+    hm.register_hook(after_update_ertype, 'after_update_entity', 'CWRType')
+    hm.register_hook(after_update_erdef, 'after_update_entity', 'CWAttribute')
+    hm.register_hook(after_update_erdef, 'after_update_entity', 'CWRelation')
     # before/after delete
-    hm.register_hook(before_del_eetype, 'before_delete_entity', 'EEType')
-    hm.register_hook(after_del_eetype, 'after_delete_entity', 'EEType')
-    hm.register_hook(before_del_ertype, 'before_delete_entity', 'ERType')
+    hm.register_hook(before_del_eetype, 'before_delete_entity', 'CWEType')
+    hm.register_hook(after_del_eetype, 'after_delete_entity', 'CWEType')
+    hm.register_hook(before_del_ertype, 'before_delete_entity', 'CWRType')
     hm.register_hook(after_del_relation_type, 'after_delete_relation', 'relation_type')
     hm.register_hook(rebuild_infered_relations, 'after_add_relation', 'specializes')
     hm.register_hook(rebuild_infered_relations, 'after_delete_relation', 'specializes')    
     # constraints synchronization hooks
-    hm.register_hook(after_add_econstraint, 'after_add_entity', 'EConstraint')
-    hm.register_hook(after_update_econstraint, 'after_update_entity', 'EConstraint')
+    hm.register_hook(after_add_econstraint, 'after_add_entity', 'CWConstraint')
+    hm.register_hook(after_update_econstraint, 'after_update_entity', 'CWConstraint')
     hm.register_hook(before_delete_constrained_by, 'before_delete_relation', 'constrained_by')
     hm.register_hook(after_add_constrained_by, 'after_add_relation', 'constrained_by')
     # permissions synchronisation ################
--- a/server/schemaserial.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/schemaserial.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,11 +1,12 @@
 """functions for schema / permissions (de)serialization using RQL
 
 :organization: Logilab
-:copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 """
 __docformat__ = "restructuredtext en"
 
+import sys
 from itertools import chain
 
 from logilab.common.shellutils import ProgressBar
@@ -18,12 +19,12 @@
     """create a group mapping from an rql cursor
 
     A group mapping has standard group names as key (managers, owners at least)
-    and the actual EGroup entity's eid as associated value.
+    and the actual CWGroup entity's eid as associated value.
     In interactive mode (the default), missing groups'eid will be prompted
     from the user.
     """
     res = {}
-    for eid, name in cursor.execute('Any G, N WHERE G is EGroup, G name N'):
+    for eid, name in cursor.execute('Any G, N WHERE G is CWGroup, G name N'):
         res[name] = eid
     if not interactive:
         return res
@@ -46,18 +47,68 @@
                     continue
     return res
 
+def _set_sql_prefix(prefix):
+    """3.2.0 migration function: allow to unset/reset SQL_PREFIX"""
+    for module in ('checkintegrity', 'migractions', 'schemahooks',
+                   'sources.rql2sql', 'sources.native'):
+        try:
+            sys.modules['cubicweb.server.%s' % module].SQL_PREFIX = prefix
+            print 'changed SQL_PREFIX for %s' % module
+        except KeyError:
+            pass
+        
+def _update_database(schema, sqlcu):
+    """3.2.0 migration function: update database schema by adding SQL_PREFIX to
+    entity type tables and columns
+    """
+    for etype in schema.entities():
+        if etype.is_final():
+            continue
+        try:
+            sql = 'ALTER TABLE %s RENAME TO cw_%s' % (
+                etype, ETYPE_NAME_MAP.get(etype, etype))
+            print sql
+            sqlcu.execute(sql)
+        except:
+            pass
+        for rschema in etype.subject_relations():
+            if rschema == 'has_text':
+                continue
+            if rschema.is_final() or rschema.inlined:
+                sql = 'ALTER TABLE cw_%s RENAME %s TO cw_%s' % (
+                    etype, rschema, rschema)
+                print sql
+                sqlcu.execute(sql)
+
 # schema / perms deserialization ##############################################
 
 def deserialize_schema(schema, session):
     """return a schema according to information stored in an rql database
-    as ERType and EEType entities
+    as CWRType and CWEType entities
     """
+    #
+    repo = session.repo
+    sqlcu = session.pool['system']
+    _3_2_migration = False
+    if 'eetype' in [t.lower() for t in repo.system_source.dbhelper.list_tables(sqlcu)]:
+        _3_2_migration = True
+        # 3.2 migration
+        _set_sql_prefix('')
+        # first rename entity types whose name changed in 3.2 without adding the
+        # cw_ prefix
+        for etype in ('EFRDef', 'ENFRDef', 'ERType', 'EEType',
+                      'EConstraintType', 'EConstraint', 'EGroup', 'EUser',
+                      'ECache', 'EPermission', 'EProperty'):
+            sql = 'ALTER TABLE %s RENAME TO %s' % (etype, ETYPE_NAME_MAP[etype])
+            print sql
+            sqlcu.execute(sql)
+        # other table renaming done once schema has been readen
     # print 'reading schema from the database...'
     index = {}
     permsdict = deserialize_ertype_permissions(session)
     schema.reading_from_database = True
     for eid, etype, desc, meta in session.execute('Any X, N, D, M WHERE '
-                                                  'X is EEType, X name N, '
+                                                  'X is CWEType, X name N, '
                                                   'X description D, X meta M',
                                                   build_descr=False):
         # base types are already in the schema, skip them
@@ -70,7 +121,7 @@
         if etype in ETYPE_NAME_MAP: # XXX <2.45 bw compat
             print 'fixing etype name from %s to %s' % (etype, ETYPE_NAME_MAP[etype])
             # can't use write rql queries at this point, use raw sql
-            session.system_sql('UPDATE EEType SET name=%(n)s WHERE eid=%(x)s',
+            session.system_sql('UPDATE CWEType SET name=%(n)s WHERE eid=%(x)s',
                                {'x': eid, 'n': ETYPE_NAME_MAP[etype]})
             session.system_sql('UPDATE entities SET type=%(n)s WHERE type=%(x)s',
                                {'x': etype, 'n': ETYPE_NAME_MAP[etype]})
@@ -91,7 +142,7 @@
         index[eid] = eschema
         set_perms(eschema, permsdict.get(eid, {}))
     try:
-        rset = session.execute('Any XN, ETN WHERE X is EEType, X name XN, '
+        rset = session.execute('Any XN, ETN WHERE X is CWEType, X name XN, '
                                'X specializes ET, ET name ETN')
     except: # `specializes` relation not available for versions prior to 2.50
         session.rollback(False)
@@ -102,7 +153,7 @@
             eschema._specialized_type = stype
             seschema._specialized_by.append(etype)
     for eid, rtype, desc, meta, sym, il in session.execute(
-        'Any X,N,D,M,S,I WHERE X is ERType, X name N, X description D, '
+        'Any X,N,D,M,S,I WHERE X is CWRType, X name N, X description D, '
         'X meta M, X symetric S, X inlined I', build_descr=False):
         try:
             # bw compat: fulltext_container added in 2.47
@@ -119,7 +170,7 @@
         set_perms(rschema, permsdict.get(eid, {}))        
     cstrsdict = deserialize_rdef_constraints(session)
     for values in session.execute(
-        'Any X,SE,RT,OE,CARD,ORD,DESC,IDX,FTIDX,I18N,DFLT WHERE X is EFRDef,'
+        'Any X,SE,RT,OE,CARD,ORD,DESC,IDX,FTIDX,I18N,DFLT WHERE X is CWAttribute,'
         'X relation_type RT, X cardinality CARD, X ordernum ORD, X indexed IDX,'
         'X description DESC, X internationalizable I18N, X defaultval DFLT,'
         'X fulltextindexed FTIDX, X from_entity SE, X to_entity OE',
@@ -137,7 +188,7 @@
                                   default=default, eid=rdefeid)
         schema.add_relation_def(rdef)
     for values in session.execute(
-        'Any X,SE,RT,OE,CARD,ORD,DESC,C WHERE X is ENFRDef, X relation_type RT,'
+        'Any X,SE,RT,OE,CARD,ORD,DESC,C WHERE X is CWRelation, X relation_type RT,'
         'X cardinality CARD, X ordernum ORD, X description DESC, '
         'X from_entity SE, X to_entity OE, X composite C', build_descr=False):
         rdefeid, seid, reid, teid, card, ord, desc, c = values
@@ -151,6 +202,9 @@
                                   eid=rdefeid)
         schema.add_relation_def(rdef)
     schema.infer_specialization_rules()
+    if _3_2_migration:
+        _update_database(schema, sqlcu)
+        _set_sql_prefix('cw_')
     session.commit()
     schema.reading_from_database = False
 
@@ -159,11 +213,11 @@
     """return sect action:groups associations for the given
     entity or relation schema with its eid, according to schema's
     permissions stored in the database as [read|add|delete|update]_permission
-    relations between EEType/ERType and EGroup entities
+    relations between CWEType/CWRType and CWGroup entities
     """
     res = {}
     for action in ('read', 'add', 'update', 'delete'):
-        rql = 'Any E,N WHERE G is EGroup, G name N, E %s_permission G' % action
+        rql = 'Any E,N WHERE G is CWGroup, G name N, E %s_permission G' % action
         for eid, gname in session.execute(rql, build_descr=False):
             res.setdefault(eid, {}).setdefault(action, []).append(gname)
         rql = ('Any E,X,EXPR,V WHERE X is RQLExpression, X expression EXPR, '
@@ -194,7 +248,7 @@
     """return the list of relation definition's constraints as instances"""
     res = {}
     for rdefeid, ceid, ct, val in session.execute(
-        'Any E, X,TN,V WHERE E constrained_by X, X is EConstraint, '
+        'Any E, X,TN,V WHERE E constrained_by X, X is CWConstraint, '
         'X cstrtype T, T name TN, X value V', build_descr=False):
         cstr = CONSTRAINTS[ct].deserialize(val)
         cstr.eid = ceid
@@ -215,7 +269,7 @@
         pb_size = len(aller) + len(CONSTRAINTS) + len([x for x in eschemas if x.specializes()])
         pb = ProgressBar(pb_size)
     for cstrtype in CONSTRAINTS:
-        rql = 'INSERT EConstraintType X: X name "%s"' % cstrtype
+        rql = 'INSERT CWConstraintType X: X name "%s"' % cstrtype
         if verbose:
             print rql
         cursor.execute(rql)
@@ -341,7 +395,7 @@
 
 def schema2rql(schema, skip=None, allow=None):
     """return a list of rql insert statements to enter the schema in the
-    database as ERType and EEType entities
+    database as CWRType and CWEType entities
     """
     assert not (skip is not None and allow is not None), \
            'can\'t use both skip and allow'
@@ -359,12 +413,12 @@
 
 def eschema2rql(eschema):
     """return a list of rql insert statements to enter an entity schema
-    in the database as an EEType entity
+    in the database as an CWEType entity
     """
     relations, values = eschema_relations_values(eschema)
     # NOTE: 'specializes' relation can't be inserted here since there's no
     # way to make sure the parent type is inserted before the child type
-    yield 'INSERT EEType X: %s' % ','.join(relations) , values
+    yield 'INSERT CWEType X: %s' % ','.join(relations) , values
 
 def specialize2rql(schema):
     for eschema in schema.entities():
@@ -379,12 +433,12 @@
 
 def rschema2rql(rschema, addrdef=True):
     """return a list of rql insert statements to enter a relation schema
-    in the database as an ERType entity
+    in the database as an CWRType entity
     """
     if rschema.type == 'has_text':
         return
     relations, values = rschema_relations_values(rschema)
-    yield 'INSERT ERType X: %s' % ','.join(relations), values
+    yield 'INSERT CWRType X: %s' % ','.join(relations), values
     if addrdef:
         for rql, values in rdef2rql(rschema):
             yield rql, values
@@ -401,17 +455,17 @@
     relations, values = frdef_relations_values(rschema, objtype, props)
     relations.append(_LOCATE_RDEF_RQL0)
     values.update({'se': str(subjtype), 'rt': str(rschema), 'oe': str(objtype)})
-    yield 'INSERT EFRDef X: %s WHERE %s' % (','.join(relations), _LOCATE_RDEF_RQL1), values
+    yield 'INSERT CWAttribute X: %s WHERE %s' % (','.join(relations), _LOCATE_RDEF_RQL1), values
     for rql, values in rdefrelations2rql(rschema, subjtype, objtype, props):
-        yield rql + ', EDEF is EFRDef', values
+        yield rql + ', EDEF is CWAttribute', values
             
 def nfrdef2rql(rschema, subjtype, objtype, props):
     relations, values = nfrdef_relations_values(rschema, objtype, props)
     relations.append(_LOCATE_RDEF_RQL0)
     values.update({'se': str(subjtype), 'rt': str(rschema), 'oe': str(objtype)})
-    yield 'INSERT ENFRDef X: %s WHERE %s' % (','.join(relations), _LOCATE_RDEF_RQL1), values
+    yield 'INSERT CWRelation X: %s WHERE %s' % (','.join(relations), _LOCATE_RDEF_RQL1), values
     for rql, values in rdefrelations2rql(rschema, subjtype, objtype, props):
-        yield rql + ', EDEF is ENFRDef', values
+        yield rql + ', EDEF is CWRelation', values
                 
 def rdefrelations2rql(rschema, subjtype, objtype, props):
     iterators = []
@@ -423,14 +477,14 @@
     values = {'ctname': unicode(constraint.type()),
               'value': unicode(constraint.serialize()),
               'rt': str(rschema), 'se': str(subjtype), 'oe': str(objtype)}
-    yield 'INSERT EConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE \
+    yield 'INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE \
 CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, \
 ER name %(rt)s, SE name %(se)s, OE name %(oe)s', values
 
 def perms2rql(schema, groupmapping):
     """return rql insert statements to enter the schema's permissions in
     the database as [read|add|delete|update]_permission relations between
-    EEType/ERType and EGroup entities
+    CWEType/CWRType and CWGroup entities
 
     groupmapping is a dictionnary mapping standard group names to
     eids
@@ -443,10 +497,10 @@
 def erperms2rql(erschema, groupmapping):
     """return rql insert statements to enter the entity or relation
     schema's permissions in the database as
-    [read|add|delete|update]_permission relations between EEType/ERType
-    and EGroup entities
+    [read|add|delete|update]_permission relations between CWEType/CWRType
+    and CWGroup entities
     """
-    etype = isinstance(erschema, schemamod.EntitySchema) and 'EEType' or 'ERType'
+    etype = isinstance(erschema, schemamod.EntitySchema) and 'CWEType' or 'CWRType'
     for action in erschema.ACTIONS:
         for group in sorted(erschema.get_groups(action)):
             try:
@@ -465,12 +519,12 @@
 def updateeschema2rql(eschema):
     relations, values = eschema_relations_values(eschema)
     values['et'] = eschema.type
-    yield 'SET %s WHERE X is EEType, X name %%(et)s' % ','.join(relations), values
+    yield 'SET %s WHERE X is CWEType, X name %%(et)s' % ','.join(relations), values
 
 def updaterschema2rql(rschema):
     relations, values = rschema_relations_values(rschema)
     values['rt'] = rschema.type
-    yield 'SET %s WHERE X is ERType, X name %%(rt)s' % ','.join(relations), values
+    yield 'SET %s WHERE X is CWRType, X name %%(rt)s' % ','.join(relations), values
             
 def updaterdef2rql(rschema, subjtype=None, objtype=None, props=None):
     genmap = {True: updatefrdef2rql, False: updatenfrdef2rql}
@@ -479,13 +533,13 @@
 def updatefrdef2rql(rschema, subjtype, objtype, props):
     relations, values = frdef_relations_values(rschema, objtype, props)
     values.update({'se': subjtype, 'rt': str(rschema), 'oe': objtype})
-    yield 'SET %s WHERE %s, %s, X is EFRDef' % (','.join(relations),
+    yield 'SET %s WHERE %s, %s, X is CWAttribute' % (','.join(relations),
                                                  _LOCATE_RDEF_RQL0,
                                                  _LOCATE_RDEF_RQL1), values
             
 def updatenfrdef2rql(rschema, subjtype, objtype, props):
     relations, values = nfrdef_relations_values(rschema, objtype, props)
     values.update({'se': subjtype, 'rt': str(rschema), 'oe': objtype})
-    yield 'SET %s WHERE %s, %s, X is ENFRDef' % (','.join(relations),
+    yield 'SET %s WHERE %s, %s, X is CWRelation' % (','.join(relations),
                                                  _LOCATE_RDEF_RQL0,
                                                  _LOCATE_RDEF_RQL1), values
--- a/server/serverctl.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/serverctl.py	Fri Apr 24 19:46:47 2009 +0200
@@ -89,7 +89,7 @@
         # set_isolation_level() is psycopg specific
         pass
     return cnx
-    
+
 def generate_sources_file(sourcesfile, sourcescfg, keys=None):
     """serialize repository'sources configuration into a INI like file
 
@@ -109,7 +109,7 @@
             # get a Configuration object
             _sconfig = Configuration(options=SOURCE_TYPES[sconfig['adapter']].options)
             for attr, val in sconfig.items():
-                if attr == 'uri': 
+                if attr == 'uri':
                     continue
                 if attr == 'adapter':
                     _sconfig.adapter = val
@@ -140,7 +140,7 @@
         except AuthenticationError:
             print 'wrong user/password'
         login, pwd = manager_userpasswd()
-    
+
 # repository specific command handlers ########################################
 
 class RepositoryCreateHandler(CommandHandler):
@@ -187,14 +187,14 @@
         restrict_perms_to_user(sourcesfile)
         # remember selected cubes for later initialization of the database
         config.write_bootstrap_cubes_file(cubes)
-        
+
     def postcreate(self):
         if confirm('do you want to create repository\'s system database?'):
             verbosity = (self.config.mode == 'installed') and 'y' or 'n'
             cmd_run('db-create', self.config.appid, '--verbose=%s' % verbosity)
         else:
             print 'nevermind, you can do it later using the db-create command'
-            
+
 USER_OPTIONS =  (
     ('login', {'type' : 'string',
                'default': REQUIRED,
@@ -236,7 +236,7 @@
                 cnx.rollback()
                 raise
 
-    
+
 class RepositoryStartHandler(CommandHandler):
     cmdname = 'start'
     cfgname = 'repository'
@@ -247,7 +247,7 @@
             command.append('--debug')
         command.append(self.config.appid)
         return ' '.join(command)
-        
+
 
 class RepositoryStopHandler(CommandHandler):
     cmdname = 'stop'
@@ -260,12 +260,12 @@
         if self.config.pyro_enabled():
             from cubicweb.server.repository import pyro_unregister
             pyro_unregister(self.config)
-    
+
 
 # repository specific commands ################################################
 class CreateApplicationDBCommand(Command):
     """Create the system database of an application (run after 'create').
-    
+
     You will be prompted for a login / password to use to connect to
     the system database.  The given user should have almost all rights
     on the database (ie a super user on the dbms allowed to create
@@ -276,7 +276,7 @@
     """
     name = 'db-create'
     arguments = '<application>'
-    
+
     options = (
         ("create-db",
          {'short': 'c', 'type': "yn", 'metavar': '<y or n>',
@@ -328,11 +328,11 @@
             except:
                 dbcnx.rollback()
                 raise
-        cnx = system_source_cnx(source, special_privs='LANGUAGE C', verbose=verbose) 
+        cnx = system_source_cnx(source, special_privs='LANGUAGE C', verbose=verbose)
         cursor = cnx.cursor()
         indexer = get_indexer(driver)
         indexer.init_extensions(cursor)
-        # postgres specific stuff        
+        # postgres specific stuff
         if driver == 'postgres':
             # install plpythonu/plpgsql language if not installed by the cube
             for extlang in ('plpythonu', 'plpgsql'):
@@ -346,10 +346,10 @@
         else:
             print 'nevermind, you can do it later using the db-init command'
 
-    
+
 class InitApplicationCommand(Command):
     """Initialize the system database of an application (run after 'db-create').
-    
+
     You will be prompted for a login / password to use to connect to
     the system database.  The given user should have the create tables,
     and grant permissions.
@@ -359,7 +359,7 @@
     """
     name = 'db-init'
     arguments = '<application>'
-    
+
     options = (
         ("drop",
          {'short': 'd', 'action': 'store_true',
@@ -377,7 +377,7 @@
 
 class GrantUserOnApplicationCommand(Command):
     """Grant a database user on a repository system database.
-    
+
     <application>
       the identifier of the application
     <user>
@@ -388,7 +388,7 @@
 
     options = (
         ("set-owner",
-         {'short': 'o', 'type' : "yn", 'metavar' : '<yes or no>', 
+         {'short': 'o', 'type' : "yn", 'metavar' : '<yes or no>',
           'default' : False,
           'help': 'Set the user as tables owner if yes (no by default).'}
          ),
@@ -417,10 +417,10 @@
             print 'grants given to %s on application %s' % (appid, user)
 
 
-    
+
 class StartRepositoryCommand(Command):
     """Start an CubicWeb RQL server for a given application.
-    
+
     The server will be accessible through pyro
 
     <application>
@@ -428,7 +428,7 @@
     """
     name = 'start-repository'
     arguments = '<application>'
-    
+
     options = (
         ("debug",
          {'short': 'D', 'action' : 'store_true',
@@ -534,7 +534,7 @@
             applversion = vcconf[cube]
         except KeyError:
             print "no cube version information for %s in version configuration" % cube
-            continue            
+            continue
         if softversion == applversion:
             continue
         if softversion > applversion:
@@ -542,11 +542,11 @@
         elif softversion < applversion:
             return 'needapplupgrade'
     return None
-    
+
 
 class DBDumpCommand(Command):
     """Backup the system database of an application.
-    
+
     <application>
       the identifier of the application to backup
       format [[user@]host:]appname
@@ -556,7 +556,7 @@
 
     options = (
         ("output",
-         {'short': 'o', 'type' : "string", 'metavar' : '<file>', 
+         {'short': 'o', 'type' : "string", 'metavar' : '<file>',
           'default' : None,
           'help': 'Specify the backup file where the backup will be stored.'}
          ),
@@ -578,7 +578,7 @@
 
 class DBRestoreCommand(Command):
     """Restore the system database of an application.
-    
+
     <application>
       the identifier of the application to restore
     """
@@ -587,7 +587,7 @@
 
     options = (
         ("no-drop",
-         {'short': 'n', 'action' : 'store_true', 
+         {'short': 'n', 'action' : 'store_true',
           'default' : False,
           'help': 'for some reason the database doesn\'t exist and so '
           'should not be dropped.'}
@@ -602,7 +602,7 @@
 
 class DBCopyCommand(Command):
     """Copy the system database of an application (backup and restore).
-    
+
     <src-application>
       the identifier of the application to backup
       format [[user@]host:]appname
@@ -615,7 +615,7 @@
 
     options = (
         ("no-drop",
-         {'short': 'n', 'action' : 'store_true', 
+         {'short': 'n', 'action' : 'store_true',
           'default' : False,
           'help': 'For some reason the database doesn\'t exist and so '
           'should not be dropped.'}
@@ -648,10 +648,10 @@
         else:
             os.remove(output)
 
-        
+
 class CheckRepositoryCommand(Command):
     """Check integrity of the system database of an application.
-    
+
     <application>
       the identifier of the application to check
     """
@@ -660,25 +660,25 @@
 
     options = (
         ("checks",
-         {'short': 'c', 'type' : "csv", 'metavar' : '<check list>', 
+         {'short': 'c', 'type' : "csv", 'metavar' : '<check list>',
           'default' : ('entities', 'relations', 'metadata', 'schema', 'text_index'),
           'help': 'Comma separated list of check to run. By default run all \
 checks, i.e. entities, relations, text_index and metadata.'}
          ),
-        
+
         ("autofix",
-         {'short': 'a', 'type' : "yn", 'metavar' : '<yes or no>', 
+         {'short': 'a', 'type' : "yn", 'metavar' : '<yes or no>',
           'default' : False,
           'help': 'Automatically correct integrity problems if this option \
 is set to "y" or "yes", else only display them'}
          ),
         ("reindex",
-         {'short': 'r', 'type' : "yn", 'metavar' : '<yes or no>', 
+         {'short': 'r', 'type' : "yn", 'metavar' : '<yes or no>',
           'default' : False,
           'help': 're-indexes the database for full text search if this \
 option is set to "y" or "yes" (may be long for large database).'}
          ),
-        
+
         )
 
     def run(self, args):
@@ -692,7 +692,7 @@
 
 class RebuildFTICommand(Command):
     """Rebuild the full-text index of the system database of an application.
-    
+
     <application>
       the identifier of the application to rebuild
     """
@@ -710,10 +710,10 @@
         reindex_entities(repo.schema, session)
         cnx.commit()
 
-    
+
 class SynchronizeApplicationSchemaCommand(Command):
     """Synchronize persistent schema with cube schema.
-        
+
     Will synchronize common stuff between the cube schema and the
     actual persistent schema, but will not add/remove any entity or relation.
 
@@ -730,7 +730,7 @@
         mih.cmd_synchronize_schema()
 
 
-register_commands( (CreateApplicationDBCommand,                   
+register_commands( (CreateApplicationDBCommand,
                     InitApplicationCommand,
                     GrantUserOnApplicationCommand,
                     StartRepositoryCommand,
--- a/server/sources/__init__.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/sources/__init__.py	Fri Apr 24 19:46:47 2009 +0200
@@ -229,8 +229,8 @@
         pass
     
     def authenticate(self, session, login, password):
-        """if the source support EUser entity type, it should implements
-        this method which should return EUser eid for the given login/password
+        """if the source support CWUser entity type, it should implements
+        this method which should return CWUser eid for the given login/password
         if this account is defined in this source and valid login / password is
         given. Else raise `AuthenticationError`
         """
--- a/server/sources/extlite.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/sources/extlite.py	Fri Apr 24 19:46:47 2009 +0200
@@ -22,7 +22,7 @@
         timeout -= 0.2
         if timeout <= 0:
             raise RuntimeError("svn source is busy, can't acquire connection lock")
-        
+
 class ConnectionWrapper(object):
     def __init__(self, source=None):
         self.source = source
@@ -34,19 +34,19 @@
             timeout_acquire(self.source._cnxlock, 5)
             self._cnx = self.source._sqlcnx
         return self._cnx
-    
+
     def commit(self):
         if self._cnx is not None:
             self._cnx.commit()
-        
+
     def rollback(self):
         if self._cnx is not None:
             self._cnx.rollback()
-        
+
     def cursor(self):
         return self.cnx.cursor()
 
-    
+
 class SQLiteAbstractSource(AbstractSource):
     """an abstract class for external sources using a sqlite database helper
     """
@@ -59,7 +59,7 @@
             native.NONSYSTEM_ETYPES.add(etype)
         for rtype in cls.support_relations:
             native.NONSYSTEM_RELATIONS.add(rtype)
-        
+
     options = (
         ('helper-db-path',
          {'type' : 'string',
@@ -69,10 +69,10 @@
           'inputlevel': 2,
           }),
     )
-            
+
     def __init__(self, repo, appschema, source_config, *args, **kwargs):
         # the helper db is used to easy querying and will store everything but
-        # actual file content 
+        # actual file content
         dbpath = source_config.get('helper-db-path')
         if dbpath is None:
             dbpath = join(repo.config.appdatahome,
@@ -91,7 +91,7 @@
         # * create the connection when needed
         # * use a lock to be sure only one connection is used
         self._cnxlock = threading.Lock()
-        
+
     @property
     def _sqlcnx(self):
         # XXX: sqlite connections can only be used in the same thread, so
@@ -138,13 +138,13 @@
                          self.repo.config['uid'])
             chown(self.dbpath, self.repo.config['uid'])
         restrict_perms_to_user(self.dbpath, self.info)
-        
+
     def set_schema(self, schema):
         super(SQLiteAbstractSource, self).set_schema(schema)
         if self._need_sql_create and self._is_schema_complete() and self.dbpath:
             self._create_database()
         self.rqlsqlgen = self.sqlgen_class(schema, self.sqladapter.dbhelper)
-                
+
     def get_connection(self):
         return ConnectionWrapper(self)
 
@@ -168,11 +168,11 @@
                 cnx._cnx = None
             finally:
                 self._cnxlock.release()
-        
+
     def syntax_tree_search(self, session, union,
                            args=None, cachekey=None, varmap=None, debug=0):
-        """return result from this source for a rql query (actually from a rql 
-        syntax tree and a solution dictionary mapping each used variable to a 
+        """return result from this source for a rql query (actually from a rql
+        syntax tree and a solution dictionary mapping each used variable to a
         possible type). If cachekey is given, the query necessary to fetch the
         results (but not the results themselves) may be cached using this key.
         """
@@ -185,7 +185,7 @@
         args = self.sqladapter.merge_args(args, query_args)
         cursor = session.pool[self.uri]
         cursor.execute(sql, args)
-        return self.sqladapter.process_result(cursor) 
+        return self.sqladapter.process_result(cursor)
 
     def local_add_entity(self, session, entity):
         """insert the entity in the local database.
@@ -198,7 +198,7 @@
         attrs = self.sqladapter.preprocess_entity(entity)
         sql = self.sqladapter.sqlgen.insert(SQL_PREFIX + str(entity.e_schema), attrs)
         cu.execute(sql, attrs)
-        
+
     def add_entity(self, session, entity):
         """add a new entity to the source"""
         raise NotImplementedError()
@@ -213,13 +213,14 @@
         cu = session.pool[self.uri]
         if attrs is None:
             attrs = self.sqladapter.preprocess_entity(entity)
-        sql = self.sqladapter.sqlgen.update(SQL_PREFIX + str(entity.e_schema), attrs, ['eid'])
+        sql = self.sqladapter.sqlgen.update(SQL_PREFIX + str(entity.e_schema),
+                                            attrs, [SQL_PREFIX + 'eid'])
         cu.execute(sql, attrs)
-        
+
     def update_entity(self, session, entity):
         """update an entity in the source"""
         raise NotImplementedError()
-        
+
     def delete_entity(self, session, etype, eid):
         """delete an entity from the source
 
@@ -227,11 +228,11 @@
         source. Main usage is to delete repository content when a Repository
         entity is deleted.
         """
-        sqlcursor = session.pool[self.uri]        
+        sqlcursor = session.pool[self.uri]
         attrs = {SQL_PREFIX + 'eid': eid}
         sql = self.sqladapter.sqlgen.delete(SQL_PREFIX + etype, attrs)
         sqlcursor.execute(sql, attrs)
-    
+
     def delete_relation(self, session, subject, rtype, object):
         """delete a relation from the source"""
         rschema = self.schema.rschema(rtype)
@@ -245,5 +246,5 @@
         else:
             attrs = {'eid_from': subject, 'eid_to': object}
             sql = self.sqladapter.sqlgen.delete('%s_relation' % rtype, attrs)
-        sqlcursor = session.pool[self.uri]        
+        sqlcursor = session.pool[self.uri]
         sqlcursor.execute(sql, attrs)
--- a/server/sources/ldapuser.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/sources/ldapuser.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,6 +1,6 @@
 """cubicweb ldap user source
 
-this source is for now limited to a read-only EUser source
+this source is for now limited to a read-only CWUser source
 
 :organization: Logilab
 :copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
@@ -51,8 +51,8 @@
 
 
 class LDAPUserSource(AbstractSource):
-    """LDAP read-only EUser source"""
-    support_entities = {'EUser': False} 
+    """LDAP read-only CWUser source"""
+    support_entities = {'CWUser': False} 
 
     port = None
     
@@ -200,7 +200,7 @@
         return ConnectionWrapper(self._conn)
     
     def authenticate(self, session, login, password):
-        """return EUser eid for the given login/password if this account is
+        """return CWUser eid for the given login/password if this account is
         defined in this source, else raise `AuthenticationError`
 
         two queries are needed since passwords are stored crypted, so we have
@@ -224,7 +224,7 @@
         except:
             # Something went wrong, most likely bad credentials
             raise AuthenticationError()
-        return self.extid2eid(user['dn'], 'EUser', session)
+        return self.extid2eid(user['dn'], 'CWUser', session)
 
     def ldap_name(self, var):
         if var.stinfo['relations']:
@@ -294,7 +294,7 @@
         mainvars = []
         for varname in rqlst.defined_vars:
             for sol in rqlst.solutions:
-                if sol[varname] == 'EUser':
+                if sol[varname] == 'CWUser':
                     mainvars.append(varname)
                     break
         assert mainvars
@@ -326,7 +326,7 @@
             filteredres = []
             for resdict in res:
                 # get sure the entity exists in the system table
-                eid = self.extid2eid(resdict['dn'], 'EUser', session)
+                eid = self.extid2eid(resdict['dn'], 'CWUser', session)
                 for eidfilter in eidfilters:
                     if not eidfilter(eid):
                         break
@@ -403,7 +403,7 @@
         except ldap.PARTIAL_RESULTS:
             res = cnx.result(all=0)[1]
         except ldap.NO_SUCH_OBJECT:
-            eid = self.extid2eid(base, 'EUser', session, insert=False)
+            eid = self.extid2eid(base, 'CWUser', session, insert=False)
             if eid:
                 self.warning('deleting ldap user with eid %s and dn %s',
                              eid, base)
--- a/server/sources/native.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/sources/native.py	Fri Apr 24 19:46:47 2009 +0200
@@ -85,9 +85,9 @@
     # need default value on class since migration doesn't call init method
     has_deleted_entitites_table = True
     
-    passwd_rql = "Any P WHERE X is EUser, X login %(login)s, X upassword P"
-    auth_rql = "Any X WHERE X is EUser, X login %(login)s, X upassword %(pwd)s"
-    _sols = ({'X': 'EUser', 'P': 'Password'},)
+    passwd_rql = "Any P WHERE X is CWUser, X login %(login)s, X upassword P"
+    auth_rql = "Any X WHERE X is CWUser, X login %(login)s, X upassword %(pwd)s"
+    _sols = ({'X': 'CWUser', 'P': 'Password'},)
     
     options = (
         ('db-driver',
@@ -199,7 +199,7 @@
             self._rql_sqlgen.schema = schema
         except AttributeError:
             pass # __init__
-        if 'EUser' in schema: # probably an empty schema if not true...
+        if 'CWUser' in schema: # probably an empty schema if not true...
             # rql syntax trees used to authenticate users
             self._passwd_rqlst = self.compile_rql(self.passwd_rql)
             self._auth_rqlst = self.compile_rql(self.auth_rql)
@@ -221,7 +221,7 @@
         return True #not rtype == 'content_for'
 
     def authenticate(self, session, login, password):
-        """return EUser eid for the given login/password if this account is
+        """return CWUser eid for the given login/password if this account is
         defined in this source, else raise `AuthenticationError`
 
         two queries are needed since passwords are stored crypted, so we have
--- a/server/sources/pyrorql.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/sources/pyrorql.py	Fri Apr 24 19:46:47 2009 +0200
@@ -134,13 +134,13 @@
 
     def last_update_time(self):
         pkey = u'sources.%s.latest-update-time' % self.uri
-        rql = 'Any V WHERE X is EProperty, X value V, X pkey %(k)s'
+        rql = 'Any V WHERE X is CWProperty, X value V, X pkey %(k)s'
         session = self.repo.internal_session()
         try:
             rset = session.execute(rql, {'k': pkey})
             if not rset:
                 # insert it
-                session.execute('INSERT EProperty X: X pkey %(k)s, X value %(v)s',
+                session.execute('INSERT CWProperty X: X pkey %(k)s, X value %(v)s',
                                 {'k': pkey, 'v': u'0'})
                 session.commit()
                 timestamp = 0
--- a/server/sources/rql2sql.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/sources/rql2sql.py	Fri Apr 24 19:46:47 2009 +0200
@@ -3,14 +3,14 @@
 
 SQL queries optimization
 ~~~~~~~~~~~~~~~~~~~~~~~~
-1. EUser X WHERE X in_group G, G name 'users':
+1. CWUser X WHERE X in_group G, G name 'users':
 
-   EUser is the only subject entity type for the in_group relation,
+   CWUser is the only subject entity type for the in_group relation,
    which allow us to do ::
 
-     SELECT eid_from FROM in_group, EGroup
-     WHERE in_group.eid_to = EGroup.eid_from
-     AND EGroup.name = 'users'
+     SELECT eid_from FROM in_group, CWGroup
+     WHERE in_group.eid_to = CWGroup.eid_from
+     AND CWGroup.name = 'users'
 
 
 2. Any X WHERE X nonfinal1 Y, Y nonfinal2 Z
@@ -935,9 +935,9 @@
     def visit_function(self, func, contextrels=None):
         """generate SQL name for a function"""
         # function_description will check function is supported by the backend
-        self.dbms_helper.function_description(func.name) 
-        return '%s(%s)' % (func.name, ', '.join(c.accept(self, contextrels)
-                                                for c in func.children))
+        sqlname = self.dbms_helper.func_sqlname(func.name) 
+        return '%s(%s)' % (sqlname, ', '.join(c.accept(self, contextrels)
+                                              for c in func.children))
 
     def visit_constant(self, constant, contextrels=None):
         """generate SQL name for a constant"""
--- a/server/sqlutils.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/sqlutils.py	Fri Apr 24 19:46:47 2009 +0200
@@ -218,6 +218,16 @@
                         value = crypt_password(value)
                 elif isinstance(value, Binary):
                     value = self.binary(value.getvalue())
+                # XXX <3.2 bw compat
+                elif type(value) is DateTimeType:
+                    warn('found mx date time instance, please update to use datetime',
+                         DeprecationWarning)
+                    value = datetime(value.year, value.month, value.day,
+                                   value.hour, value.minute, int(value.second))
+                elif type(value) is DateTimeDeltaType:
+                    warn('found mx date time instance, please update to use datetime',
+                         DeprecationWarning)
+                    value = timedelta(0, int(value.seconds), 0)
             attrs[SQL_PREFIX+str(attr)] = value
         return attrs
 
--- a/server/test/data/migrschema/relations.rel	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/data/migrschema/relations.rel	Fri Apr 24 19:46:47 2009 +0200
@@ -1,6 +1,6 @@
 Personne travaille Societe
 Personne evaluee Note
-EUser evaluee Note
+CWUser evaluee Note
 Societe evaluee Note
 Personne concerne Affaire
 Affaire concerne Societe
--- a/server/test/data/schema/Affaire.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/data/schema/Affaire.py	Fri Apr 24 19:46:47 2009 +0200
@@ -22,7 +22,7 @@
     invoiced = Int()
 
     depends_on = SubjectRelation('Affaire')
-    require_permission = SubjectRelation('EPermission')
+    require_permission = SubjectRelation('CWPermission')
     
 class concerne(RelationType):
     permissions = {
--- a/server/test/data/schema/custom.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/data/schema/custom.py	Fri Apr 24 19:46:47 2009 +0200
@@ -30,5 +30,5 @@
     subject = ('Bookmark', 'Note')
     object = ('Bookmark', 'Note')
 
-_euser = import_schema('base').EUser
+_euser = import_schema('base').CWUser
 _euser.__relations__[0].fulltextindexed = True
--- a/server/test/data/schema/relations.rel	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/data/schema/relations.rel	Fri Apr 24 19:46:47 2009 +0200
@@ -1,13 +1,13 @@
 Personne travaille Societe
 Personne evaluee Note
-EUser evaluee Note
+CWUser evaluee Note
 Societe evaluee Note
 Personne concerne Affaire
 Affaire concerne Societe
 Affaire concerne Note
 
 Note ecrit_par Personne inline CONSTRAINT E concerns P, X version_of P
-Note ecrit_par EUser inline CONSTRAINT
+Note ecrit_par CWUser inline CONSTRAINT
 Personne connait Personne symetric
 
 # not inlined intentionaly
@@ -16,7 +16,7 @@
 Note inline1 Affaire inline
 Personne inline2 Affaire inline
 
-Note todo_by EUser
+Note todo_by CWUser
 Affaire todo_by Personne
 
 Folder see_also Folder
@@ -24,10 +24,10 @@
 
 Affaire documented_by Card
 
-EUser copain EUser
+CWUser copain CWUser
 
-Tag tags EUser
-Tag tags EGroup
+Tag tags CWUser
+Tag tags CWGroup
 Tag tags State
 Tag tags Note
 Tag tags Card
@@ -36,11 +36,11 @@
 Note filed_under Folder
 Affaire filed_under Folder
 
-Card require_permission EPermission
-Note require_permission EPermission
-Personne require_permission EPermission
+Card require_permission CWPermission
+Note require_permission CWPermission
+Personne require_permission CWPermission
 
-EPermission require_state State
+CWPermission require_state State
 
 Note migrated_from Note
 
--- a/server/test/unittest_hookhelper.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_hookhelper.py	Fri Apr 24 19:46:47 2009 +0200
@@ -59,7 +59,7 @@
             SendMailOp(session, msg=content, recipients=['test@logilab.fr'])
         self.hm.register_hook(in_state_changed,
                              'before_add_relation', 'in_state')
-        self.execute('INSERT EUser X: X login "paf", X upassword "wouf", X in_state S, X in_group G WHERE S name "activated", G name "users"')
+        self.execute('INSERT CWUser X: X login "paf", X upassword "wouf", X in_state S, X in_group G WHERE S name "activated", G name "users"')
         self.assertEquals(result, [None])
         searchedops = [op for op in self.session.pending_operations
                        if isinstance(op, SendMailOp)]
--- a/server/test/unittest_hooks.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_hooks.py	Fri Apr 24 19:46:47 2009 +0200
@@ -25,14 +25,14 @@
         
     def test_delete_internal_entities(self):
         self.assertRaises(RepositoryError, self.execute,
-                          'DELETE EEType X WHERE X name "EEType"')
+                          'DELETE CWEType X WHERE X name "CWEType"')
         self.assertRaises(RepositoryError, self.execute,
-                          'DELETE ERType X WHERE X name "relation_type"')
+                          'DELETE CWRType X WHERE X name "relation_type"')
         self.assertRaises(RepositoryError, self.execute,
-                          'DELETE EGroup X WHERE X name "owners"')
+                          'DELETE CWGroup X WHERE X name "owners"')
 
     def test_delete_required_relations_subject(self):
-        self.execute('INSERT EUser X: X login "toto", X upassword "hop", X in_group Y, X in_state S '
+        self.execute('INSERT CWUser X: X login "toto", X upassword "hop", X in_group Y, X in_state S '
                      'WHERE Y name "users", S name "activated"')
         self.commit()
         self.execute('DELETE X in_group Y WHERE X login "toto", Y name "users"')
@@ -47,17 +47,17 @@
     def test_static_vocabulary_check(self):
         self.assertRaises(ValidationError,
                           self.execute,
-                          'SET X composite "whatever" WHERE X from_entity FE, FE name "EUser", X relation_type RT, RT name "in_group"')
+                          'SET X composite "whatever" WHERE X from_entity FE, FE name "CWUser", X relation_type RT, RT name "in_group"')
     
     def test_missing_required_relations_subject_inline(self):
         # missing in_group relation 
-        self.execute('INSERT EUser X: X login "toto", X upassword "hop"')
+        self.execute('INSERT CWUser X: X login "toto", X upassword "hop"')
         self.assertRaises(ValidationError,
                           self.commit)
 
     def test_delete_if_singlecard1(self):
         self.assertEquals(self.repo.schema['in_state'].inlined, False)
-        ueid, = self.execute('INSERT EUser X: X login "toto", X upassword "hop", X in_group Y, X in_state S '
+        ueid, = self.execute('INSERT CWUser X: X login "toto", X upassword "hop", X in_group Y, X in_state S '
                              'WHERE Y name "users", S name "activated"')[0]
         self.commit()
         self.execute('SET X in_state S WHERE S name "deactivated", X eid %(x)s', {'x': ueid})
@@ -119,7 +119,7 @@
         self.assertEquals(rset.get_entity(0, 0).reverse_parts[0].messageid, '<2345>')
 
     def test_unsatisfied_constraints(self):
-        self.execute('INSERT ENFRDef X: X from_entity FE, X relation_type RT, X to_entity TE '
+        self.execute('INSERT CWRelation X: X from_entity FE, X relation_type RT, X to_entity TE '
                      'WHERE FE name "Affaire", RT name "concerne", TE name "String"')
         self.assertRaises(ValidationError,
                           self.commit)
@@ -160,7 +160,7 @@
         self.commit()
         cnxid = self.repo.connect(u'toto', 'hop')
         self.failIfEqual(cnxid, self.cnxid)
-        self.execute('DELETE EUser X WHERE X login "toto"')
+        self.execute('DELETE CWUser X WHERE X login "toto"')
         self.repo.execute(cnxid, 'State X')
         self.commit()
         self.assertRaises(BadConnectionId,
@@ -194,47 +194,47 @@
         self.commit()
         self.failIf(self.execute('Any X WHERE X created_by Y, X eid >= %(x)s', {'x': eid}))
         
-class EPropertyHooksTC(RepositoryBasedTC):
+class CWPropertyHooksTC(RepositoryBasedTC):
     
     def test_unexistant_eproperty(self):
         ex = self.assertRaises(ValidationError,
-                          self.execute, 'INSERT EProperty X: X pkey "bla.bla", X value "hop", X for_user U')
+                          self.execute, 'INSERT CWProperty X: X pkey "bla.bla", X value "hop", X for_user U')
         self.assertEquals(ex.errors, {'pkey': 'unknown property key'})
         ex = self.assertRaises(ValidationError,
-                          self.execute, 'INSERT EProperty X: X pkey "bla.bla", X value "hop"')
+                          self.execute, 'INSERT CWProperty X: X pkey "bla.bla", X value "hop"')
         self.assertEquals(ex.errors, {'pkey': 'unknown property key'})
         
     def test_site_wide_eproperty(self):
         ex = self.assertRaises(ValidationError,
-                               self.execute, 'INSERT EProperty X: X pkey "ui.site-title", X value "hop", X for_user U')
+                               self.execute, 'INSERT CWProperty X: X pkey "ui.site-title", X value "hop", X for_user U')
         self.assertEquals(ex.errors, {'for_user': "site-wide property can't be set for user"})
         
     def test_bad_type_eproperty(self):
         ex = self.assertRaises(ValidationError,
-                               self.execute, 'INSERT EProperty X: X pkey "ui.language", X value "hop", X for_user U')
+                               self.execute, 'INSERT CWProperty X: X pkey "ui.language", X value "hop", X for_user U')
         self.assertEquals(ex.errors, {'value': u'unauthorized value'})
         ex = self.assertRaises(ValidationError,
-                          self.execute, 'INSERT EProperty X: X pkey "ui.language", X value "hop"')
+                          self.execute, 'INSERT CWProperty X: X pkey "ui.language", X value "hop"')
         self.assertEquals(ex.errors, {'value': u'unauthorized value'})
         
         
 class SchemaHooksTC(RepositoryBasedTC):
         
     def test_duplicate_etype_error(self):
-        # check we can't add a EEType or ERType entity if it already exists one
+        # check we can't add a CWEType or CWRType entity if it already exists one
         # with the same name
         #
         # according to hook order, we'll get a repository or validation error
         self.assertRaises((ValidationError, RepositoryError),
-                          self.execute, 'INSERT EEType X: X name "Societe"')
+                          self.execute, 'INSERT CWEType X: X name "Societe"')
         self.assertRaises((ValidationError, RepositoryError),
-                          self.execute, 'INSERT ERType X: X name "in_group"')
+                          self.execute, 'INSERT CWRType X: X name "in_group"')
         
     def test_validation_unique_constraint(self):
         self.assertRaises(ValidationError,
-                          self.execute, 'INSERT EUser X: X login "admin"')
+                          self.execute, 'INSERT CWUser X: X login "admin"')
         try:
-            self.execute('INSERT EUser X: X login "admin"')
+            self.execute('INSERT CWUser X: X login "admin"')
         except ValidationError, ex:
             self.assertIsInstance(ex.entity, int)
             self.assertEquals(ex.errors, {'login': 'the value "admin" is already used, use another one'})
@@ -264,26 +264,26 @@
         self.failIf(schema.has_entity('Societe2'))
         self.failIf(schema.has_entity('concerne2'))
         # schema should be update on insertion (after commit)
-        self.execute('INSERT EEType X: X name "Societe2", X description "", X meta FALSE, X final FALSE')
-        self.execute('INSERT ERType X: X name "concerne2", X description "", X meta FALSE, X final FALSE, X symetric FALSE')
+        self.execute('INSERT CWEType X: X name "Societe2", X description "", X meta FALSE, X final FALSE')
+        self.execute('INSERT CWRType X: X name "concerne2", X description "", X meta FALSE, X final FALSE, X symetric FALSE')
         self.failIf(schema.has_entity('Societe2'))
         self.failIf(schema.has_entity('concerne2'))
-        self.execute('SET X read_permission G WHERE X is EEType, X name "Societe2", G is EGroup')
-        self.execute('SET X read_permission G WHERE X is ERType, X name "concerne2", G is EGroup')
-        self.execute('SET X add_permission G WHERE X is EEType, X name "Societe2", G is EGroup, G name "managers"')
-        self.execute('SET X add_permission G WHERE X is ERType, X name "concerne2", G is EGroup, G name "managers"')
-        self.execute('SET X delete_permission G WHERE X is EEType, X name "Societe2", G is EGroup, G name "owners"')
-        self.execute('SET X delete_permission G WHERE X is ERType, X name "concerne2", G is EGroup, G name "owners"')
+        self.execute('SET X read_permission G WHERE X is CWEType, X name "Societe2", G is CWGroup')
+        self.execute('SET X read_permission G WHERE X is CWRType, X name "concerne2", G is CWGroup')
+        self.execute('SET X add_permission G WHERE X is CWEType, X name "Societe2", G is CWGroup, G name "managers"')
+        self.execute('SET X add_permission G WHERE X is CWRType, X name "concerne2", G is CWGroup, G name "managers"')
+        self.execute('SET X delete_permission G WHERE X is CWEType, X name "Societe2", G is CWGroup, G name "owners"')
+        self.execute('SET X delete_permission G WHERE X is CWRType, X name "concerne2", G is CWGroup, G name "owners"')
         # have to commit before adding definition relations
         self.commit()
         self.failUnless(schema.has_entity('Societe2'))
         self.failUnless(schema.has_relation('concerne2'))
-        self.execute('INSERT EFRDef X: X cardinality "11", X defaultval "noname", X indexed TRUE, X relation_type RT, X from_entity E, X to_entity F '
+        self.execute('INSERT CWAttribute X: X cardinality "11", X defaultval "noname", X indexed TRUE, X relation_type RT, X from_entity E, X to_entity F '
                      'WHERE RT name "nom", E name "Societe2", F name "String"')
         concerne2_rdef_eid = self.execute(
-            'INSERT ENFRDef X: X cardinality "**", X relation_type RT, X from_entity E, X to_entity E '
+            'INSERT CWRelation X: X cardinality "**", X relation_type RT, X from_entity E, X to_entity E '
             'WHERE RT name "concerne2", E name "Societe2"')[0][0]
-        self.execute('INSERT ENFRDef X: X cardinality "?*", X relation_type RT, X from_entity E, X to_entity C '
+        self.execute('INSERT CWRelation X: X cardinality "?*", X relation_type RT, X from_entity E, X to_entity C '
                      'WHERE RT name "comments", E name "Societe2", C name "Comment"')
         self.failIf('nom' in schema['Societe2'].subject_relations())
         self.failIf('concerne2' in schema['Societe2'].subject_relations())
@@ -299,17 +299,17 @@
         rset = self.execute('Any X WHERE X concerne2 Y')
         self.assertEquals(rset.rows, [[s2eid]])
         # check that when a relation definition is deleted, existing relations are deleted
-        self.execute('INSERT ENFRDef X: X cardinality "**", X relation_type RT, X from_entity E, X to_entity E '
+        self.execute('INSERT CWRelation X: X cardinality "**", X relation_type RT, X from_entity E, X to_entity E '
                      'WHERE RT name "concerne2", E name "Societe"')
         self.commit()
-        self.execute('DELETE ENFRDef X WHERE X eid %(x)s', {'x': concerne2_rdef_eid}, 'x')
+        self.execute('DELETE CWRelation X WHERE X eid %(x)s', {'x': concerne2_rdef_eid}, 'x')
         self.commit()
         self.failUnless('concerne2' in schema['Societe'].subject_relations())
         self.failIf('concerne2' in schema['Societe2'].subject_relations())
         self.failIf(self.execute('Any X WHERE X concerne2 Y'))
         # schema should be cleaned on delete (after commit)
-        self.execute('DELETE EEType X WHERE X name "Societe2"')
-        self.execute('DELETE ERType X WHERE X name "concerne2"')
+        self.execute('DELETE CWEType X WHERE X name "Societe2"')
+        self.execute('DELETE CWRType X WHERE X name "concerne2"')
         self.failUnless(self.index_exists('Societe2', 'nom'))
         self.failUnless(schema.has_entity('Societe2'))
         self.failUnless(schema.has_relation('concerne2'))
@@ -336,42 +336,42 @@
         
     def test_perms_synchronization_1(self):
         schema = self.repo.schema
-        self.assertEquals(schema['EUser'].get_groups('read'), set(('managers', 'users')))
-        self.failUnless(self.execute('Any X, Y WHERE X is EEType, X name "EUser", Y is EGroup, Y name "users"')[0])
-        self.execute('DELETE X read_permission Y WHERE X is EEType, X name "EUser", Y name "users"')
-        self.assertEquals(schema['EUser'].get_groups('read'), set(('managers', 'users', )))
+        self.assertEquals(schema['CWUser'].get_groups('read'), set(('managers', 'users')))
+        self.failUnless(self.execute('Any X, Y WHERE X is CWEType, X name "CWUser", Y is CWGroup, Y name "users"')[0])
+        self.execute('DELETE X read_permission Y WHERE X is CWEType, X name "CWUser", Y name "users"')
+        self.assertEquals(schema['CWUser'].get_groups('read'), set(('managers', 'users', )))
         self.commit()
-        self.assertEquals(schema['EUser'].get_groups('read'), set(('managers', )))
-        self.execute('SET X read_permission Y WHERE X is EEType, X name "EUser", Y name "users"')
+        self.assertEquals(schema['CWUser'].get_groups('read'), set(('managers', )))
+        self.execute('SET X read_permission Y WHERE X is CWEType, X name "CWUser", Y name "users"')
         self.commit()
-        self.assertEquals(schema['EUser'].get_groups('read'), set(('managers', 'users',)))
+        self.assertEquals(schema['CWUser'].get_groups('read'), set(('managers', 'users',)))
 
     def test_perms_synchronization_2(self):
         schema = self.repo.schema['in_group']
         self.assertEquals(schema.get_groups('read'), set(('managers', 'users', 'guests')))
-        self.execute('DELETE X read_permission Y WHERE X is ERType, X name "in_group", Y name "guests"')
+        self.execute('DELETE X read_permission Y WHERE X is CWRType, X name "in_group", Y name "guests"')
         self.assertEquals(schema.get_groups('read'), set(('managers', 'users', 'guests')))
         self.commit()
         self.assertEquals(schema.get_groups('read'), set(('managers', 'users')))
-        self.execute('SET X read_permission Y WHERE X is ERType, X name "in_group", Y name "guests"')
+        self.execute('SET X read_permission Y WHERE X is CWRType, X name "in_group", Y name "guests"')
         self.assertEquals(schema.get_groups('read'), set(('managers', 'users')))
         self.commit()
         self.assertEquals(schema.get_groups('read'), set(('managers', 'users', 'guests')))
 
     def test_nonregr_user_edit_itself(self):
         ueid = self.session.user.eid
-        groupeids = [eid for eid, in self.execute('EGroup G WHERE G name in ("managers", "users")')]
+        groupeids = [eid for eid, in self.execute('CWGroup G WHERE G name in ("managers", "users")')]
         self.execute('DELETE X in_group Y WHERE X eid %s' % ueid)
         self.execute('SET X surname "toto" WHERE X eid %s' % ueid)
         self.execute('SET X in_group Y WHERE X eid %s, Y name "managers"' % ueid)
         self.commit()
-        eeid = self.execute('Any X WHERE X is EEType, X name "EEType"')[0][0]
+        eeid = self.execute('Any X WHERE X is CWEType, X name "CWEType"')[0][0]
         self.execute('DELETE X read_permission Y WHERE X eid %s' % eeid)
         self.execute('SET X final FALSE WHERE X eid %s' % eeid)
         self.execute('SET X read_permission Y WHERE X eid %s, Y eid in (%s, %s)'
                      % (eeid, groupeids[0], groupeids[1]))
         self.commit()
-        self.execute('Any X WHERE X is EEType, X name "EEType"')
+        self.execute('Any X WHERE X is CWEType, X name "CWEType"')
 
     # schema modification hooks tests #########################################
     
@@ -432,7 +432,7 @@
         sqlcursor = self.session.pool['system']
         try:
             try:
-                self.execute('INSERT EConstraint X: X cstrtype CT, DEF constrained_by X '
+                self.execute('INSERT CWConstraint X: X cstrtype CT, DEF constrained_by X '
                              'WHERE CT name "UniqueConstraint", DEF relation_type RT, DEF from_entity E,'
                              'RT name "sujet", E name "Affaire"')
                 self.failIf(self.schema['Affaire'].has_unique_values('sujet'))
@@ -461,21 +461,21 @@
         RepositoryBasedTC.setUp(self)
         self.s_activated = self.execute('State X WHERE X name "activated"')[0][0]
         self.s_deactivated = self.execute('State X WHERE X name "deactivated"')[0][0]
-        self.s_dummy = self.execute('INSERT State X: X name "dummy", X state_of E WHERE E name "EUser"')[0][0]
+        self.s_dummy = self.execute('INSERT State X: X name "dummy", X state_of E WHERE E name "CWUser"')[0][0]
         self.create_user('stduser')
         # give access to users group on the user's wf transitions
         # so we can test wf enforcing on euser (managers don't have anymore this
         # enforcement
-        self.execute('SET X require_group G WHERE G name "users", X transition_of ET, ET name "EUser"')
+        self.execute('SET X require_group G WHERE G name "users", X transition_of ET, ET name "CWUser"')
         self.commit()
         
     def tearDown(self):
-        self.execute('DELETE X require_group G WHERE G name "users", X transition_of ET, ET name "EUser"')
+        self.execute('DELETE X require_group G WHERE G name "users", X transition_of ET, ET name "CWUser"')
         self.commit()
         RepositoryBasedTC.tearDown(self)
 
     def test_set_initial_state(self):
-        ueid = self.execute('INSERT EUser E: E login "x", E upassword "x", E in_group G '
+        ueid = self.execute('INSERT CWUser E: E login "x", E upassword "x", E in_group G '
                             'WHERE G name "users"')[0][0]
         self.failIf(self.execute('Any N WHERE S name N, X in_state S, X eid %(x)s',
                                  {'x' : ueid}))
@@ -488,11 +488,11 @@
         cnx = self.login('stduser')
         cu = cnx.cursor()
         self.assertRaises(ValidationError, cu.execute,
-                          'INSERT EUser X: X login "badaboum", X upassword %(pwd)s, '
+                          'INSERT CWUser X: X login "badaboum", X upassword %(pwd)s, '
                           'X in_state S WHERE S name "deactivated"', {'pwd': 'oops'})
         cnx.close()
         # though managers can do whatever he want
-        self.execute('INSERT EUser X: X login "badaboum", X upassword %(pwd)s, '
+        self.execute('INSERT CWUser X: X login "badaboum", X upassword %(pwd)s, '
                      'X in_state S, X in_group G WHERE S name "deactivated", G name "users"', {'pwd': 'oops'})
         self.commit()
         
--- a/server/test/unittest_hooksmanager.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_hooksmanager.py	Fri Apr 24 19:46:47 2009 +0200
@@ -25,13 +25,13 @@
         self.assertRaises(AssertionError,
                           self.o.register_hook, self._hook, 'before_add_entiti')
         self.assertRaises(AssertionError,
-                          self.o.register_hook, self._hook, 'session_login', 'EEType')
+                          self.o.register_hook, self._hook, 'session_login', 'CWEType')
         self.assertRaises(AssertionError,
-                          self.o.register_hook, self._hook, 'session_logout', 'EEType')
+                          self.o.register_hook, self._hook, 'session_logout', 'CWEType')
         self.assertRaises(AssertionError,
-                          self.o.register_hook, self._hook, 'server_startup', 'EEType')
+                          self.o.register_hook, self._hook, 'server_startup', 'CWEType')
         self.assertRaises(AssertionError,
-                          self.o.register_hook, self._hook, 'server_shutdown', 'EEType')
+                          self.o.register_hook, self._hook, 'server_shutdown', 'CWEType')
         
     def test_register_hook1(self):
         self.o.register_hook(self._hook, 'before_add_entity')
--- a/server/test/unittest_ldapuser.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_ldapuser.py	Fri Apr 24 19:46:47 2009 +0200
@@ -24,7 +24,7 @@
         # no such user
         raise AuthenticationError()
     # don't check upassword !
-    return self.extid2eid(user['dn'], 'EUser', session)
+    return self.extid2eid(user['dn'], 'CWUser', session)
 
 
 
@@ -45,7 +45,7 @@
         # sqlite since it doesn't support multiple connections on the same
         # database
         # so doing, ldap inserted users don't get removed between each test
-        rset = self.execute('EUser X')
+        rset = self.execute('CWUser X')
         self.commit()
         # check we get some users from ldap
         self.assert_(len(rset) > 1)
@@ -67,7 +67,7 @@
         
     def test_base(self):
         # check a known one
-        e = self.execute('EUser X WHERE X login "syt"').get_entity(0, 0)
+        e = self.execute('CWUser X WHERE X login "syt"').get_entity(0, 0)
         self.assertEquals(e.login, 'syt')
         e.complete()
         self.assertEquals(e.creation_date, None)
@@ -79,49 +79,49 @@
         self.assertEquals(e.created_by, [])
         self.assertEquals(e.primary_email[0].address, 'Sylvain Thenault')
         # email content should be indexed on the user
-        rset = self.execute('EUser X WHERE X has_text "thenault"')
+        rset = self.execute('CWUser X WHERE X has_text "thenault"')
         self.assertEquals(rset.rows, [[e.eid]])
 
     def test_not(self):
-        eid = self.execute('EUser X WHERE X login "syt"')[0][0]
-        rset = self.execute('EUser X WHERE NOT X eid %s' % eid)
+        eid = self.execute('CWUser X WHERE X login "syt"')[0][0]
+        rset = self.execute('CWUser X WHERE NOT X eid %s' % eid)
         self.assert_(rset)
         self.assert_(not eid in (r[0] for r in rset))
 
     def test_multiple(self):
-        seid = self.execute('EUser X WHERE X login "syt"')[0][0]
-        aeid = self.execute('EUser X WHERE X login "adim"')[0][0]
-        rset = self.execute('EUser X, Y WHERE X login "syt", Y login "adim"')
+        seid = self.execute('CWUser X WHERE X login "syt"')[0][0]
+        aeid = self.execute('CWUser X WHERE X login "adim"')[0][0]
+        rset = self.execute('CWUser X, Y WHERE X login "syt", Y login "adim"')
         self.assertEquals(rset.rows, [[seid, aeid]])
         rset = self.execute('Any X,Y,L WHERE X login L, X login "syt", Y login "adim"')
         self.assertEquals(rset.rows, [[seid, aeid, 'syt']])
 
     def test_in(self):
-        seid = self.execute('EUser X WHERE X login "syt"')[0][0]
-        aeid = self.execute('EUser X WHERE X login "adim"')[0][0]
+        seid = self.execute('CWUser X WHERE X login "syt"')[0][0]
+        aeid = self.execute('CWUser X WHERE X login "adim"')[0][0]
         rset = self.execute('Any X,L ORDERBY L WHERE X login IN("syt", "adim"), X login L')
         self.assertEquals(rset.rows, [[aeid, 'adim'], [seid, 'syt']])
 
     def test_relations(self):
-        eid = self.execute('EUser X WHERE X login "syt"')[0][0]
-        rset = self.execute('Any X,E WHERE X is EUser, X login L, X primary_email E')
+        eid = self.execute('CWUser X WHERE X login "syt"')[0][0]
+        rset = self.execute('Any X,E WHERE X is CWUser, X login L, X primary_email E')
         self.assert_(eid in (r[0] for r in rset))
-        rset = self.execute('Any X,L,E WHERE X is EUser, X login L, X primary_email E')
+        rset = self.execute('Any X,L,E WHERE X is CWUser, X login L, X primary_email E')
         self.assert_('syt' in (r[1] for r in rset))
 
     def test_count(self):
-        nbusers = self.execute('Any COUNT(X) WHERE X is EUser')[0][0]
+        nbusers = self.execute('Any COUNT(X) WHERE X is CWUser')[0][0]
         # just check this is a possible number
         self.assert_(nbusers > 1, nbusers)
         self.assert_(nbusers < 30, nbusers)
 
     def test_upper(self):
-        eid = self.execute('EUser X WHERE X login "syt"')[0][0]
+        eid = self.execute('CWUser X WHERE X login "syt"')[0][0]
         rset = self.execute('Any UPPER(L) WHERE X eid %s, X login L' % eid)
         self.assertEquals(rset[0][0], 'SYT')
 
     def test_unknown_attr(self):
-        eid = self.execute('EUser X WHERE X login "syt"')[0][0]
+        eid = self.execute('CWUser X WHERE X login "syt"')[0][0]
         rset = self.execute('Any L,C,M WHERE X eid %s, X login L, '
                             'X creation_date C, X modification_date M' % eid)
         self.assertEquals(rset[0][0], 'syt')
@@ -145,7 +145,7 @@
         # the related TrInfo has correct owner information
         self.execute('SET X in_group G WHERE X login "syt", G name "managers"')
         self.commit()
-        syt = self.execute('EUser X WHERE X login "syt"').get_entity(0, 0)
+        syt = self.execute('CWUser X WHERE X login "syt"').get_entity(0, 0)
         self.assertEquals([g.name for g in syt.in_group], ['managers', 'users'])
         self.patch_authenticate()
         cnx = self.login('syt', 'dummypassword')
@@ -153,7 +153,7 @@
         cu.execute('SET X in_state S WHERE X login "alf", S name "deactivated"')
         try:
             cnx.commit()
-            alf = self.execute('EUser X WHERE X login "alf"').get_entity(0, 0)
+            alf = self.execute('CWUser X WHERE X login "alf"').get_entity(0, 0)
             self.assertEquals(alf.in_state[0].name, 'deactivated')
             trinfo = alf.latest_trinfo()
             self.assertEquals(trinfo.owned_by[0].login, 'syt')
@@ -177,8 +177,8 @@
         self.failUnless(self.execute('Any X,Y WHERE X login "syt", Y login "cochon"'))
         
     def test_exists1(self):
-        self.add_entity('EGroup', name=u'bougloup1')
-        self.add_entity('EGroup', name=u'bougloup2')
+        self.add_entity('CWGroup', name=u'bougloup1')
+        self.add_entity('CWGroup', name=u'bougloup2')
         self.execute('SET U in_group G WHERE G name ~= "bougloup%", U login "admin"')
         self.execute('SET U in_group G WHERE G name = "bougloup1", U login "syt"')
         rset = self.execute('Any L,SN ORDERBY L WHERE X in_state S, S name SN, X login L, EXISTS(X in_group G, G name ~= "bougloup%")')
@@ -210,9 +210,9 @@
         self.execute('SET X copain Y WHERE X login "comme", Y login "billy"')
         self.execute('SET X copain Y WHERE X login "syt", Y login "billy"')
         # search for group name, login where
-        #   EUser copain with "comme" or "cochon" AND same login as the copain
+        #   CWUser copain with "comme" or "cochon" AND same login as the copain
         # OR
-        #   EUser in_state activated AND not copain with billy
+        #   CWUser in_state activated AND not copain with billy
         #
         # SO we expect everybody but "comme" and "syt"
         rset= self.execute('Any GN,L WHERE X in_group G, X login L, G name GN, '
@@ -243,13 +243,13 @@
                                               ['users', 'syt']])
         
     def test_cd_restriction(self):
-        rset = self.execute('EUser X WHERE X creation_date > "2009-02-01"')
+        rset = self.execute('CWUser X WHERE X creation_date > "2009-02-01"')
         self.assertEquals(len(rset), 2) # admin/anon but no ldap user since it doesn't support creation_date
         
     def test_union(self):
         afeids = self.execute('State X')
-        ueids = self.execute('EUser X')
-        rset = self.execute('(Any X WHERE X is State) UNION (Any X WHERE X is EUser)')
+        ueids = self.execute('CWUser X')
+        rset = self.execute('(Any X WHERE X is State) UNION (Any X WHERE X is CWUser)')
         self.assertEquals(sorted(r[0] for r in rset.rows),
                           sorted(r[0] for r in afeids + ueids))
 
@@ -301,7 +301,7 @@
         
     def test_nonregr5(self):
         # original jpl query:
-        # Any X, NOW - CD, P WHERE P is Project, U interested_in P, U is EUser, U login "sthenault", X concerns P, X creation_date CD ORDERBY CD DESC LIMIT 5
+        # Any X, NOW - CD, P WHERE P is Project, U interested_in P, U is CWUser, U login "sthenault", X concerns P, X creation_date CD ORDERBY CD DESC LIMIT 5
         rql = 'Any X, NOW - CD, P ORDERBY CD DESC LIMIT 5 WHERE P bookmarked_by U, U login "%s", P is X, X creation_date CD' % self.session.user.login
         self.execute(rql, )#{'x': })
         
@@ -309,7 +309,7 @@
         self.execute('Any B,U,UL GROUPBY B,U,UL WHERE B created_by U?, B is File '
                      'WITH U,UL BEING (Any U,UL WHERE ME eid %(x)s, (EXISTS(U identity ME) '
                      'OR (EXISTS(U in_group G, G name IN("managers", "staff")))) '
-                     'OR (EXISTS(U in_group H, ME in_group H, NOT H name "users")), U login UL, U is EUser)',
+                     'OR (EXISTS(U in_group H, ME in_group H, NOT H name "users")), U login UL, U is CWUser)',
                      {'x': self.session.user.eid})
 
 
@@ -363,12 +363,12 @@
         RQLGeneratorTC.tearDown(self)
         
     def test_base(self):
-        rqlst = self._prepare('EUser X WHERE X login "toto"').children[0]
+        rqlst = self._prepare('CWUser X WHERE X login "toto"').children[0]
         self.assertEquals(self.o.generate(rqlst, 'X')[1],
                           '(&(objectClass=top)(objectClass=posixAccount)(uid=toto))')
         
     def test_kwargs(self):
-        rqlst = self._prepare('EUser X WHERE X login %(x)s').children[0]
+        rqlst = self._prepare('CWUser X WHERE X login %(x)s').children[0]
         self.o._args = {'x': "toto"}
         self.assertEquals(self.o.generate(rqlst, 'X')[1],
                           '(&(objectClass=top)(objectClass=posixAccount)(uid=toto))')
--- a/server/test/unittest_migractions.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_migractions.py	Fri Apr 24 19:46:47 2009 +0200
@@ -127,9 +127,9 @@
         self.failIf('filed_under2' in self.schema)
         self.mh.cmd_add_entity_type('Folder2')
         self.failUnless('Folder2' in self.schema)
-        self.failUnless(self.execute('EEType X WHERE X name "Folder2"'))
+        self.failUnless(self.execute('CWEType X WHERE X name "Folder2"'))
         self.failUnless('filed_under2' in self.schema)
-        self.failUnless(self.execute('ERType X WHERE X name "filed_under2"'))
+        self.failUnless(self.execute('CWRType X WHERE X name "filed_under2"'))
         self.assertEquals(sorted(str(rs) for rs in self.schema['Folder2'].subject_relations()),
                           ['created_by', 'creation_date', 'description', 'description_format', 'eid',
                            'filed_under2', 'has_text', 'identity', 'is', 'is_instance_of',
@@ -154,7 +154,7 @@
         eschema = self.schema.eschema('Folder2')
         self.mh.cmd_drop_entity_type('Folder2')
         self.failIf('Folder2' in self.schema)
-        self.failIf(self.execute('EEType X WHERE X name "Folder2"'))
+        self.failIf(self.execute('CWEType X WHERE X name "Folder2"'))
         # test automatic workflow deletion
         self.failIf(self.execute('State X WHERE NOT X state_of ET'))
         self.failIf(self.execute('Transition X WHERE NOT X transition_of ET'))
@@ -179,7 +179,7 @@
     def test_add_relation_definition(self):
         self.mh.cmd_add_relation_definition('Societe', 'in_state', 'State')
         self.assertEquals(sorted(self.schema['in_state'].subjects()),
-                          ['Affaire', 'Division', 'EUser', 'Note', 'Societe', 'SubDivision'])
+                          ['Affaire', 'Division', 'CWUser', 'Note', 'Societe', 'SubDivision'])
         self.assertEquals(self.schema['in_state'].objects(), ('State',))
 
     def test_add_relation_definition_nortype(self):
@@ -210,7 +210,7 @@
         self.mh.cmd_drop_relation_definition('Personne', 'evaluee', 'Note')
         self.failUnless('evaluee' in self.schema)
         self.assertEquals(sorted(self.schema['evaluee'].subjects()),
-                          ['Division', 'EUser', 'Societe', 'SubDivision'])
+                          ['Division', 'CWUser', 'Societe', 'SubDivision'])
         self.assertEquals(sorted(self.schema['evaluee'].objects()),
                           ['Note'])
 
@@ -257,7 +257,7 @@
         migrschema['Personne'].description = 'blabla bla'
         migrschema['titre'].description = 'usually a title' 
         migrschema['titre']._rproperties[('Personne', 'String')]['description'] = 'title for this person'
-#         rinorderbefore = cursor.execute('Any O,N WHERE X is EFRDef, X relation_type RT, RT name N,'
+#         rinorderbefore = cursor.execute('Any O,N WHERE X is CWAttribute, X relation_type RT, RT name N,'
 #                                         'X from_entity FE, FE name "Personne",'
 #                                         'X ordernum O ORDERBY O')
 #         expected = [u'creation_date', u'modification_date', u'nom', u'prenom',
@@ -279,7 +279,7 @@
         # schema and so behaviour is undefined
         # "civility" is also skipped since it may have been added by
         # test_rename_attribut :o/
-        rinorder = [n for n, in cursor.execute('Any N ORDERBY O WHERE X is EFRDef, X relation_type RT, RT name N,'
+        rinorder = [n for n, in cursor.execute('Any N ORDERBY O WHERE X is CWAttribute, X relation_type RT, RT name N,'
                                                'X from_entity FE, FE name "Personne",'
                                                'X ordernum O') if n not in ('sexe', 'description', 'civility')]
         expected = [u'nom', u'prenom', u'promo', u'ass', u'adel', u'titre',
@@ -338,14 +338,14 @@
         self.mh.rollback()
 
     def _erqlexpr_rset(self, action, ertype):
-        rql = 'RQLExpression X WHERE ET is EEType, ET %s_permission X, ET name %%(name)s' % action
+        rql = 'RQLExpression X WHERE ET is CWEType, ET %s_permission X, ET name %%(name)s' % action
         return self.mh.rqlcursor.execute(rql, {'name': ertype})
     def _erqlexpr_entity(self, action, ertype):
         rset = self._erqlexpr_rset(action, ertype)
         self.assertEquals(len(rset), 1)
         return rset.get_entity(0, 0)
     def _rrqlexpr_rset(self, action, ertype):
-        rql = 'RQLExpression X WHERE ET is ERType, ET %s_permission X, ET name %%(name)s' % action
+        rql = 'RQLExpression X WHERE ET is CWRType, ET %s_permission X, ET name %%(name)s' % action
         return self.mh.rqlcursor.execute(rql, {'name': ertype})
     def _rrqlexpr_entity(self, action, ertype):
         rset = self._rrqlexpr_rset(action, ertype)
@@ -355,14 +355,14 @@
     def test_set_size_constraint(self):
         # existing previous value
         try:
-            self.mh.cmd_set_size_constraint('EEType', 'name', 128)
+            self.mh.cmd_set_size_constraint('CWEType', 'name', 128)
         finally:
-            self.mh.cmd_set_size_constraint('EEType', 'name', 64)
+            self.mh.cmd_set_size_constraint('CWEType', 'name', 64)
         # non existing previous value
         try:
-            self.mh.cmd_set_size_constraint('EEType', 'description', 256)
+            self.mh.cmd_set_size_constraint('CWEType', 'description', 256)
         finally:
-            self.mh.cmd_set_size_constraint('EEType', 'description', None)
+            self.mh.cmd_set_size_constraint('CWEType', 'description', None)
 
     def test_add_remove_cube(self):
         cubes = set(self.config.cubes())
--- a/server/test/unittest_msplanner.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_msplanner.py	Fri Apr 24 19:46:47 2009 +0200
@@ -19,7 +19,7 @@
 
 class FakeUserROSource(AbstractSource):
     uri = 'zzz'
-    support_entities = {'EUser': False}
+    support_entities = {'CWUser': False}
     support_relations = {}
     def syntax_tree_search(self, *args, **kwargs):
         return []
@@ -38,10 +38,10 @@
 
 X_ALL_SOLS = sorted([{'X': 'Affaire'}, {'X': 'Basket'}, {'X': 'Bookmark'},
                      {'X': 'Card'}, {'X': 'Comment'}, {'X': 'Division'},
-                     {'X': 'ECache'}, {'X': 'EConstraint'}, {'X': 'EConstraintType'},
-                     {'X': 'EEType'}, {'X': 'EFRDef'}, {'X': 'EGroup'},
-                     {'X': 'ENFRDef'}, {'X': 'EPermission'}, {'X': 'EProperty'},
-                     {'X': 'ERType'}, {'X': 'EUser'}, {'X': 'Email'},
+                     {'X': 'CWCache'}, {'X': 'CWConstraint'}, {'X': 'CWConstraintType'},
+                     {'X': 'CWEType'}, {'X': 'CWAttribute'}, {'X': 'CWGroup'},
+                     {'X': 'CWRelation'}, {'X': 'CWPermission'}, {'X': 'CWProperty'},
+                     {'X': 'CWRType'}, {'X': 'CWUser'}, {'X': 'Email'},
                      {'X': 'EmailAddress'}, {'X': 'EmailPart'}, {'X': 'EmailThread'},
                      {'X': 'File'}, {'X': 'Folder'}, {'X': 'Image'},
                      {'X': 'Note'}, {'X': 'Personne'}, {'X': 'RQLExpression'},
@@ -61,7 +61,7 @@
     """test planner related feature on a 3-sources repository:
     
     * system source supporting everything
-    * ldap source supporting EUser
+    * ldap source supporting CWUser
     * rql source supporting Card
     """
     repo = repo
@@ -79,11 +79,11 @@
         # add access to type attribute so S can't be invariant
         affreadperms[-1] = ERQLExpression('X concerne S?, S owned_by U, S type "X"')
         self.schema['Affaire']._groups['read'] = tuple(affreadperms)
-        # hijack EUser security
-        userreadperms = list(self.schema['EUser']._groups['read'])
+        # hijack CWUser security
+        userreadperms = list(self.schema['CWUser']._groups['read'])
         self.prevrqlexpr_user = userreadperms[-1]
         userreadperms[-1] = ERQLExpression('X owned_by U')
-        self.schema['EUser']._groups['read'] = tuple(userreadperms)
+        self.schema['CWUser']._groups['read'] = tuple(userreadperms)
         
         self.sources = self.o._repo.sources
         self.system = self.sources[-1]
@@ -115,10 +115,10 @@
         clear_cache(self.schema['Affaire'], 'ERSchema_get_rqlexprs')
         
     def restore_orig_euser_security(self):
-        userreadperms = list(self.schema['EUser']._groups['read'])
+        userreadperms = list(self.schema['CWUser']._groups['read'])
         userreadperms[-1] = self.prevrqlexpr_user
-        self.schema['EUser']._groups['read'] = tuple(userreadperms)
-        clear_cache(self.schema['EUser'], 'ERSchema_get_rqlexprs')
+        self.schema['CWUser']._groups['read'] = tuple(userreadperms)
+        clear_cache(self.schema['CWUser'], 'ERSchema_get_rqlexprs')
 
                   
 class PartPlanInformationTC(BaseMSPlannerTC):
@@ -143,13 +143,13 @@
         
     def test_simple_system_only(self):
         """retrieve entities only supported by the system source"""
-        self._test('EGroup X',
+        self._test('CWGroup X',
                    {self.system: {'X': s[0]}}, False)
         
     def test_simple_system_ldap(self):
-        """retrieve EUser X from both sources and return concatenation of results
+        """retrieve CWUser X from both sources and return concatenation of results
         """
-        self._test('EUser X',
+        self._test('CWUser X',
                    {self.system: {'X': s[0]}, self.ldap: {'X': s[0]}}, False)
         
     def test_simple_system_rql(self):
@@ -159,41 +159,41 @@
                    {self.system: {'X': s[0]}, self.rql: {'X': s[0]}}, False)
         
     def test_simple_eid_specified(self):
-        """retrieve EUser X from system source (eid is specified, can locate the entity)
+        """retrieve CWUser X from system source (eid is specified, can locate the entity)
         """
         ueid = self.session.user.eid
         self._test('Any X,L WHERE X eid %(x)s, X login L', {'x': ueid},
                    {self.system: {'X': s[0]}}, False)
         
     def test_simple_eid_invariant(self):
-        """retrieve EUser X from system source (eid is specified, can locate the entity)
+        """retrieve CWUser X from system source (eid is specified, can locate the entity)
         """
         ueid = self.session.user.eid
         self._test('Any X WHERE X eid %(x)s', {'x': ueid},
                    {self.system: {'x': s[0]}}, False)
         
     def test_simple_invariant(self):
-        """retrieve EUser X from system source only (X is invariant and in_group not supported by ldap source)
+        """retrieve CWUser X from system source only (X is invariant and in_group not supported by ldap source)
         """
-        self._test('Any X WHERE X is EUser, X in_group G, G name "users"',
+        self._test('Any X WHERE X is CWUser, X in_group G, G name "users"',
                    {self.system: {'X': s[0], 'G': s[0], 'in_group': s[0]}}, False)
         
     def test_security_has_text(self):
-        """retrieve EUser X from system source only (has_text not supported by ldap source)
+        """retrieve CWUser X from system source only (has_text not supported by ldap source)
         """
-        # specify EUser instead of any since the way this test is written we aren't well dealing
+        # specify CWUser instead of any since the way this test is written we aren't well dealing
         # with ambigous query (eg only considering the first solution)
-        self._test('EUser X WHERE X has_text "bla"',
+        self._test('CWUser X WHERE X has_text "bla"',
                    {self.system: {'X': s[0]}}, False)
         
     def test_complex_base(self):
         """
-        1. retrieve Any X, L WHERE X is EUser, X login L from system and ldap sources, store
+        1. retrieve Any X, L WHERE X is CWUser, X login L from system and ldap sources, store
            concatenation of results into a temporary table
         2. return the result of Any X, L WHERE X is TMP, X login L, X in_group G,
            G name 'users' on the system source
         """
-        self._test('Any X,L WHERE X is EUser, X in_group G, X login L, G name "users"',
+        self._test('Any X,L WHERE X is CWUser, X in_group G, X login L, G name "users"',
                    {self.system: {'X': s[0], 'G': s[0], 'in_group': s[0]},
                     self.ldap : {'X': s[0]}}, True)
 
@@ -222,7 +222,7 @@
                     self.ldap : {'X': s[0]}}, True)
 
     def test_complex_ambigous(self):
-        """retrieve EUser X from system and ldap sources, Person X from system source only
+        """retrieve CWUser X from system and ldap sources, Person X from system source only
         """
         self._test('Any X,F WHERE X firstname F',
                    {self.system: {'X': s[0, 1]},
@@ -370,61 +370,61 @@
     def test_simple_system_only(self):
         """retrieve entities only supported by the system source
         """
-        self._test('EGroup X',
-                   [('OneFetchStep', [('Any X WHERE X is EGroup', [{'X': 'EGroup'}])],
+        self._test('CWGroup X',
+                   [('OneFetchStep', [('Any X WHERE X is CWGroup', [{'X': 'CWGroup'}])],
                      None, None, [self.system], {}, [])])
 
     def test_simple_system_only_limit(self):
         """retrieve entities only supported by the system source
         """
-        self._test('EGroup X LIMIT 10',
-                   [('OneFetchStep', [('Any X LIMIT 10 WHERE X is EGroup', [{'X': 'EGroup'}])],
+        self._test('CWGroup X LIMIT 10',
+                   [('OneFetchStep', [('Any X LIMIT 10 WHERE X is CWGroup', [{'X': 'CWGroup'}])],
                      10, None, [self.system], {}, [])])
 
     def test_simple_system_only_limit_offset(self):
         """retrieve entities only supported by the system source
         """
-        self._test('EGroup X LIMIT 10 OFFSET 10',
-                   [('OneFetchStep', [('Any X LIMIT 10 OFFSET 10 WHERE X is EGroup', [{'X': 'EGroup'}])],
+        self._test('CWGroup X LIMIT 10 OFFSET 10',
+                   [('OneFetchStep', [('Any X LIMIT 10 OFFSET 10 WHERE X is CWGroup', [{'X': 'CWGroup'}])],
                      10, 10, [self.system], {}, [])])
         
     def test_simple_system_ldap(self):
-        """retrieve EUser X from both sources and return concatenation of results
+        """retrieve CWUser X from both sources and return concatenation of results
         """
-        self._test('EUser X',
-                   [('OneFetchStep', [('Any X WHERE X is EUser', [{'X': 'EUser'}])],
+        self._test('CWUser X',
+                   [('OneFetchStep', [('Any X WHERE X is CWUser', [{'X': 'CWUser'}])],
                      None, None, [self.ldap, self.system], {}, [])])
         
     def test_simple_system_ldap_limit(self):
-        """retrieve EUser X from both sources and return concatenation of results
+        """retrieve CWUser X from both sources and return concatenation of results
         """
-        self._test('EUser X LIMIT 10',
-                   [('OneFetchStep', [('Any X LIMIT 10 WHERE X is EUser', [{'X': 'EUser'}])],
+        self._test('CWUser X LIMIT 10',
+                   [('OneFetchStep', [('Any X LIMIT 10 WHERE X is CWUser', [{'X': 'CWUser'}])],
                      10, None, [self.ldap, self.system], {}, [])])
 
     def test_simple_system_ldap_limit_offset(self):
-        """retrieve EUser X from both sources and return concatenation of results
+        """retrieve CWUser X from both sources and return concatenation of results
         """
-        self._test('EUser X LIMIT 10 OFFSET 10',
-                   [('OneFetchStep', [('Any X LIMIT 10 OFFSET 10 WHERE X is EUser', [{'X': 'EUser'}])],
+        self._test('CWUser X LIMIT 10 OFFSET 10',
+                   [('OneFetchStep', [('Any X LIMIT 10 OFFSET 10 WHERE X is CWUser', [{'X': 'CWUser'}])],
                      10, 10, [self.ldap, self.system], {}, [])])
 
     def test_simple_system_ldap_ordered_limit_offset(self):
-        """retrieve EUser X from both sources and return concatenation of results
+        """retrieve CWUser X from both sources and return concatenation of results
         """
-        self._test('EUser X ORDERBY X LIMIT 10 OFFSET 10',
+        self._test('CWUser X ORDERBY X LIMIT 10 OFFSET 10',
                    [('AggrStep', 'Any X ORDERBY X', 10, 10, 'table0', None, [
-                       ('FetchStep', [('Any X WHERE X is EUser', [{'X': 'EUser'}])],
+                       ('FetchStep', [('Any X WHERE X is CWUser', [{'X': 'CWUser'}])],
                         [self.ldap, self.system], {}, {'X': 'table0.C0'}, []),
                        ]),
                    ])
     def test_simple_system_ldap_aggregat(self):
-        """retrieve EUser X from both sources and return concatenation of results
+        """retrieve CWUser X from both sources and return concatenation of results
         """
         # COUNT(X) is kept in sub-step and transformed into SUM(X) in the AggrStep
-        self._test('Any COUNT(X) WHERE X is EUser',
+        self._test('Any COUNT(X) WHERE X is CWUser',
                    [('AggrStep', 'Any COUNT(X)', None, None, 'table0', None, [
-                       ('FetchStep', [('Any COUNT(X) WHERE X is EUser', [{'X': 'EUser'}])],
+                       ('FetchStep', [('Any COUNT(X) WHERE X is CWUser', [{'X': 'CWUser'}])],
                         [self.ldap, self.system], {}, {'COUNT(X)': 'table0.C0'}, []),
                        ]),
                    ])
@@ -437,16 +437,16 @@
                      None, None, [self.rql, self.system], {}, [])])
         
     def test_simple_eid_specified(self):
-        """retrieve EUser X from system source (eid is specified, can locate the entity)
+        """retrieve CWUser X from system source (eid is specified, can locate the entity)
         """
         ueid = self.session.user.eid
         self._test('Any X,L WHERE X eid %(x)s, X login L',
-                   [('OneFetchStep', [('Any X,L WHERE X eid %s, X login L'%ueid, [{'X': 'EUser', 'L': 'String'}])],
+                   [('OneFetchStep', [('Any X,L WHERE X eid %s, X login L'%ueid, [{'X': 'CWUser', 'L': 'String'}])],
                      None, None, [self.system], {}, [])],
                    {'x': ueid})
         
     def test_simple_eid_invariant(self):
-        """retrieve EUser X from system source (eid is specified, can locate the entity)
+        """retrieve CWUser X from system source (eid is specified, can locate the entity)
         """
         ueid = self.session.user.eid
         self._test('Any X WHERE X eid %(x)s',
@@ -455,43 +455,43 @@
                    {'x': ueid})
         
     def test_simple_invariant(self):
-        """retrieve EUser X from system source only (X is invariant and in_group not supported by ldap source)
+        """retrieve CWUser X from system source only (X is invariant and in_group not supported by ldap source)
         """
-        self._test('Any X WHERE X is EUser, X in_group G, G name "users"',
-                   [('OneFetchStep', [('Any X WHERE X is EUser, X in_group G, G name "users"',
-                                       [{'X': 'EUser', 'G': 'EGroup'}])],
+        self._test('Any X WHERE X is CWUser, X in_group G, G name "users"',
+                   [('OneFetchStep', [('Any X WHERE X is CWUser, X in_group G, G name "users"',
+                                       [{'X': 'CWUser', 'G': 'CWGroup'}])],
                      None, None, [self.system], {}, [])])
         
     def test_complex_base(self):
         """
-        1. retrieve Any X, L WHERE X is EUser, X login L from system and ldap sources, store
+        1. retrieve Any X, L WHERE X is CWUser, X login L from system and ldap sources, store
            concatenation of results into a temporary table
         2. return the result of Any X, L WHERE X is TMP, X login LX in_group G,
            G name 'users' on the system source
         """
-        self._test('Any X,L WHERE X is EUser, X in_group G, X login L, G name "users"',
-                   [('FetchStep', [('Any X,L WHERE X login L, X is EUser', [{'X': 'EUser', 'L': 'String'}])],
+        self._test('Any X,L WHERE X is CWUser, X in_group G, X login L, G name "users"',
+                   [('FetchStep', [('Any X,L WHERE X login L, X is CWUser', [{'X': 'CWUser', 'L': 'String'}])],
                      [self.ldap, self.system], None,
                      {'X': 'table0.C0', 'X.login': 'table0.C1', 'L': 'table0.C1'}, []),
-                    ('OneFetchStep', [('Any X,L WHERE X in_group G, X login L, G name "users", G is EGroup, X is EUser',
-                                       [{'X': 'EUser', 'L': 'String', 'G': 'EGroup'}])],
+                    ('OneFetchStep', [('Any X,L WHERE X in_group G, X login L, G name "users", G is CWGroup, X is CWUser',
+                                       [{'X': 'CWUser', 'L': 'String', 'G': 'CWGroup'}])],
                      None, None, [self.system],
                      {'X': 'table0.C0', 'X.login': 'table0.C1', 'L': 'table0.C1'}, [])
                     ])
 
     def test_complex_base_limit_offset(self):
         """
-        1. retrieve Any X, L WHERE X is EUser, X login L from system and ldap sources, store
+        1. retrieve Any X, L WHERE X is CWUser, X login L from system and ldap sources, store
            concatenation of results into a temporary table
         2. return the result of Any X, L WHERE X is TMP, X login LX in_group G,
            G name 'users' on the system source
         """
-        self._test('Any X,L LIMIT 10 OFFSET 10 WHERE X is EUser, X in_group G, X login L, G name "users"',
-                   [('FetchStep', [('Any X,L WHERE X login L, X is EUser', [{'X': 'EUser', 'L': 'String'}])],
+        self._test('Any X,L LIMIT 10 OFFSET 10 WHERE X is CWUser, X in_group G, X login L, G name "users"',
+                   [('FetchStep', [('Any X,L WHERE X login L, X is CWUser', [{'X': 'CWUser', 'L': 'String'}])],
                      [self.ldap, self.system], None,
                      {'X': 'table0.C0', 'X.login': 'table0.C1', 'L': 'table0.C1'}, []),
-                    ('OneFetchStep', [('Any X,L LIMIT 10 OFFSET 10 WHERE X in_group G, X login L, G name "users", G is EGroup, X is EUser',
-                                       [{'X': 'EUser', 'L': 'String', 'G': 'EGroup'}])],
+                    ('OneFetchStep', [('Any X,L LIMIT 10 OFFSET 10 WHERE X in_group G, X login L, G name "users", G is CWGroup, X is CWUser',
+                                       [{'X': 'CWUser', 'L': 'String', 'G': 'CWGroup'}])],
                      10, 10,
                      [self.system], {'X': 'table0.C0', 'X.login': 'table0.C1', 'L': 'table0.C1'}, [])
                     ])
@@ -499,8 +499,8 @@
     def test_complex_ordered(self):
         self._test('Any L ORDERBY L WHERE X login L',
                    [('AggrStep', 'Any L ORDERBY L', None, None, 'table0', None, 
-                     [('FetchStep', [('Any L WHERE X login L, X is EUser',
-                                      [{'X': 'EUser', 'L': 'String'}])],
+                     [('FetchStep', [('Any L WHERE X login L, X is CWUser',
+                                      [{'X': 'CWUser', 'L': 'String'}])],
                        [self.ldap, self.system], {}, {'X.login': 'table0.C0', 'L': 'table0.C0'}, []),
                       ])
                     ])
@@ -508,8 +508,8 @@
     def test_complex_ordered_limit_offset(self):
         self._test('Any L ORDERBY L LIMIT 10 OFFSET 10 WHERE X login L',
                    [('AggrStep', 'Any L ORDERBY L', 10, 10, 'table0', None, 
-                     [('FetchStep', [('Any L WHERE X login L, X is EUser',
-                                      [{'X': 'EUser', 'L': 'String'}])],
+                     [('FetchStep', [('Any L WHERE X login L, X is CWUser',
+                                      [{'X': 'CWUser', 'L': 'String'}])],
                        [self.ldap, self.system], {}, {'X.login': 'table0.C0', 'L': 'table0.C0'}, []),
                       ])
                     ])
@@ -526,13 +526,13 @@
         ueid = self.session.user.eid
         self._test('Any X,AA ORDERBY AA WHERE E eid %(x)s, E owned_by X, X modification_date AA',
                    [('FetchStep',
-                     [('Any X,AA WHERE X modification_date AA, X is EUser',
-                       [{'AA': 'Datetime', 'X': 'EUser'}])],
+                     [('Any X,AA WHERE X modification_date AA, X is CWUser',
+                       [{'AA': 'Datetime', 'X': 'CWUser'}])],
                      [self.ldap, self.system], None,
                      {'AA': 'table0.C1', 'X': 'table0.C0', 'X.modification_date': 'table0.C1'}, []),
                     ('OneFetchStep',
-                     [('Any X,AA ORDERBY AA WHERE 5 owned_by X, X modification_date AA, X is EUser',
-                       [{'AA': 'Datetime', 'X': 'EUser'}])],
+                     [('Any X,AA ORDERBY AA WHERE 5 owned_by X, X modification_date AA, X is CWUser',
+                       [{'AA': 'Datetime', 'X': 'CWUser'}])],
                      None, None, [self.system],
                      {'AA': 'table0.C1', 'X': 'table0.C0', 'X.modification_date': 'table0.C1'}, []),
                     ],
@@ -547,23 +547,23 @@
         """
         ueid = self.session.user.eid
         self._test('Any X,L,AA WHERE E eid %(x)s, E owned_by X, X login L, X modification_date AA',
-                   [('FetchStep', [('Any X,L,AA WHERE X login L, X modification_date AA, X is EUser',
-                                    [{'AA': 'Datetime', 'X': 'EUser', 'L': 'String'}])],
+                   [('FetchStep', [('Any X,L,AA WHERE X login L, X modification_date AA, X is CWUser',
+                                    [{'AA': 'Datetime', 'X': 'CWUser', 'L': 'String'}])],
                      [self.ldap, self.system], None,
                      {'AA': 'table0.C2', 'X': 'table0.C0', 'X.login': 'table0.C1', 'X.modification_date': 'table0.C2', 'L': 'table0.C1'}, []),
-                    ('OneFetchStep', [('Any X,L,AA WHERE %s owned_by X, X login L, X modification_date AA, X is EUser'%ueid,
-                                       [{'AA': 'Datetime', 'X': 'EUser', 'L': 'String'}])],
+                    ('OneFetchStep', [('Any X,L,AA WHERE %s owned_by X, X login L, X modification_date AA, X is CWUser'%ueid,
+                                       [{'AA': 'Datetime', 'X': 'CWUser', 'L': 'String'}])],
                      None, None, [self.system],
                      {'AA': 'table0.C2', 'X': 'table0.C0', 'X.login': 'table0.C1', 'X.modification_date': 'table0.C2', 'L': 'table0.C1'}, [])],
                    {'x': ueid})
 
     def test_complex_ambigous(self):
-        """retrieve EUser X from system and ldap sources, Person X from system source only
+        """retrieve CWUser X from system and ldap sources, Person X from system source only
         """
         self._test('Any X,F WHERE X firstname F',
                    [('UnionStep', None, None, [
-                       ('OneFetchStep', [('Any X,F WHERE X firstname F, X is EUser',
-                                          [{'X': 'EUser', 'F': 'String'}])],
+                       ('OneFetchStep', [('Any X,F WHERE X firstname F, X is CWUser',
+                                          [{'X': 'CWUser', 'F': 'String'}])],
                         None, None, [self.ldap, self.system], {}, []),
                        ('OneFetchStep', [('Any X,F WHERE X firstname F, X is Personne',
                                           [{'X': 'Personne', 'F': 'String'}])],
@@ -572,12 +572,12 @@
                     ])
 
     def test_complex_ambigous_limit_offset(self):
-        """retrieve EUser X from system and ldap sources, Person X from system source only
+        """retrieve CWUser X from system and ldap sources, Person X from system source only
         """
         self._test('Any X,F LIMIT 10 OFFSET 10 WHERE X firstname F',
                    [('UnionStep', 10, 10, [
-                       ('OneFetchStep', [('Any X,F WHERE X firstname F, X is EUser',
-                                          [{'X': 'EUser', 'F': 'String'}])],
+                       ('OneFetchStep', [('Any X,F WHERE X firstname F, X is CWUser',
+                                          [{'X': 'CWUser', 'F': 'String'}])],
                         None, None,
                         [self.ldap, self.system], {}, []),
                        ('OneFetchStep', [('Any X,F WHERE X firstname F, X is Personne',
@@ -588,14 +588,14 @@
 
     def test_complex_ambigous_ordered(self):
         """
-        1. retrieve EUser X from system and ldap sources, Person X from system source only, store
+        1. retrieve CWUser X from system and ldap sources, Person X from system source only, store
            each result in the same temp table
         2. return content of the table sorted
         """
         self._test('Any X,F ORDERBY F WHERE X firstname F',
                    [('AggrStep', 'Any X,F ORDERBY F', None, None, 'table0', None, 
-                     [('FetchStep', [('Any X,F WHERE X firstname F, X is EUser',
-                                      [{'X': 'EUser', 'F': 'String'}])],
+                     [('FetchStep', [('Any X,F WHERE X firstname F, X is CWUser',
+                                      [{'X': 'CWUser', 'F': 'String'}])],
                        [self.ldap, self.system], {},
                        {'X': 'table0.C0', 'X.firstname': 'table0.C1', 'F': 'table0.C1'}, []),
                       ('FetchStep', [('Any X,F WHERE X firstname F, X is Personne',
@@ -615,15 +615,15 @@
         ueid = self.session.user.eid
         self._test('Any X,Y WHERE X login "syt", Y login "adim"',
                    [('FetchStep',
-                     [('Any X WHERE X login "syt", X is EUser', [{'X': 'EUser'}])],
+                     [('Any X WHERE X login "syt", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None,
                      {'X': 'table0.C0'}, []),
                     ('FetchStep',
-                     [('Any Y WHERE Y login "adim", Y is EUser', [{'Y': 'EUser'}])],
+                     [('Any Y WHERE Y login "adim", Y is CWUser', [{'Y': 'CWUser'}])],
                      [self.ldap, self.system], None,
                      {'Y': 'table1.C0'}, []),
                     ('OneFetchStep',
-                     [('Any X,Y WHERE X is EUser, Y is EUser', [{'X': 'EUser', 'Y': 'EUser'}])],
+                     [('Any X,Y WHERE X is CWUser, Y is CWUser', [{'X': 'CWUser', 'Y': 'CWUser'}])],
                      None, None, [self.system],
                      {'X': 'table0.C0', 'Y': 'table1.C0'}, [])
                     ], {'x': ueid})
@@ -638,13 +638,13 @@
         ueid = self.session.user.eid
         self._test('Any X,Y LIMIT 10 OFFSET 10 WHERE X login "syt", Y login "adim"',
                    [('FetchStep',
-                     [('Any X WHERE X login "syt", X is EUser', [{'X': 'EUser'}])],
+                     [('Any X WHERE X login "syt", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table0.C0'}, []),
                     ('FetchStep',
-                     [('Any Y WHERE Y login "adim", Y is EUser', [{'Y': 'EUser'}])],
+                     [('Any Y WHERE Y login "adim", Y is CWUser', [{'Y': 'CWUser'}])],
                      [self.ldap, self.system], None, {'Y': 'table1.C0'}, []),
                     ('OneFetchStep',
-                     [('Any X,Y LIMIT 10 OFFSET 10 WHERE X is EUser, Y is EUser', [{'X': 'EUser', 'Y': 'EUser'}])],
+                     [('Any X,Y LIMIT 10 OFFSET 10 WHERE X is CWUser, Y is CWUser', [{'X': 'CWUser', 'Y': 'CWUser'}])],
                      10, 10, [self.system],
                      {'X': 'table0.C0', 'Y': 'table1.C0'}, [])
                     ], {'x': ueid})
@@ -683,7 +683,7 @@
         ueid = self.session.user.eid
         self._test('Any U WHERE WF wf_info_for X, X eid %(x)s, WF owned_by U?, WF from_state FS',
                    [('OneFetchStep', [('Any U WHERE WF wf_info_for 5, WF owned_by U?, WF from_state FS',
-                                       [{'WF': 'TrInfo', 'FS': 'State', 'U': 'EUser'}])],
+                                       [{'WF': 'TrInfo', 'FS': 'State', 'U': 'CWUser'}])],
                      None, None, [self.system], {}, [])],
                    {'x': ueid})
 
@@ -691,7 +691,7 @@
         ueid = self.session.user.eid
         self._test('Any U WHERE WF wf_info_for X, X eid %(x)s, WF owned_by U?, WF from_state FS',
                    [('OneFetchStep', [('Any U WHERE WF wf_info_for 5, WF owned_by U?, WF from_state FS',
-                                       [{'WF': 'TrInfo', 'FS': 'State', 'U': 'EUser'}])],
+                                       [{'WF': 'TrInfo', 'FS': 'State', 'U': 'CWUser'}])],
                      None, None, [self.system], {}, [])],
                    {'x': ueid})
 
@@ -701,16 +701,16 @@
                    [('FetchStep', [('Any X,T WHERE X title T, X is Card', [{'X': 'Card', 'T': 'String'}])],
                      [self.rql, self.system], None,
                      {'T': 'table0.C1', 'X': 'table0.C0', 'X.title': 'table0.C1'}, []),
-                    ('FetchStep', [('Any U WHERE U login "syt", U is EUser', [{'U': 'EUser'}])],
+                    ('FetchStep', [('Any U WHERE U login "syt", U is CWUser', [{'U': 'CWUser'}])],
                      [self.ldap, self.system], None,
                      {'U': 'table1.C0'}, []),
                     ('UnionStep', None, None, [
-                        ('OneFetchStep', [('Any X,T WHERE X owned_by U, X title T, U is EUser, X is IN(Bookmark, EmailThread)',
-                                           [{'T': 'String', 'U': 'EUser', 'X': 'Bookmark'},
-                                            {'T': 'String', 'U': 'EUser', 'X': 'EmailThread'}])],
+                        ('OneFetchStep', [('Any X,T WHERE X owned_by U, X title T, U is CWUser, X is IN(Bookmark, EmailThread)',
+                                           [{'T': 'String', 'U': 'CWUser', 'X': 'Bookmark'},
+                                            {'T': 'String', 'U': 'CWUser', 'X': 'EmailThread'}])],
                          None, None, [self.system], {'U': 'table1.C0'}, []),
-                        ('OneFetchStep', [('Any X,T WHERE X owned_by U, X title T, U is EUser, X is Card',
-                                           [{'X': 'Card', 'U': 'EUser', 'T': 'String'}])],
+                        ('OneFetchStep', [('Any X,T WHERE X owned_by U, X title T, U is CWUser, X is Card',
+                                           [{'X': 'Card', 'U': 'CWUser', 'T': 'String'}])],
                          None, None, [self.system],
                          {'X': 'table0.C0', 'X.title': 'table0.C1', 'T': 'table0.C1', 'U': 'table1.C0'}, []),
                         ]),
@@ -749,7 +749,7 @@
         # both system and rql support all variables, can be 
         self._test('Any X WHERE NOT X identity U, U eid %s' % self.session.user.eid,
                    [('OneFetchStep',
-                     [('Any X WHERE NOT X identity 5, X is EUser', [{'X': 'EUser'}])],
+                     [('Any X WHERE NOT X identity 5, X is CWUser', [{'X': 'CWUser'}])],
                      None, None,
                      [self.ldap, self.system], {}, [])
                     ])
@@ -761,11 +761,11 @@
                                     [{'Y': 'Note', 'A': 'State', 'R': 'String'}])],
                      [self.rql, self.system], None,
                      {'A': 'table0.C0', 'R': 'table0.C1', 'Y.type': 'table0.C1'}, []),
-                    ('FetchStep', [('Any X,R WHERE X login R, X is EUser', [{'X': 'EUser', 'R': 'String'}])],
+                    ('FetchStep', [('Any X,R WHERE X login R, X is CWUser', [{'X': 'CWUser', 'R': 'String'}])],
                      [self.ldap, self.system], None,
                      {'X': 'table1.C0', 'X.login': 'table1.C1', 'R': 'table1.C1'}, []),
-                    ('OneFetchStep', [('Any X,MAX(R) GROUPBY X WHERE X in_state S, X login R, NOT EXISTS(Y type R, S identity A, A is State, Y is Note), S is State, X is EUser',
-                                       [{'Y': 'Note', 'X': 'EUser', 'S': 'State', 'R': 'String', 'A': 'State'}])],
+                    ('OneFetchStep', [('Any X,MAX(R) GROUPBY X WHERE X in_state S, X login R, NOT EXISTS(Y type R, S identity A, A is State, Y is Note), S is State, X is CWUser',
+                                       [{'Y': 'Note', 'X': 'CWUser', 'S': 'State', 'R': 'String', 'A': 'State'}])],
                      None, None, [self.system],
                      {'A': 'table0.C0', 'X': 'table1.C0', 'X.login': 'table1.C1', 'R': 'table1.C1', 'Y.type': 'table0.C1'}, [])
                     ])
@@ -784,8 +784,8 @@
                       ('OneFetchStep',
                        [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is Basket',
                          [{'X': 'Basket'}]),
-                        ('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is EUser',
-                         [{'X': 'EUser'}]),
+                        ('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser',
+                         [{'X': 'CWUser'}]),
                         ('Any X WHERE X has_text "bla", X is IN(Card, Comment, Division, Email, EmailThread, File, Folder, Image, Note, Personne, Societe, State, SubDivision, Tag, Transition)',
                          [{'X': 'Card'}, {'X': 'Comment'}, {'X': 'Division'},
                           {'X': 'Email'}, {'X': 'EmailThread'}, {'X': 'File'},
@@ -810,8 +810,8 @@
                          ('FetchStep',
                           [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is Basket',
                          [{'X': 'Basket'}]),
-                        ('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is EUser',
-                         [{'X': 'EUser'}]),
+                        ('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser',
+                         [{'X': 'CWUser'}]),
                         ('Any X WHERE X has_text "bla", X is IN(Card, Comment, Division, Email, EmailThread, File, Folder, Image, Note, Personne, Societe, State, SubDivision, Tag, Transition)',
                          [{'X': 'Card'}, {'X': 'Comment'}, {'X': 'Division'},
                           {'X': 'Email'}, {'X': 'EmailThread'}, {'X': 'File'},
@@ -823,7 +823,7 @@
                     ('OneFetchStep',
                      [('Any X LIMIT 10 OFFSET 10',
                        [{'X': 'Affaire'}, {'X': 'Basket'}, {'X': 'Card'},
-                        {'X': 'Comment'}, {'X': 'Division'}, {'X': 'EUser'},
+                        {'X': 'Comment'}, {'X': 'Division'}, {'X': 'CWUser'},
                         {'X': 'Email'}, {'X': 'EmailThread'}, {'X': 'File'},
                         {'X': 'Folder'}, {'X': 'Image'}, {'X': 'Note'},
                         {'X': 'Personne'}, {'X': 'Societe'}, {'X': 'State'},
@@ -837,20 +837,20 @@
         self.session = self._user_session()[1]
         self._test('Any X WHERE X login "bla"',
                    [('FetchStep',
-                     [('Any X WHERE X login "bla", X is EUser', [{'X': 'EUser'}])],
+                     [('Any X WHERE X login "bla", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table0.C0'}, []),
                     ('OneFetchStep',
-                     [('Any X WHERE EXISTS(X owned_by 5), X is EUser', [{'X': 'EUser'}])],
+                     [('Any X WHERE EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
                      None, None, [self.system], {'X': 'table0.C0'}, [])])
                 
     def test_security_complex_has_text(self):
         # use a guest user
         self.session = self._user_session()[1]
         self._test('Any X WHERE X has_text "bla", X firstname "bla"',
-                   [('FetchStep', [('Any X WHERE X firstname "bla", X is EUser', [{'X': 'EUser'}])],
+                   [('FetchStep', [('Any X WHERE X firstname "bla", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table0.C0'}, []),
                     ('UnionStep', None, None, [
-                        ('OneFetchStep', [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is EUser', [{'X': 'EUser'}])],
+                        ('OneFetchStep', [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
                          None, None, [self.system], {'X': 'table0.C0'}, []),
                         ('OneFetchStep', [('Any X WHERE X has_text "bla", X firstname "bla", X is Personne', [{'X': 'Personne'}])],
                          None, None, [self.system], {}, []),
@@ -861,16 +861,16 @@
         # use a guest user
         self.session = self._user_session()[1]
         self._test('Any X LIMIT 10 OFFSET 10 WHERE X has_text "bla", X firstname "bla"',
-                   [('FetchStep', [('Any X WHERE X firstname "bla", X is EUser', [{'X': 'EUser'}])],
+                   [('FetchStep', [('Any X WHERE X firstname "bla", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table1.C0'}, []),
                     ('UnionFetchStep', [
-                        ('FetchStep', [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is EUser', [{'X': 'EUser'}])],
+                        ('FetchStep', [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
                          [self.system], {'X': 'table1.C0'}, {'X': 'table0.C0'}, []),
                         ('FetchStep', [('Any X WHERE X has_text "bla", X firstname "bla", X is Personne', [{'X': 'Personne'}])],
                          [self.system], {}, {'X': 'table0.C0'}, []),
                         ]),
                      ('OneFetchStep',
-                      [('Any X LIMIT 10 OFFSET 10', [{'X': 'EUser'}, {'X': 'Personne'}])],
+                      [('Any X LIMIT 10 OFFSET 10', [{'X': 'CWUser'}, {'X': 'Personne'}])],
                       10, 10, [self.system], {'X': 'table0.C0'}, [])
                     ])
 
@@ -880,7 +880,7 @@
         self._test('Any MAX(X)',
                    [('FetchStep', [('Any E WHERE E type "X", E is Note', [{'E': 'Note'}])],
                      [self.rql, self.system],  None, {'E': 'table1.C0'}, []), 
-                    ('FetchStep', [('Any X WHERE X is EUser', [{'X': 'EUser'}])],
+                    ('FetchStep', [('Any X WHERE X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table2.C0'}, []),
                     ('UnionFetchStep', [
                         ('FetchStep', [('Any X WHERE EXISTS(X owned_by 5), X is Basket', [{'X': 'Basket'}])],
@@ -890,19 +890,19 @@
                                           [{'X': 'Card'}, {'X': 'Note'}, {'X': 'State'}])],
                            [self.rql, self.system], {}, {'X': 'table0.C0'}, []),
                           ('FetchStep',
-                           [('Any X WHERE X is IN(Bookmark, Comment, Division, ECache, EConstraint, EConstraintType, EEType, EFRDef, EGroup, ENFRDef, EPermission, EProperty, ERType, Email, EmailAddress, EmailPart, EmailThread, File, Folder, Image, Personne, RQLExpression, Societe, SubDivision, Tag, TrInfo, Transition)',
+                           [('Any X WHERE X is IN(Bookmark, Comment, Division, CWCache, CWConstraint, CWConstraintType, CWEType, CWAttribute, CWGroup, CWRelation, CWPermission, CWProperty, CWRType, Email, EmailAddress, EmailPart, EmailThread, File, Folder, Image, Personne, RQLExpression, Societe, SubDivision, Tag, TrInfo, Transition)',
                              sorted([{'X': 'Bookmark'}, {'X': 'Comment'}, {'X': 'Division'},
-                                      {'X': 'ECache'}, {'X': 'EConstraint'}, {'X': 'EConstraintType'},
-                                      {'X': 'EEType'}, {'X': 'EFRDef'}, {'X': 'EGroup'},
-                                      {'X': 'ENFRDef'}, {'X': 'EPermission'}, {'X': 'EProperty'},
-                                      {'X': 'ERType'}, {'X': 'Email'}, {'X': 'EmailAddress'},
+                                      {'X': 'CWCache'}, {'X': 'CWConstraint'}, {'X': 'CWConstraintType'},
+                                      {'X': 'CWEType'}, {'X': 'CWAttribute'}, {'X': 'CWGroup'},
+                                      {'X': 'CWRelation'}, {'X': 'CWPermission'}, {'X': 'CWProperty'},
+                                      {'X': 'CWRType'}, {'X': 'Email'}, {'X': 'EmailAddress'},
                                       {'X': 'EmailPart'}, {'X': 'EmailThread'}, {'X': 'File'},
                                       {'X': 'Folder'}, {'X': 'Image'}, {'X': 'Personne'},
                                       {'X': 'RQLExpression'}, {'X': 'Societe'}, {'X': 'SubDivision'},
                                       {'X': 'Tag'}, {'X': 'TrInfo'}, {'X': 'Transition'}]))],
                            [self.system], {}, {'X': 'table0.C0'}, []),
                           ]),
-                        ('FetchStep', [('Any X WHERE EXISTS(X owned_by 5), X is EUser', [{'X': 'EUser'}])],
+                        ('FetchStep', [('Any X WHERE EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
                          [self.system], {'X': 'table2.C0'}, {'X': 'table0.C0'}, []),
                         ('FetchStep', [('Any X WHERE (EXISTS(X owned_by 5)) OR ((((EXISTS(D concerne C?, C owned_by 5, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by 5, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by 5, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by 5, X identity J, E is Note, J is Affaire))), X is Affaire',
                                         [{'C': 'Division', 'E': 'Note', 'D': 'Affaire', 'G': 'SubDivision', 'F': 'Societe', 'I': 'Affaire', 'H': 'Affaire', 'J': 'Affaire', 'X': 'Affaire'}])],
@@ -921,67 +921,67 @@
                      [self.rql, self.system], None, {'X': 'table1.C0'}, []),
                     ('FetchStep', [('Any E WHERE E type "X", E is Note', [{'E': 'Note'}])],
                      [self.rql, self.system],  None, {'E': 'table2.C0'}, []),
-                    ('FetchStep', [('Any X WHERE X is EUser', [{'X': 'EUser'}])],
+                    ('FetchStep', [('Any X WHERE X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table3.C0'}, []),
                     ('UnionFetchStep',
-                     [('FetchStep', [('Any ET,X WHERE X is ET, EXISTS(X owned_by 5), ET is EEType, X is Basket',
-                                      [{'ET': 'EEType', 'X': 'Basket'}])],
+                     [('FetchStep', [('Any ET,X WHERE X is ET, EXISTS(X owned_by 5), ET is CWEType, X is Basket',
+                                      [{'ET': 'CWEType', 'X': 'Basket'}])],
                        [self.system], {}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
-                      ('FetchStep', [('Any ET,X WHERE X is ET, (EXISTS(X owned_by 5)) OR ((((EXISTS(D concerne C?, C owned_by 5, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by 5, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by 5, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by 5, X identity J, E is Note, J is Affaire))), ET is EEType, X is Affaire',
+                      ('FetchStep', [('Any ET,X WHERE X is ET, (EXISTS(X owned_by 5)) OR ((((EXISTS(D concerne C?, C owned_by 5, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by 5, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by 5, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by 5, X identity J, E is Note, J is Affaire))), ET is CWEType, X is Affaire',
                                       [{'C': 'Division', 'E': 'Note', 'D': 'Affaire',
                                         'G': 'SubDivision', 'F': 'Societe', 'I': 'Affaire',
                                         'H': 'Affaire', 'J': 'Affaire', 'X': 'Affaire',
-                                        'ET': 'EEType'}])],
+                                        'ET': 'CWEType'}])],
                        [self.system], {'E': 'table2.C0'}, {'ET': 'table0.C0', 'X': 'table0.C1'},
                        []),
-                      ('FetchStep', [('Any ET,X WHERE X is ET, EXISTS(X owned_by 5), ET is EEType, X is EUser',
-                                      [{'ET': 'EEType', 'X': 'EUser'}])],
+                      ('FetchStep', [('Any ET,X WHERE X is ET, EXISTS(X owned_by 5), ET is CWEType, X is CWUser',
+                                      [{'ET': 'CWEType', 'X': 'CWUser'}])],
                        [self.system], {'X': 'table3.C0'}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
                       # extra UnionFetchStep could be avoided but has no cost, so don't care
                       ('UnionFetchStep',
-                       [('FetchStep', [('Any ET,X WHERE X is ET, ET is EEType, X is IN(Bookmark, Comment, Division, ECache, EConstraint, EConstraintType, EEType, EFRDef, EGroup, ENFRDef, EPermission, EProperty, ERType, Email, EmailAddress, EmailPart, EmailThread, File, Folder, Image, Personne, RQLExpression, Societe, SubDivision, Tag, TrInfo, Transition)',
-                                        [{'X': 'Bookmark', 'ET': 'EEType'}, {'X': 'Comment', 'ET': 'EEType'},
-                                         {'X': 'Division', 'ET': 'EEType'}, {'X': 'ECache', 'ET': 'EEType'},
-                                         {'X': 'EConstraint', 'ET': 'EEType'}, {'X': 'EConstraintType', 'ET': 'EEType'},
-                                         {'X': 'EEType', 'ET': 'EEType'}, {'X': 'EFRDef', 'ET': 'EEType'},
-                                         {'X': 'EGroup', 'ET': 'EEType'}, {'X': 'ENFRDef', 'ET': 'EEType'},
-                                         {'X': 'EPermission', 'ET': 'EEType'}, {'X': 'EProperty', 'ET': 'EEType'},
-                                         {'X': 'ERType', 'ET': 'EEType'}, {'X': 'Email', 'ET': 'EEType'},
-                                         {'X': 'EmailAddress', 'ET': 'EEType'}, {'X': 'EmailPart', 'ET': 'EEType'},
-                                         {'X': 'EmailThread', 'ET': 'EEType'}, {'X': 'File', 'ET': 'EEType'},
-                                         {'X': 'Folder', 'ET': 'EEType'}, {'X': 'Image', 'ET': 'EEType'},
-                                         {'X': 'Personne', 'ET': 'EEType'}, {'X': 'RQLExpression', 'ET': 'EEType'},
-                                         {'X': 'Societe', 'ET': 'EEType'}, {'X': 'SubDivision', 'ET': 'EEType'},
-                                         {'X': 'Tag', 'ET': 'EEType'}, {'X': 'TrInfo', 'ET': 'EEType'},
-                                         {'X': 'Transition', 'ET': 'EEType'}])],
+                       [('FetchStep', [('Any ET,X WHERE X is ET, ET is CWEType, X is IN(Bookmark, Comment, Division, CWCache, CWConstraint, CWConstraintType, CWEType, CWAttribute, CWGroup, CWRelation, CWPermission, CWProperty, CWRType, Email, EmailAddress, EmailPart, EmailThread, File, Folder, Image, Personne, RQLExpression, Societe, SubDivision, Tag, TrInfo, Transition)',
+                                        [{'X': 'Bookmark', 'ET': 'CWEType'}, {'X': 'Comment', 'ET': 'CWEType'},
+                                         {'X': 'Division', 'ET': 'CWEType'}, {'X': 'CWCache', 'ET': 'CWEType'},
+                                         {'X': 'CWConstraint', 'ET': 'CWEType'}, {'X': 'CWConstraintType', 'ET': 'CWEType'},
+                                         {'X': 'CWEType', 'ET': 'CWEType'}, {'X': 'CWAttribute', 'ET': 'CWEType'},
+                                         {'X': 'CWGroup', 'ET': 'CWEType'}, {'X': 'CWRelation', 'ET': 'CWEType'},
+                                         {'X': 'CWPermission', 'ET': 'CWEType'}, {'X': 'CWProperty', 'ET': 'CWEType'},
+                                         {'X': 'CWRType', 'ET': 'CWEType'}, {'X': 'Email', 'ET': 'CWEType'},
+                                         {'X': 'EmailAddress', 'ET': 'CWEType'}, {'X': 'EmailPart', 'ET': 'CWEType'},
+                                         {'X': 'EmailThread', 'ET': 'CWEType'}, {'X': 'File', 'ET': 'CWEType'},
+                                         {'X': 'Folder', 'ET': 'CWEType'}, {'X': 'Image', 'ET': 'CWEType'},
+                                         {'X': 'Personne', 'ET': 'CWEType'}, {'X': 'RQLExpression', 'ET': 'CWEType'},
+                                         {'X': 'Societe', 'ET': 'CWEType'}, {'X': 'SubDivision', 'ET': 'CWEType'},
+                                         {'X': 'Tag', 'ET': 'CWEType'}, {'X': 'TrInfo', 'ET': 'CWEType'},
+                                         {'X': 'Transition', 'ET': 'CWEType'}])],
                          [self.system], {}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
                         ('FetchStep',
-                         [('Any ET,X WHERE X is ET, ET is EEType, X is IN(Card, Note, State)',
-                           [{'ET': 'EEType', 'X': 'Card'},
-                            {'ET': 'EEType', 'X': 'Note'},
-                            {'ET': 'EEType', 'X': 'State'}])],
+                         [('Any ET,X WHERE X is ET, ET is CWEType, X is IN(Card, Note, State)',
+                           [{'ET': 'CWEType', 'X': 'Card'},
+                            {'ET': 'CWEType', 'X': 'Note'},
+                            {'ET': 'CWEType', 'X': 'State'}])],
                          [self.system], {'X': 'table1.C0'}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
                         ]),
                     ]),
                     ('OneFetchStep',
                      [('Any ET,COUNT(X) GROUPBY ET ORDERBY ET',
-                       sorted([{'ET': 'EEType', 'X': 'Affaire'}, {'ET': 'EEType', 'X': 'Basket'},
-                               {'ET': 'EEType', 'X': 'Bookmark'}, {'ET': 'EEType', 'X': 'Card'},
-                               {'ET': 'EEType', 'X': 'Comment'}, {'ET': 'EEType', 'X': 'Division'},
-                               {'ET': 'EEType', 'X': 'ECache'}, {'ET': 'EEType', 'X': 'EConstraint'},
-                               {'ET': 'EEType', 'X': 'EConstraintType'}, {'ET': 'EEType', 'X': 'EEType'},
-                               {'ET': 'EEType', 'X': 'EFRDef'}, {'ET': 'EEType', 'X': 'EGroup'},
-                               {'ET': 'EEType', 'X': 'ENFRDef'}, {'ET': 'EEType', 'X': 'EPermission'},
-                               {'ET': 'EEType', 'X': 'EProperty'}, {'ET': 'EEType', 'X': 'ERType'},
-                               {'ET': 'EEType', 'X': 'EUser'}, {'ET': 'EEType', 'X': 'Email'},
-                               {'ET': 'EEType', 'X': 'EmailAddress'}, {'ET': 'EEType', 'X': 'EmailPart'},
-                               {'ET': 'EEType', 'X': 'EmailThread'}, {'ET': 'EEType', 'X': 'File'},
-                               {'ET': 'EEType', 'X': 'Folder'}, {'ET': 'EEType', 'X': 'Image'},
-                               {'ET': 'EEType', 'X': 'Note'}, {'ET': 'EEType', 'X': 'Personne'},
-                               {'ET': 'EEType', 'X': 'RQLExpression'}, {'ET': 'EEType', 'X': 'Societe'},
-                               {'ET': 'EEType', 'X': 'State'}, {'ET': 'EEType', 'X': 'SubDivision'},
-                               {'ET': 'EEType', 'X': 'Tag'}, {'ET': 'EEType', 'X': 'TrInfo'},
-                               {'ET': 'EEType', 'X': 'Transition'}]))],
+                       sorted([{'ET': 'CWEType', 'X': 'Affaire'}, {'ET': 'CWEType', 'X': 'Basket'},
+                               {'ET': 'CWEType', 'X': 'Bookmark'}, {'ET': 'CWEType', 'X': 'Card'},
+                               {'ET': 'CWEType', 'X': 'Comment'}, {'ET': 'CWEType', 'X': 'Division'},
+                               {'ET': 'CWEType', 'X': 'CWCache'}, {'ET': 'CWEType', 'X': 'CWConstraint'},
+                               {'ET': 'CWEType', 'X': 'CWConstraintType'}, {'ET': 'CWEType', 'X': 'CWEType'},
+                               {'ET': 'CWEType', 'X': 'CWAttribute'}, {'ET': 'CWEType', 'X': 'CWGroup'},
+                               {'ET': 'CWEType', 'X': 'CWRelation'}, {'ET': 'CWEType', 'X': 'CWPermission'},
+                               {'ET': 'CWEType', 'X': 'CWProperty'}, {'ET': 'CWEType', 'X': 'CWRType'},
+                               {'ET': 'CWEType', 'X': 'CWUser'}, {'ET': 'CWEType', 'X': 'Email'},
+                               {'ET': 'CWEType', 'X': 'EmailAddress'}, {'ET': 'CWEType', 'X': 'EmailPart'},
+                               {'ET': 'CWEType', 'X': 'EmailThread'}, {'ET': 'CWEType', 'X': 'File'},
+                               {'ET': 'CWEType', 'X': 'Folder'}, {'ET': 'CWEType', 'X': 'Image'},
+                               {'ET': 'CWEType', 'X': 'Note'}, {'ET': 'CWEType', 'X': 'Personne'},
+                               {'ET': 'CWEType', 'X': 'RQLExpression'}, {'ET': 'CWEType', 'X': 'Societe'},
+                               {'ET': 'CWEType', 'X': 'State'}, {'ET': 'CWEType', 'X': 'SubDivision'},
+                               {'ET': 'CWEType', 'X': 'Tag'}, {'ET': 'CWEType', 'X': 'TrInfo'},
+                               {'ET': 'CWEType', 'X': 'Transition'}]))],
                      None, None, [self.system], {'ET': 'table0.C0', 'X': 'table0.C1'}, [])
                     ])
 
@@ -993,11 +993,11 @@
                      [('Any X,XT WHERE X title XT, X is Card', [{'X': 'Card', 'XT': 'String'}])],
                      [self.rql, self.system], None, {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1'}, []),
                     ('FetchStep',
-                     [('Any U WHERE U login "syt", U is EUser', [{'U': 'EUser'}])],
+                     [('Any U WHERE U login "syt", U is CWUser', [{'U': 'CWUser'}])],
                      [self.ldap, self.system], None, {'U': 'table1.C0'}, []),
                     ('OneFetchStep',
-                     [('Any X,XT WHERE X owned_by U, X title XT, EXISTS(U owned_by 5), U is EUser, X is Card',
-                       [{'X': 'Card', 'U': 'EUser', 'XT': 'String'}])],
+                     [('Any X,XT WHERE X owned_by U, X title XT, EXISTS(U owned_by 5), U is CWUser, X is Card',
+                       [{'X': 'Card', 'U': 'CWUser', 'XT': 'String'}])],
                      None, None, [self.system],
                      {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1', 'U': 'table1.C0'}, [])
                     ])
@@ -1011,8 +1011,8 @@
                      [('Any X,XT WHERE X title XT, X is Card', [{'X': 'Card', 'XT': 'String'}])],
                      [self.rql, self.system], None, {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1'}, []),
                     ('OneFetchStep',
-                     [('Any X,XT WHERE X owned_by U, X title XT, U login "syt", EXISTS(U identity 5), U is EUser, X is Card',
-                       [{'U': 'EUser', 'X': 'Card', 'XT': 'String'}])],
+                     [('Any X,XT WHERE X owned_by U, X title XT, U login "syt", EXISTS(U identity 5), U is CWUser, X is Card',
+                       [{'U': 'CWUser', 'X': 'Card', 'XT': 'String'}])],
                      None, None, [self.system], {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1'}, [])
                     ])
 
@@ -1022,8 +1022,8 @@
         self.session = self._user_session()[1]
         self._test('Any X,XT,U WHERE X is Card, X owned_by U?, X title XT, U login L',
                    [('FetchStep',
-                     [('Any U,L WHERE U identity 5, U login L, U is EUser',
-                       [{'L': 'String', u'U': 'EUser'}])],
+                     [('Any U,L WHERE U identity 5, U login L, U is CWUser',
+                       [{'L': 'String', u'U': 'CWUser'}])],
                      [self.system], {}, {'L': 'table0.C1', 'U': 'table0.C0', 'U.login': 'table0.C1'}, []),
                     ('FetchStep',
                      [('Any X,XT WHERE X title XT, X is Card', [{'X': 'Card', 'XT': 'String'}])],
@@ -1046,47 +1046,47 @@
                      [('Any X,XT WHERE X title XT, X is Card', [{'X': 'Card', 'XT': 'String'}])],
                      [self.rql, self.system], None, {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1'}, []),
                     ('FetchStep',
-                     [('Any U WHERE U login "syt", U is EUser', [{'U': 'EUser'}])],
+                     [('Any U WHERE U login "syt", U is CWUser', [{'U': 'CWUser'}])],
                      [self.ldap, self.system], None, {'U': 'table1.C0'}, []),
                     ('OneFetchStep',
-                     [('Any X,XT LIMIT 10 OFFSET 10 WHERE X owned_by U, X title XT, EXISTS(U owned_by 5), U is EUser, X is Card',
-                       [{'X': 'Card', 'U': 'EUser', 'XT': 'String'}])],
+                     [('Any X,XT LIMIT 10 OFFSET 10 WHERE X owned_by U, X title XT, EXISTS(U owned_by 5), U is CWUser, X is Card',
+                       [{'X': 'Card', 'U': 'CWUser', 'XT': 'String'}])],
                      10, 10, [self.system],
                      {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1', 'U': 'table1.C0'}, [])
                     ])
     
     def test_exists_base(self):
         self._test('Any X,L,S WHERE X in_state S, X login L, EXISTS(X in_group G, G name "bougloup")',
-                   [('FetchStep', [('Any X,L WHERE X login L, X is EUser', [{'X': 'EUser', 'L': 'String'}])],
+                   [('FetchStep', [('Any X,L WHERE X login L, X is CWUser', [{'X': 'CWUser', 'L': 'String'}])],
                      [self.ldap, self.system], None, {'X': 'table0.C0', 'X.login': 'table0.C1', 'L': 'table0.C1'}, []),
                     ('OneFetchStep', [("Any X,L,S WHERE X in_state S, X login L, "
-                                      'EXISTS(X in_group G, G name "bougloup", G is EGroup), S is State, X is EUser',
-                                       [{'X': 'EUser', 'L': 'String', 'S': 'State', 'G': 'EGroup'}])],
+                                      'EXISTS(X in_group G, G name "bougloup", G is CWGroup), S is State, X is CWUser',
+                                       [{'X': 'CWUser', 'L': 'String', 'S': 'State', 'G': 'CWGroup'}])],
                      None, None, [self.system],
                      {'X': 'table0.C0', 'X.login': 'table0.C1', 'L': 'table0.C1'}, [])])
 
     def test_exists_complex(self):
         self._test('Any G WHERE X in_group G, G name "managers", EXISTS(X copain T, T login in ("comme", "cochon"))',
-                   [('FetchStep', [('Any T WHERE T login IN("comme", "cochon"), T is EUser', [{'T': 'EUser'}])],
+                   [('FetchStep', [('Any T WHERE T login IN("comme", "cochon"), T is CWUser', [{'T': 'CWUser'}])],
                      [self.ldap, self.system], None, {'T': 'table0.C0'}, []),
                     ('OneFetchStep',
-                     [('Any G WHERE X in_group G, G name "managers", EXISTS(X copain T, T is EUser), G is EGroup, X is EUser',
-                       [{'X': 'EUser', 'T': 'EUser', 'G': 'EGroup'}])],
+                     [('Any G WHERE X in_group G, G name "managers", EXISTS(X copain T, T is CWUser), G is CWGroup, X is CWUser',
+                       [{'X': 'CWUser', 'T': 'CWUser', 'G': 'CWGroup'}])],
                      None, None, [self.system], {'T': 'table0.C0'}, [])])
 
     def test_exists3(self):
         self._test('Any G,L WHERE X in_group G, X login L, G name "managers", EXISTS(X copain T, T login in ("comme", "cochon"))',
                    [('FetchStep',
-                     [('Any T WHERE T login IN("comme", "cochon"), T is EUser',
-                       [{'T': 'EUser'}])],
+                     [('Any T WHERE T login IN("comme", "cochon"), T is CWUser',
+                       [{'T': 'CWUser'}])],
                      [self.ldap, self.system], None, {'T': 'table0.C0'}, []),
                     ('FetchStep',
-                     [('Any L,X WHERE X login L, X is EUser', [{'X': 'EUser', 'L': 'String'}])],
+                     [('Any L,X WHERE X login L, X is CWUser', [{'X': 'CWUser', 'L': 'String'}])],
                      [self.ldap, self.system], None,
                      {'X': 'table1.C1', 'X.login': 'table1.C0', 'L': 'table1.C0'}, []),
                     ('OneFetchStep',
-                     [('Any G,L WHERE X in_group G, X login L, G name "managers", EXISTS(X copain T, T is EUser), G is EGroup, X is EUser',
-                       [{'G': 'EGroup', 'L': 'String', 'T': 'EUser', 'X': 'EUser'}])],
+                     [('Any G,L WHERE X in_group G, X login L, G name "managers", EXISTS(X copain T, T is CWUser), G is CWGroup, X is CWUser',
+                       [{'G': 'CWGroup', 'L': 'String', 'T': 'CWUser', 'X': 'CWUser'}])],
                      None, None,
                      [self.system], {'T': 'table0.C0', 'X': 'table1.C1', 'X.login': 'table1.C0', 'L': 'table1.C0'}, [])])
 
@@ -1095,18 +1095,18 @@
                    'EXISTS(X copain T, T login L, T login in ("comme", "cochon")) OR '
                    'EXISTS(X in_state S, S name "pascontent", NOT X copain T2, T2 login "billy")',
                    [('FetchStep',
-                     [('Any T,L WHERE T login L, T login IN("comme", "cochon"), T is EUser', [{'T': 'EUser', 'L': 'String'}])],
+                     [('Any T,L WHERE T login L, T login IN("comme", "cochon"), T is CWUser', [{'T': 'CWUser', 'L': 'String'}])],
                      [self.ldap, self.system], None,
                      {'T': 'table0.C0', 'T.login': 'table0.C1', 'L': 'table0.C1'}, []),
                     ('FetchStep',
-                     [('Any T2 WHERE T2 login "billy", T2 is EUser', [{'T2': 'EUser'}])],
+                     [('Any T2 WHERE T2 login "billy", T2 is CWUser', [{'T2': 'CWUser'}])],
                      [self.ldap, self.system], None, {'T2': 'table1.C0'}, []),
                     ('FetchStep',
-                     [('Any L,X WHERE X login L, X is EUser', [{'X': 'EUser', 'L': 'String'}])],
+                     [('Any L,X WHERE X login L, X is CWUser', [{'X': 'CWUser', 'L': 'String'}])],
                      [self.ldap, self.system], None, {'X': 'table2.C1', 'X.login': 'table2.C0', 'L': 'table2.C0'}, []),
                     ('OneFetchStep',
-                     [('Any G,L WHERE X in_group G, X login L, G name "managers", (EXISTS(X copain T, T login L, T is EUser)) OR (EXISTS(X in_state S, S name "pascontent", NOT X copain T2, S is State, T2 is EUser)), G is EGroup, X is EUser',
-                       [{'G': 'EGroup', 'L': 'String', 'S': 'State', 'T': 'EUser', 'T2': 'EUser', 'X': 'EUser'}])],
+                     [('Any G,L WHERE X in_group G, X login L, G name "managers", (EXISTS(X copain T, T login L, T is CWUser)) OR (EXISTS(X in_state S, S name "pascontent", NOT X copain T2, S is State, T2 is CWUser)), G is CWGroup, X is CWUser',
+                       [{'G': 'CWGroup', 'L': 'String', 'S': 'State', 'T': 'CWUser', 'T2': 'CWUser', 'X': 'CWUser'}])],
                      None, None, [self.system],
                      {'T2': 'table1.C0', 'L': 'table2.C0',
                       'T': 'table0.C0', 'T.login': 'table0.C1', 'X': 'table2.C1', 'X.login': 'table2.C0'}, [])])
@@ -1115,29 +1115,29 @@
         self._test('Any GN,L WHERE X in_group G, X login L, G name GN, '
                    'EXISTS(X copain T, T login in ("comme", "cochon")) AND '
                    'NOT EXISTS(X copain T2, T2 login "billy")',
-                   [('FetchStep', [('Any T WHERE T login IN("comme", "cochon"), T is EUser',
-                                    [{'T': 'EUser'}])],
+                   [('FetchStep', [('Any T WHERE T login IN("comme", "cochon"), T is CWUser',
+                                    [{'T': 'CWUser'}])],
                      [self.ldap, self.system], None, {'T': 'table0.C0'}, []),
-                    ('FetchStep', [('Any T2 WHERE T2 login "billy", T2 is EUser', [{'T2': 'EUser'}])],
+                    ('FetchStep', [('Any T2 WHERE T2 login "billy", T2 is CWUser', [{'T2': 'CWUser'}])],
                      [self.ldap, self.system], None, {'T2': 'table1.C0'}, []),
-                    ('FetchStep', [('Any L,X WHERE X login L, X is EUser', [{'X': 'EUser', 'L': 'String'}])],
+                    ('FetchStep', [('Any L,X WHERE X login L, X is CWUser', [{'X': 'CWUser', 'L': 'String'}])],
                      [self.ldap, self.system], None,
                      {'X': 'table2.C1', 'X.login': 'table2.C0', 'L': 'table2.C0'}, []),
-                    ('OneFetchStep', [('Any GN,L WHERE X in_group G, X login L, G name GN, EXISTS(X copain T, T is EUser), NOT EXISTS(X copain T2, T2 is EUser), G is EGroup, X is EUser',
-                       [{'G': 'EGroup', 'GN': 'String', 'L': 'String', 'T': 'EUser', 'T2': 'EUser', 'X': 'EUser'}])],
+                    ('OneFetchStep', [('Any GN,L WHERE X in_group G, X login L, G name GN, EXISTS(X copain T, T is CWUser), NOT EXISTS(X copain T2, T2 is CWUser), G is CWGroup, X is CWUser',
+                       [{'G': 'CWGroup', 'GN': 'String', 'L': 'String', 'T': 'CWUser', 'T2': 'CWUser', 'X': 'CWUser'}])],
                      None, None, [self.system],
                      {'T': 'table0.C0', 'T2': 'table1.C0',
                       'X': 'table2.C1', 'X.login': 'table2.C0', 'L': 'table2.C0'}, [])])
             
     def test_exists_security_no_invariant(self):
         ueid = self.session.user.eid
-        self._test('Any X,AA,AB,AC,AD ORDERBY AA WHERE X is EUser, X login AA, X firstname AB, X surname AC, X modification_date AD, A eid %(B)s, \
+        self._test('Any X,AA,AB,AC,AD ORDERBY AA WHERE X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, A eid %(B)s, \
     EXISTS(((X identity A) OR \
-            (EXISTS(X in_group C, C name IN("managers", "staff"), C is EGroup))) OR \
-            (EXISTS(X in_group D, A in_group D, NOT D name "users", D is EGroup)))',
-               [('FetchStep', [('Any X,AA,AB,AC,AD WHERE X login AA, X firstname AB, X surname AC, X modification_date AD, X is EUser',
+            (EXISTS(X in_group C, C name IN("managers", "staff"), C is CWGroup))) OR \
+            (EXISTS(X in_group D, A in_group D, NOT D name "users", D is CWGroup)))',
+               [('FetchStep', [('Any X,AA,AB,AC,AD WHERE X login AA, X firstname AB, X surname AC, X modification_date AD, X is CWUser',
                                 [{'AA': 'String', 'AB': 'String', 'AC': 'String', 'AD': 'Datetime',
-                                  'X': 'EUser'}])],
+                                  'X': 'CWUser'}])],
                  [self.ldap, self.system], None, {'AA': 'table0.C1', 'AB': 'table0.C2',
                                                   'AC': 'table0.C3', 'AD': 'table0.C4',
                                                   'X': 'table0.C0',
@@ -1145,9 +1145,9 @@
                                                   'X.login': 'table0.C1',
                                                   'X.modification_date': 'table0.C4',
                                                   'X.surname': 'table0.C3'}, []),
-                ('OneFetchStep', [('Any X,AA,AB,AC,AD ORDERBY AA WHERE X login AA, X firstname AB, X surname AC, X modification_date AD, EXISTS(((X identity 5) OR (EXISTS(X in_group C, C name IN("managers", "staff"), C is EGroup))) OR (EXISTS(X in_group D, 5 in_group D, NOT D name "users", D is EGroup))), X is EUser',
+                ('OneFetchStep', [('Any X,AA,AB,AC,AD ORDERBY AA WHERE X login AA, X firstname AB, X surname AC, X modification_date AD, EXISTS(((X identity 5) OR (EXISTS(X in_group C, C name IN("managers", "staff"), C is CWGroup))) OR (EXISTS(X in_group D, 5 in_group D, NOT D name "users", D is CWGroup))), X is CWUser',
                                    [{'AA': 'String', 'AB': 'String', 'AC': 'String', 'AD': 'Datetime',
-                                     'C': 'EGroup', 'D': 'EGroup', 'X': 'EUser'}])],
+                                     'C': 'CWGroup', 'D': 'CWGroup', 'X': 'CWUser'}])],
                  None, None, [self.system],
                  {'AA': 'table0.C1', 'AB': 'table0.C2', 'AC': 'table0.C3', 'AD': 'table0.C4',
                   'X': 'table0.C0',
@@ -1158,8 +1158,8 @@
     def test_relation_need_split(self):
         self._test('Any X, S WHERE X in_state S',
                    [('UnionStep', None, None, [
-                       ('OneFetchStep', [('Any X,S WHERE X in_state S, S is State, X is IN(Affaire, EUser)',
-                                          [{'X': 'Affaire', 'S': 'State'}, {'X': 'EUser', 'S': 'State'}])], 
+                       ('OneFetchStep', [('Any X,S WHERE X in_state S, S is State, X is IN(Affaire, CWUser)',
+                                          [{'X': 'Affaire', 'S': 'State'}, {'X': 'CWUser', 'S': 'State'}])], 
                         None, None, [self.system], {}, []),
                        ('OneFetchStep', [('Any X,S WHERE X in_state S, S is State, X is Note',
                                           [{'X': 'Note', 'S': 'State'}])], 
@@ -1172,8 +1172,8 @@
                                     [{'X': 'Note', 'S': 'State'}])],
                      [self.rql, self.system], None, {'X': 'table0.C0', 'S': 'table0.C1'}, []),
                      ('UnionStep', None, None,
-                      [('OneFetchStep', [('Any X,S,U WHERE X in_state S, X todo_by U, S is State, U is EUser, X is Note',
-                                          [{'X': 'Note', 'S': 'State', 'U': 'EUser'}])],
+                      [('OneFetchStep', [('Any X,S,U WHERE X in_state S, X todo_by U, S is State, U is CWUser, X is Note',
+                                          [{'X': 'Note', 'S': 'State', 'U': 'CWUser'}])],
                         None, None, [self.system], {'X': 'table0.C0', 'S': 'table0.C1'}, []),
                        ('OneFetchStep', [('Any X,S,U WHERE X in_state S, X todo_by U, S is State, U is Personne, X is Affaire',
                                           [{'X': 'Affaire', 'S': 'State', 'U': 'Personne'}])],
@@ -1187,8 +1187,8 @@
                                     [{'X': 'Note', 'S': 'State'}])],
                      [self.rql, self.system], None, {'X': 'table0.C0'}, []),
                      ('UnionStep', None, None,
-                      [('OneFetchStep', [('Any X,U WHERE X todo_by U, U is EUser, X is Note',
-                                          [{'X': 'Note', 'U': 'EUser'}])],
+                      [('OneFetchStep', [('Any X,U WHERE X todo_by U, U is CWUser, X is Note',
+                                          [{'X': 'Note', 'U': 'CWUser'}])],
                         None, None, [self.system], {'X': 'table0.C0'}, []),
                        ('OneFetchStep', [('Any X,U WHERE X in_state S, S name "pending", X todo_by U, S is State, U is Personne, X is Affaire',
                                           [{'S': 'State', 'U': 'Personne', 'X': 'Affaire'}])],
@@ -1206,9 +1206,9 @@
                                            [{'X': 'Note', 'T': 'Tag'}])],
                          None, None,
                          [self.system], {'X': 'table0.C0'}, []),
-                        ('OneFetchStep', [('Any X,T WHERE X in_state S, S name "pending", T tags X, S is State, T is Tag, X is IN(Affaire, EUser)',
+                        ('OneFetchStep', [('Any X,T WHERE X in_state S, S name "pending", T tags X, S is State, T is Tag, X is IN(Affaire, CWUser)',
                                            [{'X': 'Affaire', 'S': 'State', 'T': 'Tag'},
-                                            {'X': 'EUser', 'S': 'State', 'T': 'Tag'}])],
+                                            {'X': 'CWUser', 'S': 'State', 'T': 'Tag'}])],
                          None, None,
                          [self.system], {}, []),
                         ])
@@ -1251,9 +1251,9 @@
                        None, None, [self.rql, self.system], {},
                        []),
                       ('OneFetchStep',
-                       [('Any SN WHERE NOT X in_state S, S name SN, S is State, X is IN(Affaire, EUser)',
+                       [('Any SN WHERE NOT X in_state S, S name SN, S is State, X is IN(Affaire, CWUser)',
                          [{'S': 'State', 'SN': 'String', 'X': 'Affaire'},
-                          {'S': 'State', 'SN': 'String', 'X': 'EUser'}])],
+                          {'S': 'State', 'SN': 'String', 'X': 'CWUser'}])],
                        None, None, [self.system], {'S': 'table0.C1', 'S.name': 'table0.C0', 'SN': 'table0.C0'},
                        []),]
                      )])
@@ -1265,10 +1265,10 @@
                                     [{'A': 'Note', 'C': 'Datetime', 'B': 'Datetime'}])],
                      [self.rql], None,
                      {'A': 'table0.C0', 'A.creation_date': 'table0.C1', 'A.modification_date': 'table0.C2', 'C': 'table0.C2', 'B': 'table0.C1'}, []),
-                    #('FetchStep', [('Any D WHERE D is EUser', [{'D': 'EUser'}])],
+                    #('FetchStep', [('Any D WHERE D is CWUser', [{'D': 'CWUser'}])],
                     # [self.ldap, self.system], None, {'D': 'table1.C0'}, []),
-                    ('OneFetchStep', [('Any A,B,C,D WHERE A creation_date B, A modification_date C, A todo_by D?, A is Note, D is EUser',
-                                       [{'A': 'Note', 'C': 'Datetime', 'B': 'Datetime', 'D': 'EUser'}])],
+                    ('OneFetchStep', [('Any A,B,C,D WHERE A creation_date B, A modification_date C, A todo_by D?, A is Note, D is CWUser',
+                                       [{'A': 'Note', 'C': 'Datetime', 'B': 'Datetime', 'D': 'CWUser'}])],
                      None, None, [self.system],
                      {'A': 'table0.C0', 'A.creation_date': 'table0.C1', 'A.modification_date': 'table0.C2', 'C': 'table0.C2', 'B': 'table0.C1'}, [])],
                    {'x': 999999})
@@ -1278,7 +1278,7 @@
         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
         self._test('Any U WHERE U in_group G, (G name IN ("managers", "logilab") OR (X require_permission P?, P name "bla", P require_group G)), X eid %(x)s, U eid %(u)s',
                    [('OneFetchStep', [('Any 5 WHERE 5 in_group G, (G name IN("managers", "logilab")) OR (X require_permission P?, P name "bla", P require_group G), X eid 999999',
-                                       [{'X': 'Note', 'G': 'EGroup', 'P': 'EPermission'}])],
+                                       [{'X': 'Note', 'G': 'CWGroup', 'P': 'CWPermission'}])],
                      None, None, [self.system], {}, [])],
                    {'x': 999999, 'u': self.session.user.eid})
 
@@ -1382,11 +1382,11 @@
                                     [{'T': 'String', 'X': 'Bookmark'}])],
                      [self.system], {}, {'N': 'table0.C1', 'X': 'table0.C0', 'X.name': 'table0.C1'}, []),
                     ('FetchStep',
-                     [('Any B,C WHERE B login C, B is EUser', [{'B': 'EUser', 'C': 'String'}])],
+                     [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])],
                      [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []),
-                    ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is EUser',
-                                       [{'A': 'Bookmark', 'B': 'EUser', 'C': 'String'},
-                                        {'A': 'Tag', 'B': 'EUser', 'C': 'String'}])],
+                    ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser',
+                                       [{'A': 'Bookmark', 'B': 'CWUser', 'C': 'String'},
+                                        {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])],
                      None, None, [self.system],
                      {'A': 'table0.C0',
                       'B': 'table1.C0', 'B.login': 'table1.C1',
@@ -1416,11 +1416,11 @@
                         'X.title': 'table0.C1'}, []),
                       ]),
                     ('FetchStep',
-                     [('Any B,C WHERE B login C, B is EUser', [{'B': 'EUser', 'C': 'String'}])],
+                     [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])],
                      [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []),
-                    ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is EUser',
-                                       [{'A': 'Card', 'B': 'EUser', 'C': 'String'},
-                                        {'A': 'Tag', 'B': 'EUser', 'C': 'String'}])],
+                    ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser',
+                                       [{'A': 'Card', 'B': 'CWUser', 'C': 'String'},
+                                        {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])],
                      None, None, [self.system],
                      {'A': 'table0.C0',
                       'B': 'table1.C0', 'B.login': 'table1.C1',
@@ -1607,8 +1607,8 @@
         ueid = self.session.user.eid
         self._test('DELETE X created_by Y WHERE X eid %(x)s, NOT Y eid %(y)s',
                    [('DeleteRelationsStep', [
-                       ('OneFetchStep', [('Any 5,Y WHERE %s created_by Y, NOT Y eid %s, Y is EUser'%(ueid, ueid),
-                                          [{'Y': 'EUser'}])],
+                       ('OneFetchStep', [('Any 5,Y WHERE %s created_by Y, NOT Y eid %s, Y is CWUser'%(ueid, ueid),
+                                          [{'Y': 'CWUser'}])],
                         None, None, [self.system], {}, []),
                        ]),
                     ],
@@ -1617,10 +1617,10 @@
     def test_delete_relation2(self):
         ueid = self.session.user.eid
         self._test('DELETE X created_by Y WHERE X eid %(x)s, NOT Y login "syt"',
-                   [('FetchStep', [('Any Y WHERE NOT Y login "syt", Y is EUser', [{'Y': 'EUser'}])],
+                   [('FetchStep', [('Any Y WHERE NOT Y login "syt", Y is CWUser', [{'Y': 'CWUser'}])],
                      [self.ldap, self.system], None, {'Y': 'table0.C0'}, []),
                     ('DeleteRelationsStep', [
-                        ('OneFetchStep', [('Any %s,Y WHERE %s created_by Y, Y is EUser'%(ueid,ueid), [{'Y': 'EUser'}])],
+                        ('OneFetchStep', [('Any %s,Y WHERE %s created_by Y, Y is CWUser'%(ueid,ueid), [{'Y': 'CWUser'}])],
                          None, None, [self.system], {'Y': 'table0.C0'}, []),
                         ]),
                     ],
@@ -1651,26 +1651,26 @@
     def test_update(self):
         self._test('SET X copain Y WHERE X login "comme", Y login "cochon"',
                    [('FetchStep',
-                     [('Any X WHERE X login "comme", X is EUser', [{'X': 'EUser'}])],
+                     [('Any X WHERE X login "comme", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table0.C0'}, []),
                     ('FetchStep',
-                     [('Any Y WHERE Y login "cochon", Y is EUser', [{'Y': 'EUser'}])],
+                     [('Any Y WHERE Y login "cochon", Y is CWUser', [{'Y': 'CWUser'}])],
                      [self.ldap, self.system], None, {'Y': 'table1.C0'}, []),
                     ('UpdateStep',
                      [('OneFetchStep',
-                       [('DISTINCT Any X,Y WHERE X is EUser, Y is EUser',
-                         [{'X': 'EUser', 'Y': 'EUser'}])],
+                       [('DISTINCT Any X,Y WHERE X is CWUser, Y is CWUser',
+                         [{'X': 'CWUser', 'Y': 'CWUser'}])],
                        None, None, [self.system], {'X': 'table0.C0', 'Y': 'table1.C0'}, [])
                       ])
                     ])
 
     def test_update2(self):
         self._test('SET U in_group G WHERE G name ~= "bougloup%", U login "admin"',
-                   [('FetchStep', [('Any U WHERE U login "admin", U is EUser', [{'U': 'EUser'}])],
+                   [('FetchStep', [('Any U WHERE U login "admin", U is CWUser', [{'U': 'CWUser'}])],
                      [self.ldap, self.system], None, {'U': 'table0.C0'}, []),
                      ('UpdateStep', [
-                        ('OneFetchStep', [('DISTINCT Any U,G WHERE G name ILIKE "bougloup%", G is EGroup, U is EUser',
-                                           [{'U': 'EUser', 'G': 'EGroup'}])],
+                        ('OneFetchStep', [('DISTINCT Any U,G WHERE G name ILIKE "bougloup%", G is CWGroup, U is CWUser',
+                                           [{'U': 'CWUser', 'G': 'CWGroup'}])],
                          None, None, [self.system], {'U': 'table0.C0'}, []),
                         ]),
                     ])
@@ -1690,14 +1690,14 @@
 
 #     def test_update4(self):
 #         # since we are adding a in_state relation with a state from the system
-#         # source, EUser should only be searched only in the system source as well
+#         # source, CWUser should only be searched only in the system source as well
 #         rset = self.execute('State X WHERE X name "activated"')
 #         assert len(rset) == 1, rset
 #         activatedeid = rset[0][0]
-#         self._test('SET X in_state S WHERE X is EUser, S eid %s' % activatedeid,
+#         self._test('SET X in_state S WHERE X is CWUser, S eid %s' % activatedeid,
 #                    [('UpdateStep', [
-#                        ('OneFetchStep', [('DISTINCT Any X,%s WHERE X is EUser' % activatedeid,
-#                                           [{'X': 'EUser'}])],
+#                        ('OneFetchStep', [('DISTINCT Any X,%s WHERE X is CWUser' % activatedeid,
+#                                           [{'X': 'CWUser'}])],
 #                         None, None, [self.system], {}, []),
 #                        ]),
 #                     ])
@@ -1707,14 +1707,14 @@
     def test_nonregr1(self):
         self._test('Any X, Y WHERE X copain Y, X login "syt", Y login "cochon"',
                    [('FetchStep',
-                     [('Any X WHERE X login "syt", X is EUser', [{'X': 'EUser'}])],
+                     [('Any X WHERE X login "syt", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table0.C0'}, []),
                     ('FetchStep',
-                     [('Any Y WHERE Y login "cochon", Y is EUser', [{'Y': 'EUser'}])],
+                     [('Any Y WHERE Y login "cochon", Y is CWUser', [{'Y': 'CWUser'}])],
                      [self.ldap, self.system], None, {'Y': 'table1.C0'}, []),
                     ('OneFetchStep',
-                     [('Any X,Y WHERE X copain Y, X is EUser, Y is EUser',
-                       [{'X': 'EUser', 'Y': 'EUser'}])],
+                     [('Any X,Y WHERE X copain Y, X is CWUser, Y is CWUser',
+                       [{'X': 'CWUser', 'Y': 'CWUser'}])],
                      None, None, [self.system], {'X': 'table0.C0', 'Y': 'table1.C0'}, [])
                     ])
     
@@ -1724,8 +1724,8 @@
                    [('FetchStep', [('Any X,D WHERE X modification_date D, X is Note',
                                     [{'X': 'Note', 'D': 'Datetime'}])],
                      [self.rql, self.system], None, {'X': 'table0.C0', 'X.modification_date': 'table0.C1', 'D': 'table0.C1'}, []),
-                    ('FetchStep', [('Any X,D WHERE X modification_date D, X is EUser',
-                                    [{'X': 'EUser', 'D': 'Datetime'}])],
+                    ('FetchStep', [('Any X,D WHERE X modification_date D, X is CWUser',
+                                    [{'X': 'CWUser', 'D': 'Datetime'}])],
                      [self.ldap, self.system], None, {'X': 'table1.C0', 'X.modification_date': 'table1.C1', 'D': 'table1.C1'}, []),
                     ('AggrStep', 'Any X ORDERBY D DESC', None, None, 'table2', None, [
                         ('FetchStep', [('Any X,D WHERE E eid %s, E wf_info_for X, X modification_date D, E is TrInfo, X is Affaire'%treid,
@@ -1733,8 +1733,8 @@
                          [self.system],
                          {},
                          {'X': 'table2.C0', 'X.modification_date': 'table2.C1', 'D': 'table2.C1', 'E.wf_info_for': 'table2.C0'}, []),
-                        ('FetchStep', [('Any X,D WHERE E eid %s, E wf_info_for X, X modification_date D, E is TrInfo, X is EUser'%treid,
-                                        [{'X': 'EUser', 'E': 'TrInfo', 'D': 'Datetime'}])],
+                        ('FetchStep', [('Any X,D WHERE E eid %s, E wf_info_for X, X modification_date D, E is TrInfo, X is CWUser'%treid,
+                                        [{'X': 'CWUser', 'E': 'TrInfo', 'D': 'Datetime'}])],
                          [self.system],
                          {'X': 'table1.C0', 'X.modification_date': 'table1.C1', 'D': 'table1.C1'},
                          {'X': 'table2.C0', 'X.modification_date': 'table2.C1', 'D': 'table2.C1', 'E.wf_info_for': 'table2.C0'}, []),
@@ -1749,22 +1749,22 @@
         
     def test_nonregr3(self):
         # original jpl query:
-        # Any X, NOW - CD, P WHERE P is Project, U interested_in P, U is EUser, U login "sthenault", X concerns P, X creation_date CD ORDERBY CD DESC LIMIT 5
+        # Any X, NOW - CD, P WHERE P is Project, U interested_in P, U is CWUser, U login "sthenault", X concerns P, X creation_date CD ORDERBY CD DESC LIMIT 5
         self._test('Any X, NOW - CD, P ORDERBY CD DESC LIMIT 5 WHERE P bookmarked_by U, U login "admin", P is X, X creation_date CD',
-                   [('FetchStep', [('Any U WHERE U login "admin", U is EUser', [{'U': 'EUser'}])],
+                   [('FetchStep', [('Any U WHERE U login "admin", U is CWUser', [{'U': 'CWUser'}])],
                      [self.ldap, self.system], None, {'U': 'table0.C0'}, []),
-                    ('OneFetchStep', [('Any X,(NOW - CD),P ORDERBY CD DESC LIMIT 5 WHERE P bookmarked_by U, P is X, X creation_date CD, P is Bookmark, U is EUser, X is EEType',
-                                       [{'P': 'Bookmark', 'U': 'EUser', 'X': 'EEType', 'CD': 'Datetime'}])],
+                    ('OneFetchStep', [('Any X,(NOW - CD),P ORDERBY CD DESC LIMIT 5 WHERE P bookmarked_by U, P is X, X creation_date CD, P is Bookmark, U is CWUser, X is CWEType',
+                                       [{'P': 'Bookmark', 'U': 'CWUser', 'X': 'CWEType', 'CD': 'Datetime'}])],
                      5, None,  [self.system], {'U': 'table0.C0'}, [])]
                    )
         
     def test_nonregr4(self):
         self._test('Any U ORDERBY D DESC WHERE WF wf_info_for X, WF creation_date D, WF from_state FS, '
                    'WF owned_by U?, X eid %(x)s',
-                   [#('FetchStep', [('Any U WHERE U is EUser', [{'U': 'EUser'}])],
+                   [#('FetchStep', [('Any U WHERE U is CWUser', [{'U': 'CWUser'}])],
                     # [self.ldap, self.system], None, {'U': 'table0.C0'}, []),
                     ('OneFetchStep', [('Any U ORDERBY D DESC WHERE WF wf_info_for 5, WF creation_date D, WF from_state FS, WF owned_by U?',
-                                       [{'WF': 'TrInfo', 'FS': 'State', 'U': 'EUser', 'D': 'Datetime'}])],
+                                       [{'WF': 'TrInfo', 'FS': 'State', 'U': 'CWUser', 'D': 'Datetime'}])],
                      None, None,
                      [self.system], {}, [])],
                    {'x': self.session.user.eid})
@@ -1837,17 +1837,17 @@
                    {'x': 999999, 'z': 999998})
 
     def test_nonregr10(self):
-        repo._type_source_cache[999999] = ('EUser', 'ldapuser', 999999)
+        repo._type_source_cache[999999] = ('CWUser', 'ldapuser', 999999)
         self._test('Any X,AA,AB ORDERBY AA WHERE E eid %(x)s, E owned_by X, X login AA, X modification_date AB',
                    [('FetchStep',
-                     [('Any X,AA,AB WHERE X login AA, X modification_date AB, X is EUser',
-                       [{'AA': 'String', 'AB': 'Datetime', 'X': 'EUser'}])],
+                     [('Any X,AA,AB WHERE X login AA, X modification_date AB, X is CWUser',
+                       [{'AA': 'String', 'AB': 'Datetime', 'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'AA': 'table0.C1', 'AB': 'table0.C2',
                                                       'X': 'table0.C0', 'X.login': 'table0.C1', 'X.modification_date': 'table0.C2'},
                      []),
                     ('OneFetchStep',
-                     [('Any X,AA,AB ORDERBY AA WHERE 999999 owned_by X, X login AA, X modification_date AB, X is EUser',
-                       [{'AA': 'String', 'AB': 'Datetime', 'X': 'EUser'}])],
+                     [('Any X,AA,AB ORDERBY AA WHERE 999999 owned_by X, X login AA, X modification_date AB, X is CWUser',
+                       [{'AA': 'String', 'AB': 'Datetime', 'X': 'CWUser'}])],
                      None, None, [self.system], {'AA': 'table0.C1', 'AB': 'table0.C2',
                                                  'X': 'table0.C0', 'X.login': 'table0.C1', 'X.modification_date': 'table0.C2'},
                      [])
@@ -1858,11 +1858,11 @@
         repo._type_source_cache[999999] = ('Bookmark', 'system', 999999)
         self._test('SET X bookmarked_by Y WHERE X eid %(x)s, Y login "hop"',
                    [('FetchStep',
-                     [('Any Y WHERE Y login "hop", Y is EUser', [{'Y': 'EUser'}])],
+                     [('Any Y WHERE Y login "hop", Y is CWUser', [{'Y': 'CWUser'}])],
                      [self.ldap, self.system],
                      None, {'Y': 'table0.C0'}, []),
                     ('UpdateStep',
-                     [('OneFetchStep', [('DISTINCT Any 999999,Y WHERE Y is EUser', [{'Y': 'EUser'}])],
+                     [('OneFetchStep', [('DISTINCT Any 999999,Y WHERE Y is CWUser', [{'Y': 'CWUser'}])],
                        None, None, [self.system], {'Y': 'table0.C0'},
                        [])]
                      )],
@@ -1898,20 +1898,20 @@
         self._test('Any B,U,UL GROUPBY B,U,UL WHERE B created_by U?, B is File '
                    'WITH U,UL BEING (Any U,UL WHERE ME eid %(x)s, (EXISTS(U identity ME) '
                    'OR (EXISTS(U in_group G, G name IN("managers", "staff")))) '
-                   'OR (EXISTS(U in_group H, ME in_group H, NOT H name "users")), U login UL, U is EUser)',
-                   [('FetchStep', [('Any U,UL WHERE U login UL, U is EUser',
-                                    [{'U': 'EUser', 'UL': 'String'}])],
+                   'OR (EXISTS(U in_group H, ME in_group H, NOT H name "users")), U login UL, U is CWUser)',
+                   [('FetchStep', [('Any U,UL WHERE U login UL, U is CWUser',
+                                    [{'U': 'CWUser', 'UL': 'String'}])],
                      [self.ldap, self.system], None,
                      {'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
                      []),
-                    ('FetchStep', [('Any U,UL WHERE ((EXISTS(U identity 5)) OR (EXISTS(U in_group G, G name IN("managers", "staff"), G is EGroup))) OR (EXISTS(U in_group H, 5 in_group H, NOT H name "users", H is EGroup)), U login UL, U is EUser',
-                                    [{'G': 'EGroup', 'H': 'EGroup', 'U': 'EUser', 'UL': 'String'}])],
+                    ('FetchStep', [('Any U,UL WHERE ((EXISTS(U identity 5)) OR (EXISTS(U in_group G, G name IN("managers", "staff"), G is CWGroup))) OR (EXISTS(U in_group H, 5 in_group H, NOT H name "users", H is CWGroup)), U login UL, U is CWUser',
+                                    [{'G': 'CWGroup', 'H': 'CWGroup', 'U': 'CWUser', 'UL': 'String'}])],
                      [self.system],
                      {'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
                      {'U': 'table1.C0', 'U.login': 'table1.C1', 'UL': 'table1.C1'},
                      []),
                     ('OneFetchStep', [('Any B,U,UL GROUPBY B,U,UL WHERE B created_by U?, B is File',
-                                       [{'B': 'File', 'U': 'EUser', 'UL': 'String'}])],
+                                       [{'B': 'File', 'U': 'CWUser', 'UL': 'String'}])],
                      None, None, [self.system],
                      {'U': 'table1.C0', 'UL': 'table1.C1'},
                      [])],
@@ -1932,20 +1932,20 @@
         self._test('Any B,U,UL GROUPBY B,U,UL WHERE B created_by U?, B is File '
                    'WITH U,UL BEING (Any U,UL WHERE ME eid %(x)s, (U identity ME '
                    'OR (EXISTS(U in_group G, G name IN("managers", "staff")))) '
-                   'OR (EXISTS(U in_group H, ME in_group H, NOT H name "users")), U login UL, U is EUser)',
-                   [('FetchStep', [('Any U,UL WHERE U login UL, U is EUser',
-                                    [{'U': 'EUser', 'UL': 'String'}])],
+                   'OR (EXISTS(U in_group H, ME in_group H, NOT H name "users")), U login UL, U is CWUser)',
+                   [('FetchStep', [('Any U,UL WHERE U login UL, U is CWUser',
+                                    [{'U': 'CWUser', 'UL': 'String'}])],
                      [self.ldap, self.system], None,
                      {'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
                      []),
-                    ('FetchStep', [('Any U,UL WHERE ((U identity 5) OR (EXISTS(U in_group G, G name IN("managers", "staff"), G is EGroup))) OR (EXISTS(U in_group H, 5 in_group H, NOT H name "users", H is EGroup)), U login UL, U is EUser',
-                                    [{'G': 'EGroup', 'H': 'EGroup', 'U': 'EUser', 'UL': 'String'}])],
+                    ('FetchStep', [('Any U,UL WHERE ((U identity 5) OR (EXISTS(U in_group G, G name IN("managers", "staff"), G is CWGroup))) OR (EXISTS(U in_group H, 5 in_group H, NOT H name "users", H is CWGroup)), U login UL, U is CWUser',
+                                    [{'G': 'CWGroup', 'H': 'CWGroup', 'U': 'CWUser', 'UL': 'String'}])],
                      [self.system],
                      {'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
                      {'U': 'table1.C0', 'U.login': 'table1.C1', 'UL': 'table1.C1'},
                      []),
                     ('OneFetchStep', [('Any B,U,UL GROUPBY B,U,UL WHERE B created_by U?, B is File',
-                                       [{'B': 'File', 'U': 'EUser', 'UL': 'String'}])],
+                                       [{'B': 'File', 'U': 'CWUser', 'UL': 'String'}])],
                      None, None, [self.system],
                      {'U': 'table1.C0', 'UL': 'table1.C1'},
                      [])],
--- a/server/test/unittest_multisources.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_multisources.py	Fri Apr 24 19:46:47 2009 +0200
@@ -195,8 +195,8 @@
         
     def test_union(self):
         afeids = self.execute('Affaire X')
-        ueids = self.execute('EUser X')
-        rset = self.execute('(Any X WHERE X is Affaire) UNION (Any X WHERE X is EUser)')
+        ueids = self.execute('CWUser X')
+        rset = self.execute('(Any X WHERE X is Affaire) UNION (Any X WHERE X is CWUser)')
         self.assertEquals(sorted(r[0] for r in rset.rows),
                           sorted(r[0] for r in afeids + ueids))
         
--- a/server/test/unittest_querier.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_querier.py	Fri Apr 24 19:46:47 2009 +0200
@@ -39,7 +39,7 @@
 
 class MakeSchemaTC(TestCase):
     def test_known_values(self):
-        solution = {'A': 'String', 'B': 'EUser'}
+        solution = {'A': 'String', 'B': 'CWUser'}
         self.assertEquals(make_schema((Variable('A'), Variable('B')), solution, 
                                       'table0', TYPEMAP),
                           ('C0 text,C1 integer', {'A': 'table0.C0', 'B': 'table0.C1'}))
@@ -60,13 +60,13 @@
         pass
     
     def test_preprocess_1(self):
-        reid = self.execute('Any X WHERE X is ERType, X name "owned_by"')[0][0]
+        reid = self.execute('Any X WHERE X is CWRType, X name "owned_by"')[0][0]
         rqlst = self._prepare('Any COUNT(RDEF) WHERE RDEF relation_type X, X eid %(x)s', {'x': reid})
-        self.assertEquals(rqlst.solutions, [{'RDEF': 'EFRDef'}, {'RDEF': 'ENFRDef'}])
+        self.assertEquals(rqlst.solutions, [{'RDEF': 'CWAttribute'}, {'RDEF': 'CWRelation'}])
         
     def test_preprocess_2(self):
         teid = self.execute("INSERT Tag X: X name 'tag'")[0][0]
-        #geid = self.execute("EGroup G WHERE G name 'users'")[0][0]
+        #geid = self.execute("CWGroup G WHERE G name 'users'")[0][0]
         #self.execute("SET X tags Y WHERE X eid %(t)s, Y eid %(g)s",
         #             {'g': geid, 't': teid}, 'g')
         rqlst = self._prepare('Any X WHERE E eid %(x)s, E tags X', {'x': teid})
@@ -96,7 +96,7 @@
                           ' OR (EXISTS(H concerne G?, G owned_by %(B)s, G is SubDivision, X identity H, H is Affaire)))'
                           ' OR (EXISTS(I concerne F?, F owned_by %(B)s, F is Societe, X identity I, I is Affaire)))'
                           ' OR (EXISTS(J concerne E?, E owned_by %(B)s, E is Note, X identity J, J is Affaire)))'
-                          ', ET is EEType, X is Affaire')
+                          ', ET is CWEType, X is Affaire')
         self.assertEquals(solutions, [{'C': 'Division',
                                        'D': 'Affaire',
                                        'E': 'Note',
@@ -106,47 +106,47 @@
                                        'I': 'Affaire',
                                        'J': 'Affaire',
                                        'X': 'Affaire',
-                                       'ET': 'EEType', 'ETN': 'String'}])
+                                       'ET': 'CWEType', 'ETN': 'String'}])
         rql, solutions = partrqls[1]
-        self.assertEquals(rql,  'Any ETN,X WHERE X is ET, ET name ETN, ET is EEType, '
-                          'X is IN(Bookmark, Card, Comment, Division, ECache, EConstraint, EConstraintType, EEType, EFRDef, EGroup, ENFRDef, EPermission, EProperty, ERType, EUser, Email, EmailAddress, EmailPart, EmailThread, File, Folder, Image, Note, Personne, RQLExpression, Societe, State, SubDivision, Tag, TrInfo, Transition)')
+        self.assertEquals(rql,  'Any ETN,X WHERE X is ET, ET name ETN, ET is CWEType, '
+                          'X is IN(Bookmark, Card, Comment, Division, CWCache, CWConstraint, CWConstraintType, CWEType, CWAttribute, CWGroup, CWRelation, CWPermission, CWProperty, CWRType, CWUser, Email, EmailAddress, EmailPart, EmailThread, File, Folder, Image, Note, Personne, RQLExpression, Societe, State, SubDivision, Tag, TrInfo, Transition)')
         self.assertListEquals(sorted(solutions),
-                              sorted([{'X': 'Bookmark', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'Card', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'Comment', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'Division', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'ECache', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'EConstraint', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'EConstraintType', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'EEType', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'EFRDef', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'EGroup', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'Email', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'EmailAddress', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'EmailPart', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'EmailThread', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'ENFRDef', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'EPermission', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'EProperty', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'ERType', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'EUser', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'File', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'Folder', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'Image', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'Note', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'Personne', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'RQLExpression', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'Societe', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'State', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'SubDivision', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'Tag', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'Transition', 'ETN': 'String', 'ET': 'EEType'},
-                                      {'X': 'TrInfo', 'ETN': 'String', 'ET': 'EEType'}]))
+                              sorted([{'X': 'Bookmark', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'Card', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'Comment', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'Division', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWCache', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWConstraint', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWConstraintType', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWEType', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWAttribute', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWGroup', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'Email', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'EmailAddress', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'EmailPart', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'EmailThread', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWRelation', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWPermission', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWProperty', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWRType', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWUser', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'File', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'Folder', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'Image', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'Note', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'Personne', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'RQLExpression', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'Societe', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'State', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'SubDivision', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'Tag', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'Transition', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'TrInfo', 'ETN': 'String', 'ET': 'CWEType'}]))
         rql, solutions = partrqls[2]
         self.assertEquals(rql,
                           'Any ETN,X WHERE X is ET, ET name ETN, EXISTS(X owned_by %(C)s), '
-                          'ET is EEType, X is Basket')
-        self.assertEquals(solutions, [{'ET': 'EEType',
+                          'ET is CWEType, X is Basket')
+        self.assertEquals(solutions, [{'ET': 'CWEType',
                                        'X': 'Basket',
                                        'ETN': 'String',
                                        }])
@@ -170,7 +170,7 @@
     def test_build_description(self):
         # should return an empty result set
         rset = self.execute('Any X WHERE X eid %(x)s', {'x': self.session.user.eid})
-        self.assertEquals(rset.description[0][0], 'EUser')
+        self.assertEquals(rset.description[0][0], 'CWUser')
         rset = self.execute('Any 1')
         self.assertEquals(rset.description[0][0], 'Int')
         rset = self.execute('Any TRUE')
@@ -202,7 +202,7 @@
 
     def test_encoding_pb(self):
         self.assertRaises(RQLSyntaxError, self.execute,
-                          'Any X WHERE X is ERType, X name "öwned_by"')
+                          'Any X WHERE X is CWRType, X name "öwned_by"')
 
     def test_unknown_eid(self):
         # should return an empty result set
@@ -211,20 +211,20 @@
     # selection queries tests #################################################
     
     def test_select_1(self):
-        rset = self.execute('Any X ORDERBY X WHERE X is EGroup')
+        rset = self.execute('Any X ORDERBY X WHERE X is CWGroup')
         result, descr = rset.rows, rset.description
         self.assertEquals(tuplify(result), [(1,), (2,), (3,), (4,)])
-        self.assertEquals(descr, [('EGroup',), ('EGroup',), ('EGroup',), ('EGroup',)])
+        self.assertEquals(descr, [('CWGroup',), ('CWGroup',), ('CWGroup',), ('CWGroup',)])
         
     def test_select_2(self):
-        rset = self.execute('Any X ORDERBY N WHERE X is EGroup, X name N')
+        rset = self.execute('Any X ORDERBY N WHERE X is CWGroup, X name N')
         self.assertEquals(tuplify(rset.rows), [(3,), (1,), (4,), (2,)])
-        self.assertEquals(rset.description, [('EGroup',), ('EGroup',), ('EGroup',), ('EGroup',)])
-        rset = self.execute('Any X ORDERBY N DESC WHERE X is EGroup, X name N')
+        self.assertEquals(rset.description, [('CWGroup',), ('CWGroup',), ('CWGroup',), ('CWGroup',)])
+        rset = self.execute('Any X ORDERBY N DESC WHERE X is CWGroup, X name N')
         self.assertEquals(tuplify(rset.rows), [(2,), (4,), (1,), (3,)])
         
     def test_select_3(self):
-        rset = self.execute('Any N GROUPBY N WHERE X is EGroup, X name N')
+        rset = self.execute('Any N GROUPBY N WHERE X is CWGroup, X name N')
         result, descr = rset.rows, rset.description
         result.sort()
         self.assertEquals(tuplify(result), [('guests',), ('managers',), ('owners',), ('users',)])
@@ -240,10 +240,10 @@
         result, descr = rset.rows, rset.description
         self.assertEquals(descr[0][0], 'String')
         self.assertEquals(descr[0][1], 'Int')
-        self.assertEquals(result[0][0], 'ENFRDef')
+        self.assertEquals(result[0][0], 'CWRelation')
         
     def test_select_groupby_orderby(self):
-        rset = self.execute('Any N GROUPBY N ORDERBY N WHERE X is EGroup, X name N')
+        rset = self.execute('Any N GROUPBY N ORDERBY N WHERE X is CWGroup, X name N')
         self.assertEquals(tuplify(rset.rows), [('guests',), ('managers',), ('owners',), ('users',)])
         self.assertEquals(rset.description, [('String',), ('String',), ('String',), ('String',)])
         
@@ -263,9 +263,9 @@
         self.assertEquals(len(rset), 5)
         
     def test_select_5(self):
-        rset = self.execute('Any X, TMP ORDERBY TMP WHERE X name TMP, X is EGroup')
+        rset = self.execute('Any X, TMP ORDERBY TMP WHERE X name TMP, X is CWGroup')
         self.assertEquals(tuplify(rset.rows), [(3, 'guests',), (1, 'managers',), (4, 'owners',), (2, 'users',)])
-        self.assertEquals(rset.description, [('EGroup', 'String',), ('EGroup', 'String',), ('EGroup', 'String',), ('EGroup', 'String',)])
+        self.assertEquals(rset.description, [('CWGroup', 'String',), ('CWGroup', 'String',), ('CWGroup', 'String',), ('CWGroup', 'String',)])
         
     def test_select_6(self):
         self.execute("INSERT Personne X: X nom 'bidule'")[0]
@@ -307,16 +307,16 @@
         self.execute("INSERT Personne X: X nom 'chouette'")
         self.execute("INSERT Personne X: X nom 'autre'")
         self.execute("SET X ecrit_par P WHERE X para 'bidule', P nom 'chouette'")
-        rset = self.execute('Any U,T ORDERBY T DESC WHERE U is EUser, '
+        rset = self.execute('Any U,T ORDERBY T DESC WHERE U is CWUser, '
                             'N ecrit_par U, N type T')#, {'x': self.ueid})
         self.assertEquals(len(rset.rows), 0)
         
     def test_select_nonregr_edition_not(self):
         groupeids = set((1, 2, 3))
-        groupreadperms = set(r[0] for r in self.execute('Any Y WHERE X name "EGroup", Y eid IN(1, 2, 3), X read_permission Y'))
-        rset = self.execute('DISTINCT Any Y WHERE X is EEType, X name "EGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
+        groupreadperms = set(r[0] for r in self.execute('Any Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), X read_permission Y'))
+        rset = self.execute('DISTINCT Any Y WHERE X is CWEType, X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
         self.assertEquals(sorted(r[0] for r in rset.rows), sorted(groupeids - groupreadperms))
-        rset = self.execute('DISTINCT Any Y WHERE X name "EGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
+        rset = self.execute('DISTINCT Any Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
         self.assertEquals(sorted(r[0] for r in rset.rows), sorted(groupeids - groupreadperms))
                      
     def test_select_outer_join(self):
@@ -340,7 +340,7 @@
         self.assertEquals(rset.rows, [[peid1]])
 
     def test_select_left_outer_join(self):
-        ueid = self.execute("INSERT EUser X: X login 'bob', X upassword 'toto', X in_group G "
+        ueid = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto', X in_group G "
                             "WHERE G name 'users'")[0][0]
         self.commit()
         try:
@@ -359,13 +359,13 @@
                                 {'x': ueid}, 'x')
             self.assertEquals(len(rset), 2)
         finally:
-            self.execute('DELETE EUser X WHERE X eid %s' % ueid)
+            self.execute('DELETE CWUser X WHERE X eid %s' % ueid)
             self.commit()
 
     def test_select_ambigous_outer_join(self):
         teid = self.execute("INSERT Tag X: X name 'tag'")[0][0]
         self.execute("INSERT Tag X: X name 'tagbis'")[0][0]
-        geid = self.execute("EGroup G WHERE G name 'users'")[0][0]
+        geid = self.execute("CWGroup G WHERE G name 'users'")[0][0]
         self.execute("SET X tags Y WHERE X eid %(t)s, Y eid %(g)s",
                      {'g': geid, 't': teid}, 'g')
         rset = self.execute("Any GN,TN ORDERBY GN WHERE T? tags G, T name TN, G name GN")
@@ -423,13 +423,13 @@
         self.assertEquals(rset.description, [('Int',)])
 
     def test_select_custom_aggregat_concat_string(self):
-        rset = self.execute('Any CONCAT_STRINGS(N) WHERE X is EGroup, X name N')
+        rset = self.execute('Any CONCAT_STRINGS(N) WHERE X is CWGroup, X name N')
         self.failUnless(rset)
         self.failUnlessEqual(sorted(rset[0][0].split(', ')), ['guests', 'managers',
                                                              'owners', 'users'])
 
     def test_select_custom_regproc_limit_size(self):
-        rset = self.execute('Any TEXT_LIMIT_SIZE(N, 3) WHERE X is EGroup, X name N, X name "managers"')
+        rset = self.execute('Any TEXT_LIMIT_SIZE(N, 3) WHERE X is CWGroup, X name N, X name "managers"')
         self.failUnless(rset)
         self.failUnlessEqual(rset[0][0], 'man...')
         self.execute("INSERT Basket X: X name 'bidule', X description '<b>hop hop</b>', X description_format 'text/html'")
@@ -438,10 +438,10 @@
         self.failUnlessEqual(rset[0][0], 'hop...')
 
     def test_select_regproc_orderby(self):
-        rset = self.execute('DISTINCT Any X,N ORDERBY GROUP_SORT_VALUE(N) WHERE X is EGroup, X name N, X name "managers"')
+        rset = self.execute('DISTINCT Any X,N ORDERBY GROUP_SORT_VALUE(N) WHERE X is CWGroup, X name N, X name "managers"')
         self.failUnlessEqual(len(rset), 1)
         self.failUnlessEqual(rset[0][1], 'managers')
-        rset = self.execute('Any X,N ORDERBY GROUP_SORT_VALUE(N) WHERE X is EGroup, X name N, NOT U in_group X, U login "admin"')
+        rset = self.execute('Any X,N ORDERBY GROUP_SORT_VALUE(N) WHERE X is CWGroup, X name N, NOT U in_group X, U login "admin"')
         self.failUnlessEqual(len(rset), 3)
         self.failUnlessEqual(rset[0][1], 'owners')
         
@@ -449,7 +449,7 @@
         rset = self.execute('Any G, COUNT(U) GROUPBY G ORDERBY 2 WHERE U in_group G')
         self.assertEquals(len(rset.rows), 2)
         self.assertEquals(len(rset.rows[0]), 2)
-        self.assertEquals(rset.description[0], ('EGroup', 'Int',))
+        self.assertEquals(rset.description[0], ('CWGroup', 'Int',))
 
     def test_select_aggregat_having(self):
         rset = self.execute('Any N,COUNT(RDEF) GROUPBY N ORDERBY 2,N '
@@ -477,12 +477,12 @@
         self.assertEquals(tuplify(result), [(1,), (2,), (3,), (4,), (5,)])
         
     def test_select_upper(self):
-        rset = self.execute('Any X, UPPER(L) ORDERBY L WHERE X is EUser, X login L')
+        rset = self.execute('Any X, UPPER(L) ORDERBY L WHERE X is CWUser, X login L')
         self.assertEquals(len(rset.rows), 2)
         self.assertEquals(rset.rows[0][1], 'ADMIN')
-        self.assertEquals(rset.description[0], ('EUser', 'String',))
+        self.assertEquals(rset.description[0], ('CWUser', 'String',))
         self.assertEquals(rset.rows[1][1], 'ANON')
-        self.assertEquals(rset.description[1], ('EUser', 'String',))
+        self.assertEquals(rset.description[1], ('CWUser', 'String',))
         eid = rset.rows[0][0]
         rset = self.execute('Any UPPER(L) WHERE X eid %s, X login L'%eid)
         self.assertEquals(rset.rows[0][0], 'ADMIN')
@@ -538,16 +538,16 @@
         self.assertEquals(len(rset.rows), 1, rset.rows)
         
     def test_select_no_descr(self):
-        rset = self.execute('Any X WHERE X is EGroup', build_descr=0)
+        rset = self.execute('Any X WHERE X is CWGroup', build_descr=0)
         rset.rows.sort()
         self.assertEquals(tuplify(rset.rows), [(1,), (2,), (3,), (4,)])
         self.assertEquals(rset.description, ())
 
     def test_select_limit_offset(self):
-        rset = self.execute('EGroup X ORDERBY N LIMIT 2 WHERE X name N')
+        rset = self.execute('CWGroup X ORDERBY N LIMIT 2 WHERE X name N')
         self.assertEquals(tuplify(rset.rows), [(3,), (1,)])
-        self.assertEquals(rset.description, [('EGroup',), ('EGroup',)])
-        rset = self.execute('EGroup X ORDERBY N LIMIT 2 OFFSET 2 WHERE X name N')
+        self.assertEquals(rset.description, [('CWGroup',), ('CWGroup',)])
+        rset = self.execute('CWGroup X ORDERBY N LIMIT 2 OFFSET 2 WHERE X name N')
         self.assertEquals(tuplify(rset.rows), [(4,), (2,)])
         
     def test_select_symetric(self):
@@ -637,7 +637,7 @@
         self.assertEqual(rset.rows, [['abcd'], ['important'], ['minor'], ['normal'], ['zou']])
         
     def test_select_ordered_distinct_3(self):
-        rset = self.execute('DISTINCT Any N ORDERBY GROUP_SORT_VALUE(N) WHERE X is EGroup, X name N')
+        rset = self.execute('DISTINCT Any N ORDERBY GROUP_SORT_VALUE(N) WHERE X is CWGroup, X name N')
         self.assertEqual(rset.rows, [['owners'], ['guests'], ['users'], ['managers']])
 
     def test_select_or_value(self):
@@ -674,7 +674,7 @@
         self.assertEqual(len(rset.rows), 2)
 
     def test_select_boolean(self):
-        rset = self.execute('Any N WHERE X is EEType, X name N, X final %(val)s',
+        rset = self.execute('Any N WHERE X is CWEType, X name N, X final %(val)s',
                             {'val': True})
         self.assertEquals(sorted(r[0] for r in rset.rows), ['Boolean', 'Bytes',
                                                             'Date', 'Datetime',
@@ -682,7 +682,7 @@
                                                             'Int', 'Interval',
                                                             'Password', 'String',
                                                             'Time'])
-        rset = self.execute('Any N WHERE X is EEType, X name N, X final TRUE')
+        rset = self.execute('Any N WHERE X is CWEType, X name N, X final TRUE')
         self.assertEquals(sorted(r[0] for r in rset.rows), ['Boolean', 'Bytes',
                                                             'Date', 'Datetime',
                                                             'Decimal', 'Float',
@@ -691,28 +691,28 @@
                                                             'Time'])
         
     def test_select_constant(self):
-        rset = self.execute('Any X, "toto" ORDERBY X WHERE X is EGroup')
+        rset = self.execute('Any X, "toto" ORDERBY X WHERE X is CWGroup')
         self.assertEquals(rset.rows,
                           map(list, zip((1,2,3,4), ('toto','toto','toto','toto',))))
         self.assertIsInstance(rset[0][1], unicode)
         self.assertEquals(rset.description,
-                          zip(('EGroup', 'EGroup', 'EGroup', 'EGroup'),
+                          zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
                               ('String', 'String', 'String', 'String',)))
-        rset = self.execute('Any X, %(value)s ORDERBY X WHERE X is EGroup', {'value': 'toto'})
+        rset = self.execute('Any X, %(value)s ORDERBY X WHERE X is CWGroup', {'value': 'toto'})
         self.assertEquals(rset.rows,
                           map(list, zip((1,2,3,4), ('toto','toto','toto','toto',))))
         self.assertIsInstance(rset[0][1], unicode)
         self.assertEquals(rset.description,
-                          zip(('EGroup', 'EGroup', 'EGroup', 'EGroup'),
+                          zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
                               ('String', 'String', 'String', 'String',)))
-        rset = self.execute('Any X,GN WHERE X is EUser, G is EGroup, X login "syt", X in_group G, G name GN')
+        rset = self.execute('Any X,GN WHERE X is CWUser, G is CWGroup, X login "syt", X in_group G, G name GN')
 
     def test_select_union(self):
         rset = self.execute('Any X,N ORDERBY N WITH X,N BEING '
                             '((Any X,N WHERE X name N, X transition_of E, E name %(name)s)'
                             ' UNION '
                             '(Any X,N WHERE X name N, X state_of E, E name %(name)s))',
-                            {'name': 'EUser'})
+                            {'name': 'CWUser'})
         self.assertEquals([x[1] for x in rset.rows],
                           ['activate', 'activated', 'deactivate', 'deactivated'])
         self.assertEquals(rset.description,
@@ -748,7 +748,7 @@
                            'start', 'todo'])
         
     def test_exists(self):
-        geid = self.execute("INSERT EGroup X: X name 'lulufanclub'")[0][0]
+        geid = self.execute("INSERT CWGroup X: X name 'lulufanclub'")[0][0]
         self.execute("SET U in_group G WHERE G name 'lulufanclub'")
         peid = self.execute("INSERT Personne X: X prenom 'lulu', X nom 'petit'")[0][0]
         rset = self.execute("Any X WHERE X prenom 'lulu',"
@@ -764,7 +764,7 @@
         self.assertEquals(login, 'admin')
 
     def test_select_date_mathexp(self):
-        rset = self.execute('Any X, TODAY - CD WHERE X is EUser, X creation_date CD')
+        rset = self.execute('Any X, TODAY - CD WHERE X is CWUser, X creation_date CD')
         self.failUnless(rset)
         self.failUnlessEqual(rset.description[0][1], 'Interval')
         eid, = self.execute("INSERT Personne X: X nom 'bidule'")[0]
@@ -776,7 +776,7 @@
         self.execute('SET X in_group G WHERE G name "users"')
         rset = self.execute('Any GN, COUNT(X)*100/T GROUPBY GN ORDERBY 2,1'
                             ' WHERE G name GN, X in_group G'
-                            ' WITH T BEING (Any COUNT(U) WHERE U is EUser)')
+                            ' WITH T BEING (Any COUNT(U) WHERE U is CWUser)')
         self.assertEquals(rset.rows, [[u'guests', 50], [u'managers', 50], [u'users', 100]])
         self.assertEquals(rset.description, [('String', 'Int'), ('String', 'Int'), ('String', 'Int')])
 
@@ -884,13 +884,13 @@
 
         self.assertRaises(QueryError,
                           self.execute,
-                          "INSERT EUser X: X login 'toto', X eid %s" % cnx.user(self.session).eid)
+                          "INSERT CWUser X: X login 'toto', X eid %s" % cnx.user(self.session).eid)
 
     def test_insertion_description_with_where(self):
-        rset = self.execute('INSERT EUser E, EmailAddress EM: E login "X", E upassword "X", '
+        rset = self.execute('INSERT CWUser E, EmailAddress EM: E login "X", E upassword "X", '
                             'E primary_email EM, EM address "X", E in_group G '
                             'WHERE G name "managers"')
-        self.assertEquals(list(rset.description[0]), ['EUser', 'EmailAddress'])
+        self.assertEquals(list(rset.description[0]), ['CWUser', 'EmailAddress'])
     
     # deletion queries tests ##################################################
 
@@ -1027,7 +1027,7 @@
         self.assertEquals(self.execute('Any X WHERE X nom "tutu"').rows, [[peid2]])
 
     def test_update_multiple2(self):
-        ueid = self.execute("INSERT EUser X: X login 'bob', X upassword 'toto'")[0][0]
+        ueid = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto'")[0][0]
         peid1 = self.execute("INSERT Personne Y: Y nom 'turlu'")[0][0]
         peid2 = self.execute("INSERT Personne Y: Y nom 'tutu'")[0][0]
         self.execute('SET P1 owned_by U, P2 owned_by U '
@@ -1065,33 +1065,33 @@
     # upassword encryption tests #################################################
     
     def test_insert_upassword(self):
-        rset = self.execute("INSERT EUser X: X login 'bob', X upassword 'toto'")
+        rset = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto'")
         self.assertEquals(len(rset.rows), 1)
-        self.assertEquals(rset.description, [('EUser',)])
+        self.assertEquals(rset.description, [('CWUser',)])
         self.assertRaises(Unauthorized,
-                          self.execute, "Any P WHERE X is EUser, X login 'bob', X upassword P")
+                          self.execute, "Any P WHERE X is CWUser, X login 'bob', X upassword P")
         cursor = self.pool['system']
-        cursor.execute("SELECT %supassword from %sEUser WHERE %slogin='bob'"
+        cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
                        % (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
         passwd = cursor.fetchone()[0].getvalue()
         self.assertEquals(passwd, crypt_password('toto', passwd[:2])) 
-        rset = self.execute("Any X WHERE X is EUser, X login 'bob', X upassword '%s'" % passwd)
+        rset = self.execute("Any X WHERE X is CWUser, X login 'bob', X upassword '%s'" % passwd)
         self.assertEquals(len(rset.rows), 1)
-        self.assertEquals(rset.description, [('EUser',)])
+        self.assertEquals(rset.description, [('CWUser',)])
         
     def test_update_upassword(self):
         cursor = self.pool['system']
-        rset = self.execute("INSERT EUser X: X login 'bob', X upassword %(pwd)s", {'pwd': 'toto'})
-        self.assertEquals(rset.description[0][0], 'EUser')
-        rset = self.execute("SET X upassword %(pwd)s WHERE X is EUser, X login 'bob'",
+        rset = self.execute("INSERT CWUser X: X login 'bob', X upassword %(pwd)s", {'pwd': 'toto'})
+        self.assertEquals(rset.description[0][0], 'CWUser')
+        rset = self.execute("SET X upassword %(pwd)s WHERE X is CWUser, X login 'bob'",
                             {'pwd': 'tutu'})
-        cursor.execute("SELECT %supassword from %sEUser WHERE %slogin='bob'"
+        cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
                        % (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
         passwd = cursor.fetchone()[0].getvalue()
         self.assertEquals(passwd, crypt_password('tutu', passwd[:2])) 
-        rset = self.execute("Any X WHERE X is EUser, X login 'bob', X upassword '%s'" % passwd)
+        rset = self.execute("Any X WHERE X is CWUser, X login 'bob', X upassword '%s'" % passwd)
         self.assertEquals(len(rset.rows), 1)
-        self.assertEquals(rset.description, [('EUser',)])
+        self.assertEquals(rset.description, [('CWUser',)])
 
     # non regression tests ####################################################
     
@@ -1107,7 +1107,7 @@
 
     def test_nonregr_2(self):
         teid = self.execute("INSERT Tag X: X name 'tag'")[0][0]
-        geid = self.execute("EGroup G WHERE G name 'users'")[0][0]
+        geid = self.execute("CWGroup G WHERE G name 'users'")[0][0]
         self.execute("SET X tags Y WHERE X eid %(t)s, Y eid %(g)s",
                        {'g': geid, 't': teid})
         rset = self.execute('Any X WHERE E eid %(x)s, E tags X',
@@ -1118,7 +1118,7 @@
         """bad sql generated on the second query (destination_state is not
         detected as an inlined relation)
         """
-        rset = self.execute('Any S,ES,T WHERE S state_of ET, ET name "EUser",'
+        rset = self.execute('Any S,ES,T WHERE S state_of ET, ET name "CWUser",'
                              'ES allowed_transition T, T destination_state S')
         self.assertEquals(len(rset.rows), 2)
 
@@ -1127,7 +1127,7 @@
         # union queries and that make for instance a 266Ko sql query which is refused
         # by the server (or client lib)
         rset = self.execute('Any ER,SE,OE WHERE SE name "Comment", ER name "comments", OE name "Comment",'
-                            'ER is ERType, SE is EEType, OE is EEType')
+                            'ER is CWRType, SE is CWEType, OE is CWEType')
         self.assertEquals(len(rset), 1)
 
     def test_nonregr_5(self):
@@ -1246,16 +1246,16 @@
         self.execute('SET X creation_date %(date)s WHERE X eid 1', {'date': date.today()})
 
     def test_nonregr_set_query(self):
-        ueid = self.execute("INSERT EUser X: X login 'bob', X upassword 'toto'")[0][0]
+        ueid = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto'")[0][0]
         self.execute("SET E in_group G, E in_state S, "
                       "E firstname %(firstname)s, E surname %(surname)s "
                       "WHERE E eid %(x)s, G name 'users', S name 'activated'",
                       {'x':ueid, 'firstname': u'jean', 'surname': u'paul'}, 'x')
         
     def test_nonregr_u_owned_by_u(self):
-        ueid = self.execute("INSERT EUser X: X login 'bob', X upassword 'toto', X in_group G "
+        ueid = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto', X in_group G "
                              "WHERE G name 'users'")[0][0]
-        rset = self.execute("EUser U")
+        rset = self.execute("CWUser U")
         self.assertEquals(len(rset), 3) # bob + admin + anon
         rset = self.execute("Any U WHERE NOT U owned_by U")
         self.assertEquals(len(rset), 0) # even admin created at repo initialization time should belong to itself
@@ -1265,18 +1265,18 @@
         self.execute("SET X description D WHERE X is State, X description D")
 
     def test_nonregr_is(self):
-        uteid = self.execute('Any ET WHERE ET name "EUser"')[0][0]
+        uteid = self.execute('Any ET WHERE ET name "CWUser"')[0][0]
         self.execute('Any X, ET WHERE X is ET, ET eid %s' % uteid)
 
     def test_nonregr_orderby(self):
         seid = self.execute('Any X WHERE X name "activated"')[0][0]
-        self.execute('Any X,S, MAX(T) GROUPBY X,S ORDERBY S WHERE X is EUser, T tags X, S eid IN(%s), X in_state S' % seid)
+        self.execute('Any X,S, MAX(T) GROUPBY X,S ORDERBY S WHERE X is CWUser, T tags X, S eid IN(%s), X in_state S' % seid)
 
     def test_nonregr_solution_cache(self):
         self.skip('XXX should be fixed or documented') # (doesn't occur if cache key is provided.)
-        rset = self.execute('Any X WHERE X is EUser, X eid %(x)s', {'x':self.ueid})
+        rset = self.execute('Any X WHERE X is CWUser, X eid %(x)s', {'x':self.ueid})
         self.assertEquals(len(rset), 1)
-        rset = self.execute('Any X WHERE X is EUser, X eid %(x)s', {'x':12345})
+        rset = self.execute('Any X WHERE X is CWUser, X eid %(x)s', {'x':12345})
         self.assertEquals(len(rset), 0)
 
     def test_nonregr_final_norestr(self):
--- a/server/test/unittest_repository.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_repository.py	Fri Apr 24 19:46:47 2009 +0200
@@ -46,7 +46,7 @@
         self.repo.config._cubes = None # avoid assertion error
         self.repo.fill_schema()
         pool = self.repo._get_pool()
-        table = SQL_PREFIX + 'EEType'
+        table = SQL_PREFIX + 'CWEType'
         namecol = SQL_PREFIX + 'name'
         finalcol = SQL_PREFIX + 'final'
         try:
@@ -68,12 +68,12 @@
     def test_schema_has_owner(self):
         repo = self.repo
         cnxid = repo.connect(*self.default_user_password())
-        self.failIf(repo.execute(cnxid, 'EEType X WHERE NOT X owned_by U'))
-        self.failIf(repo.execute(cnxid, 'ERType X WHERE NOT X owned_by U'))
-        self.failIf(repo.execute(cnxid, 'EFRDef X WHERE NOT X owned_by U'))
-        self.failIf(repo.execute(cnxid, 'ENFRDef X WHERE NOT X owned_by U'))
-        self.failIf(repo.execute(cnxid, 'EConstraint X WHERE NOT X owned_by U'))
-        self.failIf(repo.execute(cnxid, 'EConstraintType X WHERE NOT X owned_by U'))
+        self.failIf(repo.execute(cnxid, 'CWEType X WHERE NOT X owned_by U'))
+        self.failIf(repo.execute(cnxid, 'CWRType X WHERE NOT X owned_by U'))
+        self.failIf(repo.execute(cnxid, 'CWAttribute X WHERE NOT X owned_by U'))
+        self.failIf(repo.execute(cnxid, 'CWRelation X WHERE NOT X owned_by U'))
+        self.failIf(repo.execute(cnxid, 'CWConstraint X WHERE NOT X owned_by U'))
+        self.failIf(repo.execute(cnxid, 'CWConstraintType X WHERE NOT X owned_by U'))
         
     def test_connect(self):
         login, passwd = self.default_user_password()
@@ -97,7 +97,7 @@
     def test_login_upassword_accent(self):
         repo = self.repo
         cnxid = repo.connect(*self.default_user_password())
-        repo.execute(cnxid, 'INSERT EUser X: X login %(login)s, X upassword %(passwd)s, X in_state S, X in_group G WHERE S name "activated", G name "users"',
+        repo.execute(cnxid, 'INSERT CWUser X: X login %(login)s, X upassword %(passwd)s, X in_state S, X in_group G WHERE S name "activated", G name "users"',
                      {'login': u"barnabé", 'passwd': u"héhéhé".encode('UTF8')})
         repo.commit(cnxid)
         repo.close(cnxid)
@@ -106,10 +106,10 @@
     def test_invalid_entity_rollback(self):
         repo = self.repo
         cnxid = repo.connect(*self.default_user_password())
-        repo.execute(cnxid, 'INSERT EUser X: X login %(login)s, X upassword %(passwd)s, X in_state S WHERE S name "activated"',
+        repo.execute(cnxid, 'INSERT CWUser X: X login %(login)s, X upassword %(passwd)s, X in_state S WHERE S name "activated"',
                      {'login': u"tutetute", 'passwd': 'tutetute'})
         self.assertRaises(ValidationError, repo.commit, cnxid)
-        rset = repo.execute(cnxid, 'EUser X WHERE X login "tutetute"')
+        rset = repo.execute(cnxid, 'CWUser X WHERE X login "tutetute"')
         self.assertEquals(rset.rowcount, 0)
         
     def test_close(self):
@@ -201,7 +201,7 @@
     def test_initial_schema(self):
         schema = self.repo.schema
         # check order of attributes is respected
-        self.assertListEquals([r.type for r in schema.eschema('EFRDef').ordered_relations()
+        self.assertListEquals([r.type for r in schema.eschema('CWAttribute').ordered_relations()
                                if not r.type in ('eid', 'is', 'is_instance_of', 'identity', 
                                                  'creation_date', 'modification_date',
                                                  'owned_by', 'created_by')],
@@ -210,10 +210,10 @@
                                'indexed', 'fulltextindexed', 'internationalizable',
                                'defaultval', 'description_format', 'description'])
 
-        self.assertEquals(schema.eschema('EEType').main_attribute(), 'name')
+        self.assertEquals(schema.eschema('CWEType').main_attribute(), 'name')
         self.assertEquals(schema.eschema('State').main_attribute(), 'name')
 
-        constraints = schema.rschema('name').rproperty('EEType', 'String', 'constraints')
+        constraints = schema.rschema('name').rproperty('CWEType', 'String', 'constraints')
         self.assertEquals(len(constraints), 2)
         for cstr in constraints[:]:
             if isinstance(cstr, UniqueConstraint):
@@ -225,14 +225,14 @@
         self.assertEquals(sizeconstraint.min, None)
         self.assertEquals(sizeconstraint.max, 64)
 
-        constraints = schema.rschema('relation_type').rproperty('EFRDef', 'ERType', 'constraints')
+        constraints = schema.rschema('relation_type').rproperty('CWAttribute', 'CWRType', 'constraints')
         self.assertEquals(len(constraints), 1)
         cstr = constraints[0]
         self.assert_(isinstance(cstr, RQLConstraint))
         self.assertEquals(cstr.restriction, 'O final TRUE')
 
         ownedby = schema.rschema('owned_by')
-        self.assertEquals(ownedby.objects('EEType'), ('EUser',))
+        self.assertEquals(ownedby.objects('CWEType'), ('CWUser',))
 
     def test_pyro(self):
         import Pyro
@@ -267,8 +267,8 @@
         repo = self.repo
         cnxid = repo.connect(*self.default_user_password())
         session = repo._get_session(cnxid, setpool=True)
-        self.assertEquals(repo.type_and_source_from_eid(1, session), ('EGroup', 'system', None))
-        self.assertEquals(repo.type_from_eid(1, session), 'EGroup')
+        self.assertEquals(repo.type_and_source_from_eid(1, session), ('CWGroup', 'system', None))
+        self.assertEquals(repo.type_from_eid(1, session), 'CWGroup')
         self.assertEquals(repo.source_from_eid(1, session).uri, 'system')
         self.assertEquals(repo.eid2extid(repo.system_source, 1, session), None)
         class dummysource: uri = 'toto'
@@ -278,13 +278,13 @@
         self.assertEquals(self.repo.get_schema(), self.repo.schema)
         self.assertEquals(self.repo.source_defs(), {'system': {'adapter': 'native', 'uri': 'system'}})
         # .properties() return a result set
-        self.assertEquals(self.repo.properties().rql, 'Any K,V WHERE P is EProperty,P pkey K, P value V, NOT P for_user U')
+        self.assertEquals(self.repo.properties().rql, 'Any K,V WHERE P is CWProperty,P pkey K, P value V, NOT P for_user U')
 
     def test_session_api(self):
         repo = self.repo
         cnxid = repo.connect(*self.default_user_password())
         self.assertEquals(repo.user_info(cnxid), (5, 'admin', set([u'managers']), {}))
-        self.assertEquals(repo.describe(cnxid, 1), (u'EGroup', u'system', None))
+        self.assertEquals(repo.describe(cnxid, 1), (u'CWGroup', u'system', None))
         repo.close(cnxid)
         self.assertRaises(BadConnectionId, repo.user_info, cnxid)
         self.assertRaises(BadConnectionId, repo.describe, cnxid, 1)
@@ -325,7 +325,7 @@
         self.assertRaises(UnknownEid, self.repo.source_from_eid, -2, self.session)
 
     def test_type_from_eid(self):
-        self.assertEquals(self.repo.type_from_eid(1, self.session), 'EGroup')
+        self.assertEquals(self.repo.type_from_eid(1, self.session), 'CWGroup')
         
     def test_type_from_eid_raise(self):
         self.assertRaises(UnknownEid, self.repo.type_from_eid, -2, self.session)
@@ -449,7 +449,7 @@
         """make sure after_<event>_relation hooks are deferred"""
         self.hm.register_hook(self._after_relation_hook,
                              'after_add_relation', 'in_state')
-        eidp = self.execute('INSERT EUser X: X login "toto", X upassword "tutu", X in_state S WHERE S name "activated"')[0][0]
+        eidp = self.execute('INSERT CWUser X: X login "toto", X upassword "tutu", X in_state S WHERE S name "activated"')[0][0]
         eids = self.execute('State X WHERE X name "activated"')[0][0]
         self.assertEquals(self.called, [(eidp, 'in_state', eids,)])
     
--- a/server/test/unittest_rql2sql.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_rql2sql.py	Fri Apr 24 19:46:47 2009 +0200
@@ -121,14 +121,14 @@
 FROM cw_Affaire AS X
 WHERE DATE(X.cw_creation_date)=CURRENT_DATE'''),
 
-    ("Any N WHERE G is EGroup, G name N, E eid 12, E read_permission G",
+    ("Any N WHERE G is CWGroup, G name N, E eid 12, E read_permission G",
      '''SELECT G.cw_name
-FROM cw_EGroup AS G, read_permission_relation AS rel_read_permission0
+FROM cw_CWGroup AS G, read_permission_relation AS rel_read_permission0
 WHERE rel_read_permission0.eid_from=12 AND rel_read_permission0.eid_to=G.cw_eid'''),
 
     ('Any Y WHERE U login "admin", U login Y', # stupid but valid...
      """SELECT U.cw_login
-FROM cw_EUser AS U
+FROM cw_CWUser AS U
 WHERE U.cw_login=admin"""),
 
     ('Any T WHERE T tags X, X is State',
@@ -145,13 +145,13 @@
      "EXISTS(X owned_by U, U in_group G, G name 'lulufanclub' OR G name 'managers');",
      '''SELECT X.cw_eid
 FROM cw_Personne AS X
-WHERE X.cw_prenom=lulu AND EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0, in_group_relation AS rel_in_group1, cw_EGroup AS G WHERE rel_owned_by0.eid_from=X.cw_eid AND rel_in_group1.eid_from=rel_owned_by0.eid_to AND rel_in_group1.eid_to=G.cw_eid AND ((G.cw_name=lulufanclub) OR (G.cw_name=managers)))'''),
+WHERE X.cw_prenom=lulu AND EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0, in_group_relation AS rel_in_group1, cw_CWGroup AS G WHERE rel_owned_by0.eid_from=X.cw_eid AND rel_in_group1.eid_from=rel_owned_by0.eid_to AND rel_in_group1.eid_to=G.cw_eid AND ((G.cw_name=lulufanclub) OR (G.cw_name=managers)))'''),
 
     ("Any X WHERE X prenom 'lulu',"
      "NOT EXISTS(X owned_by U, U in_group G, G name 'lulufanclub' OR G name 'managers');",
      '''SELECT X.cw_eid
 FROM cw_Personne AS X
-WHERE X.cw_prenom=lulu AND NOT EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0, in_group_relation AS rel_in_group1, cw_EGroup AS G WHERE rel_owned_by0.eid_from=X.cw_eid AND rel_in_group1.eid_from=rel_owned_by0.eid_to AND rel_in_group1.eid_to=G.cw_eid AND ((G.cw_name=lulufanclub) OR (G.cw_name=managers)))'''),
+WHERE X.cw_prenom=lulu AND NOT EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0, in_group_relation AS rel_in_group1, cw_CWGroup AS G WHERE rel_owned_by0.eid_from=X.cw_eid AND rel_in_group1.eid_from=rel_owned_by0.eid_to AND rel_in_group1.eid_to=G.cw_eid AND ((G.cw_name=lulufanclub) OR (G.cw_name=managers)))'''),
 ]
 
 ADVANCED= [
@@ -234,11 +234,11 @@
     
     ('Any SEN,RN,OEN WHERE X from_entity SE, SE eid 44, X relation_type R, R eid 139, X to_entity OE, OE eid 42, R name RN, SE name SEN, OE name OEN',
      '''SELECT SE.cw_name, R.cw_name, OE.cw_name
-FROM cw_EEType AS OE, cw_EEType AS SE, cw_EFRDef AS X, cw_ERType AS R
+FROM cw_CWEType AS OE, cw_CWEType AS SE, cw_CWAttribute AS X, cw_CWRType AS R
 WHERE X.cw_from_entity=44 AND SE.cw_eid=44 AND X.cw_relation_type=139 AND R.cw_eid=139 AND X.cw_to_entity=42 AND OE.cw_eid=42
 UNION ALL
 SELECT SE.cw_name, R.cw_name, OE.cw_name
-FROM cw_EEType AS OE, cw_EEType AS SE, cw_ENFRDef AS X, cw_ERType AS R
+FROM cw_CWEType AS OE, cw_CWEType AS SE, cw_CWRelation AS X, cw_CWRType AS R
 WHERE X.cw_from_entity=44 AND SE.cw_eid=44 AND X.cw_relation_type=139 AND R.cw_eid=139 AND X.cw_to_entity=42 AND OE.cw_eid=42'''),
 
     # Any O WHERE NOT S corrected_in O, S eid %(x)s, S concerns P, O version_of P, O in_state ST, NOT ST name "published", O modification_date MTIME ORDERBY MTIME DESC LIMIT 9
@@ -272,8 +272,8 @@
 
     ('Any GN WHERE X in_group G, G name GN, (G name "managers" OR EXISTS(X copain T, T login in ("comme", "cochon")))',
      '''SELECT G.cw_name
-FROM cw_EGroup AS G, in_group_relation AS rel_in_group0
-WHERE rel_in_group0.eid_to=G.cw_eid AND ((G.cw_name=managers) OR (EXISTS(SELECT 1 FROM copain_relation AS rel_copain1, cw_EUser AS T WHERE rel_copain1.eid_from=rel_in_group0.eid_from AND rel_copain1.eid_to=T.cw_eid AND T.cw_login IN(comme, cochon))))'''),
+FROM cw_CWGroup AS G, in_group_relation AS rel_in_group0
+WHERE rel_in_group0.eid_to=G.cw_eid AND ((G.cw_name=managers) OR (EXISTS(SELECT 1 FROM copain_relation AS rel_copain1, cw_CWUser AS T WHERE rel_copain1.eid_from=rel_in_group0.eid_from AND rel_copain1.eid_to=T.cw_eid AND T.cw_login IN(comme, cochon))))'''),
 
     ('Any C WHERE C is Card, EXISTS(X documented_by C)',
       """SELECT C.cw_eid
@@ -292,12 +292,12 @@
 
     ('Any GN,L WHERE X in_group G, X login L, G name GN, EXISTS(X copain T, T login L, T login IN("comme", "cochon"))',
      '''SELECT G.cw_name, X.cw_login
-FROM cw_EGroup AS G, cw_EUser AS X, in_group_relation AS rel_in_group0
-WHERE rel_in_group0.eid_from=X.cw_eid AND rel_in_group0.eid_to=G.cw_eid AND EXISTS(SELECT 1 FROM copain_relation AS rel_copain1, cw_EUser AS T WHERE rel_copain1.eid_from=X.cw_eid AND rel_copain1.eid_to=T.cw_eid AND T.cw_login=X.cw_login AND T.cw_login IN(comme, cochon))'''),
+FROM cw_CWGroup AS G, cw_CWUser AS X, in_group_relation AS rel_in_group0
+WHERE rel_in_group0.eid_from=X.cw_eid AND rel_in_group0.eid_to=G.cw_eid AND EXISTS(SELECT 1 FROM copain_relation AS rel_copain1, cw_CWUser AS T WHERE rel_copain1.eid_from=X.cw_eid AND rel_copain1.eid_to=T.cw_eid AND T.cw_login=X.cw_login AND T.cw_login IN(comme, cochon))'''),
 
-    ('Any X,S, MAX(T) GROUPBY X,S ORDERBY S WHERE X is EUser, T tags X, S eid IN(32), X in_state S',
+    ('Any X,S, MAX(T) GROUPBY X,S ORDERBY S WHERE X is CWUser, T tags X, S eid IN(32), X in_state S',
      '''SELECT X.cw_eid, 32, MAX(rel_tags0.eid_from)
-FROM cw_EUser AS X, tags_relation AS rel_tags0
+FROM cw_CWUser AS X, tags_relation AS rel_tags0
 WHERE rel_tags0.eid_to=X.cw_eid AND X.cw_in_state=32
 GROUP BY X.cw_eid'''),
 
@@ -309,24 +309,24 @@
 ORDER BY 1 DESC
 LIMIT 10'''),
 
-    ('Any X WHERE Y evaluee X, Y is EUser',
+    ('Any X WHERE Y evaluee X, Y is CWUser',
      '''SELECT rel_evaluee0.eid_to
-FROM cw_EUser AS Y, evaluee_relation AS rel_evaluee0
+FROM cw_CWUser AS Y, evaluee_relation AS rel_evaluee0
 WHERE rel_evaluee0.eid_from=Y.cw_eid'''),
 
     ('Any L WHERE X login "admin", X identity Y, Y login L',
      '''SELECT Y.cw_login
-FROM cw_EUser AS X, cw_EUser AS Y
+FROM cw_CWUser AS X, cw_CWUser AS Y
 WHERE X.cw_login=admin AND X.cw_eid=Y.cw_eid'''),
 
     ('Any L WHERE X login "admin", NOT X identity Y, Y login L',
      '''SELECT Y.cw_login
-FROM cw_EUser AS X, cw_EUser AS Y
+FROM cw_CWUser AS X, cw_CWUser AS Y
 WHERE X.cw_login=admin AND NOT X.cw_eid=Y.cw_eid'''),
     
     ('Any L WHERE X login "admin", X identity Y?, Y login L',
      '''SELECT Y.cw_login
-FROM cw_EUser AS X LEFT OUTER JOIN cw_EUser AS Y ON (X.cw_eid=Y.cw_eid)
+FROM cw_CWUser AS X LEFT OUTER JOIN cw_CWUser AS Y ON (X.cw_eid=Y.cw_eid)
 WHERE X.cw_login=admin'''),
 
     ('Any XN ORDERBY XN WHERE X name XN',
@@ -334,22 +334,22 @@
 FROM cw_Basket AS X
 UNION ALL
 SELECT X.cw_name
-FROM cw_ECache AS X
+FROM cw_CWCache AS X
 UNION ALL
 SELECT X.cw_name
-FROM cw_EConstraintType AS X
+FROM cw_CWConstraintType AS X
 UNION ALL
 SELECT X.cw_name
-FROM cw_EEType AS X
+FROM cw_CWEType AS X
 UNION ALL
 SELECT X.cw_name
-FROM cw_EGroup AS X
+FROM cw_CWGroup AS X
 UNION ALL
 SELECT X.cw_name
-FROM cw_EPermission AS X
+FROM cw_CWPermission AS X
 UNION ALL
 SELECT X.cw_name
-FROM cw_ERType AS X
+FROM cw_CWRType AS X
 UNION ALL
 SELECT X.cw_name
 FROM cw_File AS X
@@ -376,108 +376,108 @@
 #     ''''''),
 
     # DISTINCT, can use relatin under exists scope as principal
-    ('DISTINCT Any X,Y WHERE X name "EGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)',
+    ('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)',
      '''SELECT DISTINCT X.cw_eid, rel_read_permission0.eid_to
-FROM cw_EEType AS X, read_permission_relation AS rel_read_permission0
-WHERE X.cw_name=EGroup AND rel_read_permission0.eid_to IN(1, 2, 3) AND EXISTS(SELECT 1 WHERE rel_read_permission0.eid_from=X.cw_eid)
+FROM cw_CWEType AS X, read_permission_relation AS rel_read_permission0
+WHERE X.cw_name=CWGroup AND rel_read_permission0.eid_to IN(1, 2, 3) AND EXISTS(SELECT 1 WHERE rel_read_permission0.eid_from=X.cw_eid)
 UNION
 SELECT DISTINCT X.cw_eid, rel_read_permission0.eid_to
-FROM cw_ERType AS X, read_permission_relation AS rel_read_permission0
-WHERE X.cw_name=EGroup AND rel_read_permission0.eid_to IN(1, 2, 3) AND EXISTS(SELECT 1 WHERE rel_read_permission0.eid_from=X.cw_eid)'''),
+FROM cw_CWRType AS X, read_permission_relation AS rel_read_permission0
+WHERE X.cw_name=CWGroup AND rel_read_permission0.eid_to IN(1, 2, 3) AND EXISTS(SELECT 1 WHERE rel_read_permission0.eid_from=X.cw_eid)'''),
 
     # no distinct, Y can't be invariant
-    ('Any X,Y WHERE X name "EGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)',
+    ('Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)',
      '''SELECT X.cw_eid, Y.cw_eid
-FROM cw_EEType AS X, cw_EGroup AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWEType AS X, cw_CWGroup AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION ALL
 SELECT X.cw_eid, Y.cw_eid
-FROM cw_EEType AS X, cw_RQLExpression AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWEType AS X, cw_RQLExpression AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION ALL
 SELECT X.cw_eid, Y.cw_eid
-FROM cw_EGroup AS Y, cw_ERType AS X
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWGroup AS Y, cw_CWRType AS X
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION ALL
 SELECT X.cw_eid, Y.cw_eid
-FROM cw_ERType AS X, cw_RQLExpression AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)'''),
+FROM cw_CWRType AS X, cw_RQLExpression AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)'''),
 
     # DISTINCT but NEGED exists, can't be invariant
-    ('DISTINCT Any X,Y WHERE X name "EGroup", Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)',
+    ('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)',
      '''SELECT DISTINCT X.cw_eid, Y.cw_eid
-FROM cw_EEType AS X, cw_EGroup AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWEType AS X, cw_CWGroup AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION
 SELECT DISTINCT X.cw_eid, Y.cw_eid
-FROM cw_EEType AS X, cw_RQLExpression AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWEType AS X, cw_RQLExpression AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION
 SELECT DISTINCT X.cw_eid, Y.cw_eid
-FROM cw_EGroup AS Y, cw_ERType AS X
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWGroup AS Y, cw_CWRType AS X
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION
 SELECT DISTINCT X.cw_eid, Y.cw_eid
-FROM cw_ERType AS X, cw_RQLExpression AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)'''),
+FROM cw_CWRType AS X, cw_RQLExpression AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)'''),
 
     # should generate the same query as above
-    ('DISTINCT Any X,Y WHERE X name "EGroup", Y eid IN(1, 2, 3), NOT X read_permission Y',
+    ('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y',
      '''SELECT DISTINCT X.cw_eid, Y.cw_eid
-FROM cw_EEType AS X, cw_EGroup AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWEType AS X, cw_CWGroup AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION
 SELECT DISTINCT X.cw_eid, Y.cw_eid
-FROM cw_EEType AS X, cw_RQLExpression AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWEType AS X, cw_RQLExpression AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION
 SELECT DISTINCT X.cw_eid, Y.cw_eid
-FROM cw_EGroup AS Y, cw_ERType AS X
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWGroup AS Y, cw_CWRType AS X
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION
 SELECT DISTINCT X.cw_eid, Y.cw_eid
-FROM cw_ERType AS X, cw_RQLExpression AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)'''),
+FROM cw_CWRType AS X, cw_RQLExpression AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)'''),
     
     # neged relation, can't be inveriant
-    ('Any X,Y WHERE X name "EGroup", Y eid IN(1, 2, 3), NOT X read_permission Y',
+    ('Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y',
      '''SELECT X.cw_eid, Y.cw_eid
-FROM cw_EEType AS X, cw_EGroup AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWEType AS X, cw_CWGroup AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION ALL
 SELECT X.cw_eid, Y.cw_eid
-FROM cw_EEType AS X, cw_RQLExpression AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWEType AS X, cw_RQLExpression AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION ALL
 SELECT X.cw_eid, Y.cw_eid
-FROM cw_EGroup AS Y, cw_ERType AS X
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
+FROM cw_CWGroup AS Y, cw_CWRType AS X
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)
 UNION ALL
 SELECT X.cw_eid, Y.cw_eid
-FROM cw_ERType AS X, cw_RQLExpression AS Y
-WHERE X.cw_name=EGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)'''),
+FROM cw_CWRType AS X, cw_RQLExpression AS Y
+WHERE X.cw_name=CWGroup AND Y.cw_eid IN(1, 2, 3) AND NOT EXISTS(SELECT 1 FROM read_permission_relation AS rel_read_permission0 WHERE rel_read_permission0.eid_from=X.cw_eid AND rel_read_permission0.eid_to=Y.cw_eid)'''),
 
     ('Any MAX(X)+MIN(X), N GROUPBY N WHERE X name N;',
      '''SELECT (MAX(T1.C0) + MIN(T1.C0)), T1.C1 FROM (SELECT X.cw_eid AS C0, X.cw_name AS C1
 FROM cw_Basket AS X
 UNION ALL
 SELECT X.cw_eid AS C0, X.cw_name AS C1
-FROM cw_ECache AS X
+FROM cw_CWCache AS X
 UNION ALL
 SELECT X.cw_eid AS C0, X.cw_name AS C1
-FROM cw_EConstraintType AS X
+FROM cw_CWConstraintType AS X
 UNION ALL
 SELECT X.cw_eid AS C0, X.cw_name AS C1
-FROM cw_EEType AS X
+FROM cw_CWEType AS X
 UNION ALL
 SELECT X.cw_eid AS C0, X.cw_name AS C1
-FROM cw_EGroup AS X
+FROM cw_CWGroup AS X
 UNION ALL
 SELECT X.cw_eid AS C0, X.cw_name AS C1
-FROM cw_EPermission AS X
+FROM cw_CWPermission AS X
 UNION ALL
 SELECT X.cw_eid AS C0, X.cw_name AS C1
-FROM cw_ERType AS X
+FROM cw_CWRType AS X
 UNION ALL
 SELECT X.cw_eid AS C0, X.cw_name AS C1
 FROM cw_File AS X
@@ -523,25 +523,25 @@
 '''),
 
     # ambiguity in EXISTS() -> should union the sub-query
-    ('Any T WHERE T is Tag, NOT T name in ("t1", "t2"), EXISTS(T tags X, X is IN (EUser, EGroup))',
+    ('Any T WHERE T is Tag, NOT T name in ("t1", "t2"), EXISTS(T tags X, X is IN (CWUser, CWGroup))',
      '''SELECT T.cw_eid
 FROM cw_Tag AS T
-WHERE NOT (T.cw_name IN(t1, t2)) AND EXISTS(SELECT 1 FROM tags_relation AS rel_tags0, cw_EGroup AS X WHERE rel_tags0.eid_from=T.cw_eid AND rel_tags0.eid_to=X.cw_eid UNION SELECT 1 FROM tags_relation AS rel_tags1, cw_EUser AS X WHERE rel_tags1.eid_from=T.cw_eid AND rel_tags1.eid_to=X.cw_eid)'''),
+WHERE NOT (T.cw_name IN(t1, t2)) AND EXISTS(SELECT 1 FROM tags_relation AS rel_tags0, cw_CWGroup AS X WHERE rel_tags0.eid_from=T.cw_eid AND rel_tags0.eid_to=X.cw_eid UNION SELECT 1 FROM tags_relation AS rel_tags1, cw_CWUser AS X WHERE rel_tags1.eid_from=T.cw_eid AND rel_tags1.eid_to=X.cw_eid)'''),
 
     # must not use a relation in EXISTS scope to inline a variable 
     ('Any U WHERE U eid IN (1,2), EXISTS(X owned_by U)',
      '''SELECT U.cw_eid
-FROM cw_EUser AS U
+FROM cw_CWUser AS U
 WHERE U.cw_eid IN(1, 2) AND EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0 WHERE rel_owned_by0.eid_to=U.cw_eid)'''),
 
     ('Any U WHERE EXISTS(U eid IN (1,2), X owned_by U)',
      '''SELECT U.cw_eid
-FROM cw_EUser AS U
+FROM cw_CWUser AS U
 WHERE EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0 WHERE U.cw_eid IN(1, 2) AND rel_owned_by0.eid_to=U.cw_eid)'''),
 
     ('Any COUNT(U) WHERE EXISTS (P owned_by U, P is IN (Note, Affaire))',
      '''SELECT COUNT(U.cw_eid)
-FROM cw_EUser AS U
+FROM cw_CWUser AS U
 WHERE EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0, cw_Affaire AS P WHERE rel_owned_by0.eid_from=P.cw_eid AND rel_owned_by0.eid_to=U.cw_eid UNION SELECT 1 FROM owned_by_relation AS rel_owned_by1, cw_Note AS P WHERE rel_owned_by1.eid_from=P.cw_eid AND rel_owned_by1.eid_to=U.cw_eid)'''),
 
     ('Any MAX(X)',
@@ -584,7 +584,7 @@
     
     ('Any X GROUPBY X ORDERBY Y WHERE X eid 12, X login Y',
      '''SELECT X.cw_eid
-FROM cw_EUser AS X
+FROM cw_CWUser AS X
 WHERE X.cw_eid=12
 GROUP BY X.cw_eid
 ORDER BY X.cw_login'''),
@@ -598,12 +598,12 @@
 
     ('DISTINCT Any X ORDERBY stockproc(X) WHERE U login X',
      '''SELECT T1.C0 FROM (SELECT DISTINCT U.cw_login AS C0, STOCKPROC(U.cw_login) AS C1
-FROM cw_EUser AS U
+FROM cw_CWUser AS U
 ORDER BY 2) AS T1'''),
     
     ('DISTINCT Any X ORDERBY Y WHERE B bookmarked_by X, X login Y',
      '''SELECT T1.C0 FROM (SELECT DISTINCT X.cw_eid AS C0, X.cw_login AS C1
-FROM bookmarked_by_relation AS rel_bookmarked_by0, cw_EUser AS X
+FROM bookmarked_by_relation AS rel_bookmarked_by0, cw_CWUser AS X
 WHERE rel_bookmarked_by0.eid_to=X.cw_eid
 ORDER BY 2) AS T1'''),
 
@@ -613,7 +613,7 @@
 WHERE X.cw_in_state=S.cw_eid
 UNION
 SELECT DISTINCT X.cw_eid AS C0, S.cw_name AS C1
-FROM cw_EUser AS X, cw_State AS S
+FROM cw_CWUser AS X, cw_State AS S
 WHERE X.cw_in_state=S.cw_eid
 UNION
 SELECT DISTINCT X.cw_eid AS C0, S.cw_name AS C1
@@ -679,7 +679,7 @@
     
     ('Any S WHERE T is Tag, T name TN, NOT T eid 28258, T tags S, S name SN',
      '''SELECT S.cw_eid
-FROM cw_EGroup AS S, cw_Tag AS T, tags_relation AS rel_tags0
+FROM cw_CWGroup AS S, cw_Tag AS T, tags_relation AS rel_tags0
 WHERE NOT (T.cw_eid=28258) AND rel_tags0.eid_from=T.cw_eid AND rel_tags0.eid_to=S.cw_eid
 UNION ALL
 SELECT S.cw_eid
@@ -707,7 +707,7 @@
 WHERE NOT EXISTS(SELECT 1 FROM evaluee_relation AS rel_evaluee0 WHERE rel_evaluee0.eid_from=Y.cw_eid)
 UNION ALL
 SELECT Y.cw_eid
-FROM cw_EUser AS Y
+FROM cw_CWUser AS Y
 WHERE NOT EXISTS(SELECT 1 FROM evaluee_relation AS rel_evaluee0 WHERE rel_evaluee0.eid_from=Y.cw_eid)
 UNION ALL
 SELECT Y.cw_eid
@@ -722,10 +722,10 @@
 FROM cw_SubDivision AS Y
 WHERE NOT EXISTS(SELECT 1 FROM evaluee_relation AS rel_evaluee0 WHERE rel_evaluee0.eid_from=Y.cw_eid)'''),
 
-    ('Any X WHERE NOT Y evaluee X, Y is EUser',
+    ('Any X WHERE NOT Y evaluee X, Y is CWUser',
      '''SELECT X.cw_eid
 FROM cw_Note AS X
-WHERE NOT EXISTS(SELECT 1 FROM evaluee_relation AS rel_evaluee0,cw_EUser AS Y WHERE rel_evaluee0.eid_from=Y.cw_eid AND rel_evaluee0.eid_to=X.cw_eid)'''),
+WHERE NOT EXISTS(SELECT 1 FROM evaluee_relation AS rel_evaluee0,cw_CWUser AS Y WHERE rel_evaluee0.eid_from=Y.cw_eid AND rel_evaluee0.eid_to=X.cw_eid)'''),
     
     ('Any X,T WHERE X title T, NOT X is Bookmark',
      '''SELECT DISTINCT X.cw_eid, X.cw_title
@@ -734,18 +734,18 @@
 SELECT DISTINCT X.cw_eid, X.cw_title
 FROM cw_EmailThread AS X'''),
 
-    ('Any K,V WHERE P is EProperty, P pkey K, P value V, NOT P for_user U',
+    ('Any K,V WHERE P is CWProperty, P pkey K, P value V, NOT P for_user U',
      '''SELECT DISTINCT P.cw_pkey, P.cw_value
-FROM cw_EProperty AS P
+FROM cw_CWProperty AS P
 WHERE P.cw_for_user IS NULL'''),
 
-    ('Any S WHERE NOT X in_state S, X is IN(Affaire, EUser)',
+    ('Any S WHERE NOT X in_state S, X is IN(Affaire, CWUser)',
      '''SELECT DISTINCT S.cw_eid
 FROM cw_Affaire AS X, cw_State AS S
 WHERE (X.cw_in_state IS NULL OR X.cw_in_state!=S.cw_eid)
 INTERSECT
 SELECT DISTINCT S.cw_eid
-FROM cw_EUser AS X, cw_State AS S
+FROM cw_CWUser AS X, cw_State AS S
 WHERE (X.cw_in_state IS NULL OR X.cw_in_state!=S.cw_eid)'''),
     ]
 
@@ -791,7 +791,7 @@
     ('Any X WHERE X is Affaire, S is Societe, EXISTS(X owned_by U OR (X concerne S?, S owned_by U))',
      '''SELECT X.cw_eid
 FROM cw_Affaire AS X
-WHERE EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0, cw_EUser AS U, cw_Affaire AS A LEFT OUTER JOIN concerne_relation AS rel_concerne1 ON (rel_concerne1.eid_from=A.cw_eid) LEFT OUTER JOIN cw_Societe AS S ON (rel_concerne1.eid_to=S.cw_eid), owned_by_relation AS rel_owned_by2 WHERE ((rel_owned_by0.eid_from=A.cw_eid AND rel_owned_by0.eid_to=U.cw_eid) OR (rel_owned_by2.eid_from=S.cw_eid AND rel_owned_by2.eid_to=U.cw_eid)) AND X.cw_eid=A.cw_eid)'''),
+WHERE EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0, cw_CWUser AS U, cw_Affaire AS A LEFT OUTER JOIN concerne_relation AS rel_concerne1 ON (rel_concerne1.eid_from=A.cw_eid) LEFT OUTER JOIN cw_Societe AS S ON (rel_concerne1.eid_to=S.cw_eid), owned_by_relation AS rel_owned_by2 WHERE ((rel_owned_by0.eid_from=A.cw_eid AND rel_owned_by0.eid_to=U.cw_eid) OR (rel_owned_by2.eid_from=S.cw_eid AND rel_owned_by2.eid_to=U.cw_eid)) AND X.cw_eid=A.cw_eid)'''),
 
     ('Any C,M WHERE C travaille G?, G evaluee M?, G is Societe',
      '''SELECT C.cw_eid, rel_evaluee1.eid_to
@@ -804,7 +804,7 @@
      'F name "read", F require_group E, U in_group E)), U eid 1',
      '''SELECT A.cw_eid, rel_documented_by0.eid_to
 FROM cw_Affaire AS A LEFT OUTER JOIN documented_by_relation AS rel_documented_by0 ON (rel_documented_by0.eid_from=A.cw_eid)
-WHERE ((rel_documented_by0.eid_to IS NULL) OR (EXISTS(SELECT 1 FROM require_permission_relation AS rel_require_permission1, cw_EPermission AS F, require_group_relation AS rel_require_group2, in_group_relation AS rel_in_group3 WHERE rel_documented_by0.eid_to=rel_require_permission1.eid_from AND rel_require_permission1.eid_to=F.cw_eid AND F.cw_name=read AND rel_require_group2.eid_from=F.cw_eid AND rel_in_group3.eid_to=rel_require_group2.eid_to AND rel_in_group3.eid_from=1)))'''),
+WHERE ((rel_documented_by0.eid_to IS NULL) OR (EXISTS(SELECT 1 FROM require_permission_relation AS rel_require_permission1, cw_CWPermission AS F, require_group_relation AS rel_require_group2, in_group_relation AS rel_in_group3 WHERE rel_documented_by0.eid_to=rel_require_permission1.eid_from AND rel_require_permission1.eid_to=F.cw_eid AND F.cw_name=read AND rel_require_group2.eid_from=F.cw_eid AND rel_in_group3.eid_to=rel_require_group2.eid_to AND rel_in_group3.eid_from=1)))'''),
 
     ("Any X WHERE X eid 12, P? connait X",
      '''SELECT X.cw_eid
@@ -818,7 +818,7 @@
     ('Any GN, TN ORDERBY GN WHERE T tags G?, T name TN, G name GN',
     '''SELECT _T0.C1, T.cw_name
 FROM cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid) LEFT OUTER JOIN (SELECT G.cw_eid AS C0, G.cw_name AS C1
-FROM cw_EGroup AS G
+FROM cw_CWGroup AS G
 UNION ALL
 SELECT G.cw_eid AS C0, G.cw_name AS C1
 FROM cw_State AS G
@@ -829,9 +829,9 @@
 
 
     # optional variable with additional restriction
-    ('Any T,G WHERE T tags G?, G name "hop", G is EGroup',
+    ('Any T,G WHERE T tags G?, G name "hop", G is CWGroup',
      '''SELECT T.cw_eid, G.cw_eid
-FROM cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid) LEFT OUTER JOIN cw_EGroup AS G ON (rel_tags0.eid_to=G.cw_eid AND G.cw_name=hop)'''),
+FROM cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid) LEFT OUTER JOIN cw_CWGroup AS G ON (rel_tags0.eid_to=G.cw_eid AND G.cw_name=hop)'''),
 
     # optional variable with additional invariant restriction
     ('Any T,G WHERE T tags G?, G eid 12',
@@ -839,33 +839,33 @@
 FROM cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid AND rel_tags0.eid_to=12)'''),
 
     # optional variable with additional restriction appearing before the relation
-    ('Any T,G WHERE G name "hop", T tags G?, G is EGroup',
+    ('Any T,G WHERE G name "hop", T tags G?, G is CWGroup',
      '''SELECT T.cw_eid, G.cw_eid
-FROM cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid) LEFT OUTER JOIN cw_EGroup AS G ON (rel_tags0.eid_to=G.cw_eid AND G.cw_name=hop)'''),
+FROM cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid) LEFT OUTER JOIN cw_CWGroup AS G ON (rel_tags0.eid_to=G.cw_eid AND G.cw_name=hop)'''),
 
     # optional variable with additional restriction on inlined relation
     # XXX the expected result should be as the query below. So what, raise BadRQLQuery ?
-    ('Any T,G,S WHERE T tags G?, G in_state S, S name "hop", G is EUser',
+    ('Any T,G,S WHERE T tags G?, G in_state S, S name "hop", G is CWUser',
      '''SELECT T.cw_eid, G.cw_eid, S.cw_eid
-FROM cw_State AS S, cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid) LEFT OUTER JOIN cw_EUser AS G ON (rel_tags0.eid_to=G.cw_eid)
+FROM cw_State AS S, cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid) LEFT OUTER JOIN cw_CWUser AS G ON (rel_tags0.eid_to=G.cw_eid)
 WHERE G.cw_in_state=S.cw_eid AND S.cw_name=hop
 '''),
 
     # optional variable with additional invariant restriction on an inlined relation
-    ('Any T,G,S WHERE T tags G, G in_state S?, S eid 1, G is EUser',
+    ('Any T,G,S WHERE T tags G, G in_state S?, S eid 1, G is CWUser',
      '''SELECT rel_tags0.eid_from, G.cw_eid, G.cw_in_state
-FROM cw_EUser AS G, tags_relation AS rel_tags0
+FROM cw_CWUser AS G, tags_relation AS rel_tags0
 WHERE rel_tags0.eid_to=G.cw_eid AND (G.cw_in_state=1 OR G.cw_in_state IS NULL)'''),
 
     # two optional variables with additional invariant restriction on an inlined relation
-    ('Any T,G,S WHERE T tags G?, G in_state S?, S eid 1, G is EUser',
+    ('Any T,G,S WHERE T tags G?, G in_state S?, S eid 1, G is CWUser',
      '''SELECT T.cw_eid, G.cw_eid, G.cw_in_state
-FROM cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid) LEFT OUTER JOIN cw_EUser AS G ON (rel_tags0.eid_to=G.cw_eid AND (G.cw_in_state=1 OR G.cw_in_state IS NULL))'''),
+FROM cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid) LEFT OUTER JOIN cw_CWUser AS G ON (rel_tags0.eid_to=G.cw_eid AND (G.cw_in_state=1 OR G.cw_in_state IS NULL))'''),
 
     # two optional variables with additional restriction on an inlined relation
-    ('Any T,G,S WHERE T tags G?, G in_state S?, S name "hop", G is EUser',
+    ('Any T,G,S WHERE T tags G?, G in_state S?, S name "hop", G is CWUser',
      '''SELECT T.cw_eid, G.cw_eid, S.cw_eid
-FROM cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid) LEFT OUTER JOIN cw_EUser AS G ON (rel_tags0.eid_to=G.cw_eid) LEFT OUTER JOIN cw_State AS S ON (G.cw_in_state=S.cw_eid AND S.cw_name=hop)'''),
+FROM cw_Tag AS T LEFT OUTER JOIN tags_relation AS rel_tags0 ON (rel_tags0.eid_from=T.cw_eid) LEFT OUTER JOIN cw_CWUser AS G ON (rel_tags0.eid_to=G.cw_eid) LEFT OUTER JOIN cw_State AS S ON (G.cw_in_state=S.cw_eid AND S.cw_name=hop)'''),
     
     # two optional variables with additional restriction on an ambigous inlined relation
     ('Any T,G,S WHERE T tags G?, G in_state S?, S name "hop"',
@@ -874,7 +874,7 @@
 FROM cw_Affaire AS G LEFT OUTER JOIN cw_State AS S ON (G.cw_in_state=S.cw_eid AND S.cw_name=hop) 
 UNION ALL
 SELECT G.cw_eid AS C0, S.cw_eid AS C1
-FROM cw_EUser AS G LEFT OUTER JOIN cw_State AS S ON (G.cw_in_state=S.cw_eid AND S.cw_name=hop) 
+FROM cw_CWUser AS G LEFT OUTER JOIN cw_State AS S ON (G.cw_in_state=S.cw_eid AND S.cw_name=hop) 
 UNION ALL
 SELECT G.cw_eid AS C0, S.cw_eid AS C1
 FROM cw_Note AS G LEFT OUTER JOIN cw_State AS S ON (G.cw_in_state=S.cw_eid AND S.cw_name=hop) ) AS _T0 ON (rel_tags0.eid_to=_T0.C0)'''),
@@ -1039,17 +1039,17 @@
 FROM cw_Note AS N, cw_Personne AS P
 WHERE (N.cw_ecrit_par IS NULL OR N.cw_ecrit_par!=P.cw_eid) AND N.cw_eid=512'''),
 
-    ('Any S,ES,T WHERE S state_of ET, ET name "EUser", ES allowed_transition T, T destination_state S',
+    ('Any S,ES,T WHERE S state_of ET, ET name "CWUser", ES allowed_transition T, T destination_state S',
      '''SELECT T.cw_destination_state, rel_allowed_transition1.eid_from, T.cw_eid
-FROM allowed_transition_relation AS rel_allowed_transition1, cw_EEType AS ET, cw_Transition AS T, state_of_relation AS rel_state_of0
-WHERE T.cw_destination_state=rel_state_of0.eid_from AND rel_state_of0.eid_to=ET.cw_eid AND ET.cw_name=EUser AND rel_allowed_transition1.eid_to=T.cw_eid'''),
+FROM allowed_transition_relation AS rel_allowed_transition1, cw_CWEType AS ET, cw_Transition AS T, state_of_relation AS rel_state_of0
+WHERE T.cw_destination_state=rel_state_of0.eid_from AND rel_state_of0.eid_to=ET.cw_eid AND ET.cw_name=CWUser AND rel_allowed_transition1.eid_to=T.cw_eid'''),
     ('Any O WHERE S eid 0, S in_state O',
      '''SELECT S.cw_in_state
 FROM cw_Affaire AS S
 WHERE S.cw_eid=0 AND S.cw_in_state IS NOT NULL
 UNION ALL
 SELECT S.cw_in_state
-FROM cw_EUser AS S
+FROM cw_CWUser AS S
 WHERE S.cw_eid=0 AND S.cw_in_state IS NOT NULL
 UNION ALL
 SELECT S.cw_in_state
@@ -1065,7 +1065,7 @@
 WHERE (X.cw_in_state IS NULL OR X.cw_in_state!=S.cw_eid)
 INTERSECT
 SELECT DISTINCT S.cw_name
-FROM cw_EUser AS X, cw_State AS S
+FROM cw_CWUser AS X, cw_State AS S
 WHERE (X.cw_in_state IS NULL OR X.cw_in_state!=S.cw_eid)
 INTERSECT
 SELECT DISTINCT S.cw_name
@@ -1171,11 +1171,11 @@
     def test1(self):
         self._checkall('Any count(RDEF) WHERE RDEF relation_type X, X eid %(x)s',
                        ("""SELECT COUNT(T1.C0) FROM (SELECT RDEF.cw_eid AS C0
-FROM cw_EFRDef AS RDEF
+FROM cw_CWAttribute AS RDEF
 WHERE RDEF.cw_relation_type=%(x)s
 UNION ALL
 SELECT RDEF.cw_eid AS C0
-FROM cw_ENFRDef AS RDEF
+FROM cw_CWRelation AS RDEF
 WHERE RDEF.cw_relation_type=%(x)s) AS T1""", {}),
                        )
 
@@ -1198,14 +1198,14 @@
 WHERE rel_in_basket0.eid_to=12''')
 
     def test_varmap(self):
-        self._check('Any X,L WHERE X is EUser, X in_group G, X login L, G name "users"',
+        self._check('Any X,L WHERE X is CWUser, X in_group G, X login L, G name "users"',
                     '''SELECT T00.x, T00.l
-FROM T00, cw_EGroup AS G, in_group_relation AS rel_in_group0
+FROM T00, cw_CWGroup AS G, in_group_relation AS rel_in_group0
 WHERE rel_in_group0.eid_from=T00.x AND rel_in_group0.eid_to=G.cw_eid AND G.cw_name=users''',
                     varmap={'X': 'T00.x', 'X.login': 'T00.l'})
-        self._check('Any X,L,GN WHERE X is EUser, X in_group G, X login L, G name GN',
+        self._check('Any X,L,GN WHERE X is CWUser, X in_group G, X login L, G name GN',
                     '''SELECT T00.x, T00.l, G.cw_name
-FROM T00, cw_EGroup AS G, in_group_relation AS rel_in_group0
+FROM T00, cw_CWGroup AS G, in_group_relation AS rel_in_group0
 WHERE rel_in_group0.eid_from=T00.x AND rel_in_group0.eid_to=G.cw_eid''',
                     varmap={'X': 'T00.x', 'X.login': 'T00.l'})
 
@@ -1311,7 +1311,7 @@
 UNION ALL
 (SELECT X.cw_eid AS C0
 FROM cw_Affaire AS X
-WHERE ((EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0 WHERE rel_owned_by0.eid_from=X.cw_eid AND rel_owned_by0.eid_to=1)) OR (((EXISTS(SELECT 1 FROM cw_Affaire AS D LEFT OUTER JOIN concerne_relation AS rel_concerne1 ON (rel_concerne1.eid_from=D.cw_eid) LEFT OUTER JOIN cw_Note AS B ON (rel_concerne1.eid_to=B.cw_eid), owned_by_relation AS rel_owned_by2 WHERE rel_owned_by2.eid_from=B.cw_eid AND rel_owned_by2.eid_to=1 AND X.cw_eid=D.cw_eid)) OR (EXISTS(SELECT 1 FROM cw_Affaire AS F LEFT OUTER JOIN concerne_relation AS rel_concerne3 ON (rel_concerne3.eid_from=F.cw_eid) LEFT OUTER JOIN cw_Societe AS E ON (rel_concerne3.eid_to=E.cw_eid), owned_by_relation AS rel_owned_by4 WHERE rel_owned_by4.eid_from=E.cw_eid AND rel_owned_by4.eid_to=1 AND X.cw_eid=F.cw_eid))))))) AS _T0, cw_EEType AS ET, is_relation AS rel_is0
+WHERE ((EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0 WHERE rel_owned_by0.eid_from=X.cw_eid AND rel_owned_by0.eid_to=1)) OR (((EXISTS(SELECT 1 FROM cw_Affaire AS D LEFT OUTER JOIN concerne_relation AS rel_concerne1 ON (rel_concerne1.eid_from=D.cw_eid) LEFT OUTER JOIN cw_Note AS B ON (rel_concerne1.eid_to=B.cw_eid), owned_by_relation AS rel_owned_by2 WHERE rel_owned_by2.eid_from=B.cw_eid AND rel_owned_by2.eid_to=1 AND X.cw_eid=D.cw_eid)) OR (EXISTS(SELECT 1 FROM cw_Affaire AS F LEFT OUTER JOIN concerne_relation AS rel_concerne3 ON (rel_concerne3.eid_from=F.cw_eid) LEFT OUTER JOIN cw_Societe AS E ON (rel_concerne3.eid_to=E.cw_eid), owned_by_relation AS rel_owned_by4 WHERE rel_owned_by4.eid_from=E.cw_eid AND rel_owned_by4.eid_to=1 AND X.cw_eid=F.cw_eid))))))) AS _T0, cw_CWEType AS ET, is_relation AS rel_is0
 WHERE rel_is0.eid_from=_T0.C0 AND rel_is0.eid_to=ET.cw_eid
 GROUP BY ET.cw_name'''),
             )):
@@ -1389,9 +1389,9 @@
 
 
     def test_from_clause_needed(self):
-        queries = [("Any 1 WHERE EXISTS(T is EGroup, T name 'managers')",
+        queries = [("Any 1 WHERE EXISTS(T is CWGroup, T name 'managers')",
                     '''SELECT 1
-WHERE EXISTS(SELECT 1 FROM cw_EGroup AS T WHERE T.cw_name=managers)'''),
+WHERE EXISTS(SELECT 1 FROM cw_CWGroup AS T WHERE T.cw_name=managers)'''),
                    ('Any X,Y WHERE NOT X created_by Y, X eid 5, Y eid 6',
                     '''SELECT 5, 6
 WHERE NOT EXISTS(SELECT 1 FROM created_by_relation AS rel_created_by0 WHERE rel_created_by0.eid_from=5 AND rel_created_by0.eid_to=6)'''),
@@ -1548,10 +1548,10 @@
         return sql.strip().replace(' ILIKE ', ' LIKE ')
 
     def test_from_clause_needed(self):
-        queries = [("Any 1 WHERE EXISTS(T is EGroup, T name 'managers')",
+        queries = [("Any 1 WHERE EXISTS(T is CWGroup, T name 'managers')",
                     '''SELECT 1
 FROM (SELECT 1) AS _T
-WHERE EXISTS(SELECT 1 FROM cw_EGroup AS T WHERE T.cw_name=managers)'''),
+WHERE EXISTS(SELECT 1 FROM cw_CWGroup AS T WHERE T.cw_name=managers)'''),
                    ('Any X,Y WHERE NOT X created_by Y, X eid 5, Y eid 6',
                     '''SELECT 5, 6
 FROM (SELECT 1) AS _T
--- a/server/test/unittest_rqlannotation.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_rqlannotation.py	Fri Apr 24 19:46:47 2009 +0200
@@ -37,7 +37,7 @@
         self.assert_(rqlst.defined_vars['B'].stinfo['attrvar'])
         self.assertEquals(rqlst.defined_vars['C']._q_invariant, False)
         self.assertEquals(rqlst.solutions, [{'A': 'TrInfo', 'B': 'String', 'C': 'Affaire'},
-                                      {'A': 'TrInfo', 'B': 'String', 'C': 'EUser'},
+                                      {'A': 'TrInfo', 'B': 'String', 'C': 'CWUser'},
                                       {'A': 'TrInfo', 'B': 'String', 'C': 'Note'}])
 
     def test_0_5(self):        
@@ -176,7 +176,7 @@
         self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
         
     def test_not_relation_4_4(self):
-        rqlst = self._prepare('Any X WHERE NOT Y evaluee X, Y is EUser')
+        rqlst = self._prepare('Any X WHERE NOT Y evaluee X, Y is CWUser')
         self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
         self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
 
@@ -186,12 +186,12 @@
         self.assertEquals(rqlst.solutions, [{'X': 'Note'}])
         
     def test_not_relation_5_1(self):
-        rqlst = self._prepare('Any X,Y WHERE X name "EGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
+        rqlst = self._prepare('Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
         self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
         self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
 
     def test_not_relation_5_2(self):
-        rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "EGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
+        rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
         self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
         self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
 
@@ -201,7 +201,7 @@
         self.assertEquals(rqlst.defined_vars['A']._q_invariant, True)
 
     def test_not_relation_7(self):
-        rqlst = self._prepare('Any K,V WHERE P is EProperty, P pkey K, P value V, NOT P for_user U') 
+        rqlst = self._prepare('Any K,V WHERE P is CWProperty, P pkey K, P value V, NOT P for_user U') 
         self.assertEquals(rqlst.defined_vars['P']._q_invariant, False)
         self.assertEquals(rqlst.defined_vars['U']._q_invariant, True)
        
@@ -221,12 +221,12 @@
         self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
         
     def test_exists_4(self):
-        rqlst = self._prepare('Any X,Y WHERE X name "EGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)')
+        rqlst = self._prepare('Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)')
         self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
         self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
         
     def test_exists_5(self):
-        rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "EGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)')
+        rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)')
         self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
         self.assertEquals(rqlst.defined_vars['Y']._q_invariant, True)
 
@@ -236,11 +236,11 @@
         self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)        
 
     def test_not_exists_2(self):        
-        rqlst = self._prepare('Any X,Y WHERE X name "EGroup", Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)')
+        rqlst = self._prepare('Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)')
         self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
 
     def test_not_exists_distinct_1(self):        
-        rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "EGroup", Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)')
+        rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)')
         self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
         
     def test_or_1(self):        
--- a/server/test/unittest_rqlrewrite.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_rqlrewrite.py	Fri Apr 24 19:46:47 2009 +0200
@@ -22,7 +22,7 @@
     repotest.undo_monkey_patch()
     
 def eid_func_map(eid):
-    return {1: 'EUser',
+    return {1: 'CWUser',
             2: 'Card'}[eid]
 
 def rewrite(rqlst, snippets_map, kwargs):
@@ -74,7 +74,7 @@
         self.failUnlessEqual(rqlst.as_string(),
                              u"Any C WHERE C is Card, B eid %(D)s, "
                              "EXISTS(C in_state A, B in_group E, F require_state A, "
-                             "F name 'read', F require_group E, A is State, E is EGroup, F is EPermission)")
+                             "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission)")
         
     def test_multiple_var(self):
         card_constraint = ('X in_state S, U in_group G, P require_state S,'
@@ -87,8 +87,8 @@
         self.assertTextEquals(rqlst.as_string(),
                              "Any S WHERE S documented_by C, C eid %(u)s, B eid %(D)s, "
                              "EXISTS(C in_state A, B in_group E, F require_state A, "
-                             "F name 'read', F require_group E, A is State, E is EGroup, F is EPermission), "
-                             "(EXISTS(S ref LIKE 'PUBLIC%')) OR (EXISTS(B in_group G, G name 'public', G is EGroup)), "
+                             "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission), "
+                             "(EXISTS(S ref LIKE 'PUBLIC%')) OR (EXISTS(B in_group G, G name 'public', G is CWGroup)), "
                              "S is Affaire")
         self.failUnless('D' in kwargs)
         
@@ -99,8 +99,8 @@
         self.failUnlessEqual(rqlst.as_string(),
                              "Any S WHERE S owned_by C, C eid %(u)s, A eid %(B)s, "
                              "EXISTS((C identity A) OR (C in_state D, E identity A, "
-                             "E in_state D, D name 'subscribed'), D is State, E is EUser), "
-                             "S is IN(Affaire, Basket, Bookmark, Card, Comment, Division, ECache, EConstraint, EConstraintType, EEType, EFRDef, EGroup, ENFRDef, EPermission, EProperty, ERType, EUser, Email, EmailAddress, EmailPart, EmailThread, File, Folder, Image, Note, Personne, RQLExpression, Societe, State, SubDivision, Tag, TrInfo, Transition)")
+                             "E in_state D, D name 'subscribed'), D is State, E is CWUser), "
+                             "S is IN(Affaire, Basket, Bookmark, Card, Comment, Division, CWCache, CWConstraint, CWConstraintType, CWEType, CWAttribute, CWGroup, CWRelation, CWPermission, CWProperty, CWRType, CWUser, Email, EmailAddress, EmailPart, EmailThread, File, Folder, Image, Note, Personne, RQLExpression, Societe, State, SubDivision, Tag, TrInfo, Transition)")
 
     def test_simplified_rqlst(self):
         card_constraint = ('X in_state S, U in_group G, P require_state S,'
@@ -110,7 +110,7 @@
         self.failUnlessEqual(rqlst.as_string(),
                              u"Any 2 WHERE B eid %(C)s, "
                              "EXISTS(2 in_state A, B in_group D, E require_state A, "
-                             "E name 'read', E require_group D, A is State, D is EGroup, E is EPermission)")
+                             "E name 'read', E require_group D, A is State, D is CWGroup, E is CWPermission)")
 
     def test_optional_var(self):
         card_constraint = ('X in_state S, U in_group G, P require_state S,'
@@ -141,22 +141,22 @@
         self.failUnlessEqual(rqlst.as_string(),
                              u"Any C WHERE C in_state STATE, C is Card, A eid %(B)s, "
                              "EXISTS(A in_group D, E require_state STATE, "
-                             "E name 'read', E require_group D, D is EGroup, E is EPermission), "
+                             "E name 'read', E require_group D, D is CWGroup, E is CWPermission), "
                              "STATE is State")
 
     def test_unsupported_constraint_1(self):
-        # EUser doesn't have require_permission
+        # CWUser doesn't have require_permission
         trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"')
-        rqlst = parse('Any U,T WHERE U is EUser, T wf_info_for U')
+        rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U')
         self.assertRaises(Unauthorized, rewrite, rqlst, {'T': (trinfo_constraint,)}, {})
         
     def test_unsupported_constraint_2(self):
         trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"')
-        rqlst = parse('Any U,T WHERE U is EUser, T wf_info_for U')
+        rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U')
         rewrite(rqlst, {'T': (trinfo_constraint, 'X wf_info_for Y, Y in_group G, G name "managers"')}, {})
         self.failUnlessEqual(rqlst.as_string(),
-                             u"Any U,T WHERE U is EUser, T wf_info_for U, "
-                             "EXISTS(U in_group B, B name 'managers', B is EGroup), T is TrInfo")
+                             u"Any U,T WHERE U is CWUser, T wf_info_for U, "
+                             "EXISTS(U in_group B, B name 'managers', B is CWGroup), T is TrInfo")
 
     def test_unsupported_constraint_3(self):
         self.skip('raise unauthorized for now')
--- a/server/test/unittest_schemaserial.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_schemaserial.py	Fri Apr 24 19:46:47 2009 +0200
@@ -20,16 +20,16 @@
 class Schema2RQLTC(TestCase):
         
     def test_eschema2rql1(self):
-        self.assertListEquals(list(eschema2rql(schema.eschema('EFRDef'))),
+        self.assertListEquals(list(eschema2rql(schema.eschema('CWAttribute'))),
                               [
-            ('INSERT EEType X: X description %(description)s,X final %(final)s,X meta %(meta)s,X name %(name)s',
+            ('INSERT CWEType X: X description %(description)s,X final %(final)s,X meta %(meta)s,X name %(name)s',
              {'description': u'define a final relation: link a final relation type from a non final entity to a final entity type. used to build the application schema',
-              'meta': True, 'name': u'EFRDef', 'final': False})
+              'meta': True, 'name': u'CWAttribute', 'final': False})
             ])
         
     def test_eschema2rql2(self):
         self.assertListEquals(list(eschema2rql(schema.eschema('String'))), [
-                ('INSERT EEType X: X description %(description)s,X final %(final)s,X meta %(meta)s,X name %(name)s',
+                ('INSERT CWEType X: X description %(description)s,X final %(final)s,X meta %(meta)s,X name %(name)s',
                  {'description': u'', 'final': True, 'meta': True, 'name': u'String'})])
     
     def test_eschema2rql_specialization(self):
@@ -43,32 +43,32 @@
     def test_rschema2rql1(self):
         self.assertListEquals(list(rschema2rql(schema.rschema('relation_type'))),
                              [
-            ('INSERT ERType X: X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X meta %(meta)s,X name %(name)s,X symetric %(symetric)s',
+            ('INSERT CWRType X: X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X meta %(meta)s,X name %(name)s,X symetric %(symetric)s',
              {'description': u'link a relation definition to its relation type', 'meta': True, 'symetric': False, 'name': u'relation_type', 'final' : False, 'fulltext_container': None, 'inlined': True}),
-            ('INSERT ENFRDef X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
-             {'rt': 'relation_type', 'description': u'', 'composite': u'object', 'oe': 'ERType',
-              'ordernum': 1, 'cardinality': u'1*', 'se': 'EFRDef'}),
-            ('INSERT EConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is ENFRDef',
-             {'rt': 'relation_type', 'oe': 'ERType', 'ctname': u'RQLConstraint', 'se': 'EFRDef', 'value': u'O final TRUE'}),
-            ('INSERT ENFRDef X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
-             {'rt': 'relation_type', 'description': u'', 'composite': u'object', 'oe': 'ERType',
-              'ordernum': 1, 'cardinality': u'1*', 'se': 'ENFRDef'}),
-            ('INSERT EConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is ENFRDef',
-             {'rt': 'relation_type', 'oe': 'ERType', 'ctname': u'RQLConstraint', 'se': 'ENFRDef', 'value': u'O final FALSE'}),
+            ('INSERT CWRelation X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
+             {'rt': 'relation_type', 'description': u'', 'composite': u'object', 'oe': 'CWRType',
+              'ordernum': 1, 'cardinality': u'1*', 'se': 'CWAttribute'}),
+            ('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is CWRelation',
+             {'rt': 'relation_type', 'oe': 'CWRType', 'ctname': u'RQLConstraint', 'se': 'CWAttribute', 'value': u'O final TRUE'}),
+            ('INSERT CWRelation X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
+             {'rt': 'relation_type', 'description': u'', 'composite': u'object', 'oe': 'CWRType',
+              'ordernum': 1, 'cardinality': u'1*', 'se': 'CWRelation'}),
+            ('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is CWRelation',
+             {'rt': 'relation_type', 'oe': 'CWRType', 'ctname': u'RQLConstraint', 'se': 'CWRelation', 'value': u'O final FALSE'}),
             ])
         
     def test_rschema2rql2(self):
         expected = [
-            ('INSERT ERType X: X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X meta %(meta)s,X name %(name)s,X symetric %(symetric)s', {'description': u'core relation giving to a group the permission to add an entity or relation type', 'meta': True, 'symetric': False, 'name': u'add_permission', 'final': False, 'fulltext_container': None, 'inlined': False}),
-            ('INSERT ENFRDef X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
-             {'rt': 'add_permission', 'description': u'rql expression allowing to add entities/relations of this type', 'composite': 'subject', 'oe': 'RQLExpression', 'ordernum': 5, 'cardinality': u'*?', 'se': 'EEType'}),
-            ('INSERT ENFRDef X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
-             {'rt': 'add_permission', 'description': u'rql expression allowing to add entities/relations of this type', 'composite': 'subject', 'oe': 'RQLExpression', 'ordernum': 5, 'cardinality': u'*?', 'se': 'ERType'}),
+            ('INSERT CWRType X: X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X meta %(meta)s,X name %(name)s,X symetric %(symetric)s', {'description': u'core relation giving to a group the permission to add an entity or relation type', 'meta': True, 'symetric': False, 'name': u'add_permission', 'final': False, 'fulltext_container': None, 'inlined': False}),
+            ('INSERT CWRelation X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
+             {'rt': 'add_permission', 'description': u'rql expression allowing to add entities/relations of this type', 'composite': 'subject', 'oe': 'RQLExpression', 'ordernum': 5, 'cardinality': u'*?', 'se': 'CWEType'}),
+            ('INSERT CWRelation X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
+             {'rt': 'add_permission', 'description': u'rql expression allowing to add entities/relations of this type', 'composite': 'subject', 'oe': 'RQLExpression', 'ordernum': 5, 'cardinality': u'*?', 'se': 'CWRType'}),
             
-            ('INSERT ENFRDef X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
-             {'rt': 'add_permission', 'description': u'groups allowed to add entities/relations of this type', 'composite': None, 'oe': 'EGroup', 'ordernum': 3, 'cardinality': u'**', 'se': 'EEType'}),
-            ('INSERT ENFRDef X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
-             {'rt': 'add_permission', 'description': u'groups allowed to add entities/relations of this type', 'composite': None, 'oe': 'EGroup', 'ordernum': 3, 'cardinality': u'**', 'se': 'ERType'}),
+            ('INSERT CWRelation X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
+             {'rt': 'add_permission', 'description': u'groups allowed to add entities/relations of this type', 'composite': None, 'oe': 'CWGroup', 'ordernum': 3, 'cardinality': u'**', 'se': 'CWEType'}),
+            ('INSERT CWRelation X: X cardinality %(cardinality)s,X composite %(composite)s,X description %(description)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
+             {'rt': 'add_permission', 'description': u'groups allowed to add entities/relations of this type', 'composite': None, 'oe': 'CWGroup', 'ordernum': 3, 'cardinality': u'**', 'se': 'CWRType'}),
             ]
         for i, (rql, args) in enumerate(rschema2rql(schema.rschema('add_permission'))):
             yield self.assertEquals, (rql, args), expected[i]
@@ -76,41 +76,41 @@
     def test_rschema2rql3(self):
         self.assertListEquals(list(rschema2rql(schema.rschema('cardinality'))), 
                              [
-            ('INSERT ERType X: X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X meta %(meta)s,X name %(name)s,X symetric %(symetric)s',
+            ('INSERT CWRType X: X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X meta %(meta)s,X name %(name)s,X symetric %(symetric)s',
              {'description': u'', 'meta': False, 'symetric': False, 'name': u'cardinality', 'final': True, 'fulltext_container': None, 'inlined': False}),
 
-            ('INSERT EFRDef X: X cardinality %(cardinality)s,X defaultval %(defaultval)s,X description %(description)s,X fulltextindexed %(fulltextindexed)s,X indexed %(indexed)s,X internationalizable %(internationalizable)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
-             {'rt': 'cardinality', 'description': u'subject/object cardinality', 'internationalizable': True, 'fulltextindexed': False, 'ordernum': 5, 'defaultval': None, 'indexed': False, 'cardinality': u'?1', 'oe': 'String', 'se': 'EFRDef'}),
-            ('INSERT EConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is EFRDef',
-             {'rt': 'cardinality', 'oe': 'String', 'ctname': u'SizeConstraint', 'se': 'EFRDef', 'value': u'max=2'}),
-            ('INSERT EConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is EFRDef',
-             {'rt': 'cardinality', 'oe': 'String', 'ctname': u'StaticVocabularyConstraint', 'se': 'EFRDef', 'value': u"u'?1', u'11', u'??', u'1?'"}),
+            ('INSERT CWAttribute X: X cardinality %(cardinality)s,X defaultval %(defaultval)s,X description %(description)s,X fulltextindexed %(fulltextindexed)s,X indexed %(indexed)s,X internationalizable %(internationalizable)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
+             {'rt': 'cardinality', 'description': u'subject/object cardinality', 'internationalizable': True, 'fulltextindexed': False, 'ordernum': 5, 'defaultval': None, 'indexed': False, 'cardinality': u'?1', 'oe': 'String', 'se': 'CWAttribute'}),
+            ('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is CWAttribute',
+             {'rt': 'cardinality', 'oe': 'String', 'ctname': u'SizeConstraint', 'se': 'CWAttribute', 'value': u'max=2'}),
+            ('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is CWAttribute',
+             {'rt': 'cardinality', 'oe': 'String', 'ctname': u'StaticVocabularyConstraint', 'se': 'CWAttribute', 'value': u"u'?1', u'11', u'??', u'1?'"}),
 
-            ('INSERT EFRDef X: X cardinality %(cardinality)s,X defaultval %(defaultval)s,X description %(description)s,X fulltextindexed %(fulltextindexed)s,X indexed %(indexed)s,X internationalizable %(internationalizable)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
-             {'rt': 'cardinality', 'description': u'subject/object cardinality', 'internationalizable': True, 'fulltextindexed': False, 'ordernum': 5, 'defaultval': None, 'indexed': False, 'cardinality': u'?1', 'oe': 'String', 'se': 'ENFRDef'}),
-            ('INSERT EConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is EFRDef',
-             {'rt': 'cardinality', 'oe': 'String', 'ctname': u'SizeConstraint', 'se': 'ENFRDef', 'value': u'max=2'}),
-            ('INSERT EConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is EFRDef',
-             {'rt': 'cardinality', 'oe': 'String', 'ctname': u'StaticVocabularyConstraint', 'se': 'ENFRDef', 'value': u"u'?*', u'1*', u'+*', u'**', u'?+', u'1+', u'++', u'*+', u'?1', u'11', u'+1', u'*1', u'??', u'1?', u'+?', u'*?'"}),
+            ('INSERT CWAttribute X: X cardinality %(cardinality)s,X defaultval %(defaultval)s,X description %(description)s,X fulltextindexed %(fulltextindexed)s,X indexed %(indexed)s,X internationalizable %(internationalizable)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE name %(se)s,ER name %(rt)s,OE name %(oe)s',
+             {'rt': 'cardinality', 'description': u'subject/object cardinality', 'internationalizable': True, 'fulltextindexed': False, 'ordernum': 5, 'defaultval': None, 'indexed': False, 'cardinality': u'?1', 'oe': 'String', 'se': 'CWRelation'}),
+            ('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is CWAttribute',
+             {'rt': 'cardinality', 'oe': 'String', 'ctname': u'SizeConstraint', 'se': 'CWRelation', 'value': u'max=2'}),
+            ('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is CWAttribute',
+             {'rt': 'cardinality', 'oe': 'String', 'ctname': u'StaticVocabularyConstraint', 'se': 'CWRelation', 'value': u"u'?*', u'1*', u'+*', u'**', u'?+', u'1+', u'++', u'*+', u'?1', u'11', u'+1', u'*1', u'??', u'1?', u'+?', u'*?'"}),
             ])
         
 
     def test_updateeschema2rql1(self):
-        self.assertListEquals(list(updateeschema2rql(schema.eschema('EFRDef'))),
-                              [('SET X description %(description)s,X final %(final)s,X meta %(meta)s,X name %(name)s WHERE X is EEType, X name %(et)s',
-                                {'description': u'define a final relation: link a final relation type from a non final entity to a final entity type. used to build the application schema', 'meta': True, 'et': 'EFRDef', 'final': False, 'name': u'EFRDef'}),
+        self.assertListEquals(list(updateeschema2rql(schema.eschema('CWAttribute'))),
+                              [('SET X description %(description)s,X final %(final)s,X meta %(meta)s,X name %(name)s WHERE X is CWEType, X name %(et)s',
+                                {'description': u'define a final relation: link a final relation type from a non final entity to a final entity type. used to build the application schema', 'meta': True, 'et': 'CWAttribute', 'final': False, 'name': u'CWAttribute'}),
                                ])
         
     def test_updateeschema2rql2(self):
         self.assertListEquals(list(updateeschema2rql(schema.eschema('String'))),
-                              [('SET X description %(description)s,X final %(final)s,X meta %(meta)s,X name %(name)s WHERE X is EEType, X name %(et)s',
+                              [('SET X description %(description)s,X final %(final)s,X meta %(meta)s,X name %(name)s WHERE X is CWEType, X name %(et)s',
                                 {'description': u'', 'meta': True, 'et': 'String', 'final': True, 'name': u'String'})
                                ])
         
     def test_updaterschema2rql1(self):
         self.assertListEquals(list(updaterschema2rql(schema.rschema('relation_type'))),
                              [
-            ('SET X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X meta %(meta)s,X name %(name)s,X symetric %(symetric)s WHERE X is ERType, X name %(rt)s',
+            ('SET X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X meta %(meta)s,X name %(name)s,X symetric %(symetric)s WHERE X is CWRType, X name %(rt)s',
              {'rt': 'relation_type', 'symetric': False,
               'description': u'link a relation definition to its relation type',
               'meta': True, 'final': False, 'fulltext_container': None, 'inlined': True, 'name': u'relation_type'})
@@ -118,7 +118,7 @@
         
     def test_updaterschema2rql2(self):
         expected = [
-            ('SET X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X meta %(meta)s,X name %(name)s,X symetric %(symetric)s WHERE X is ERType, X name %(rt)s',
+            ('SET X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X meta %(meta)s,X name %(name)s,X symetric %(symetric)s WHERE X is CWRType, X name %(rt)s',
              {'rt': 'add_permission', 'symetric': False,
               'description': u'core relation giving to a group the permission to add an entity or relation type',
               'meta': True, 'final': False, 'fulltext_container': None, 'inlined': False, 'name': u'add_permission'})
@@ -135,41 +135,41 @@
         }
     
     def test_eperms2rql1(self):
-        self.assertListEquals([rql for rql, kwargs in erperms2rql(schema.eschema('EEType'), self.GROUP_MAPPING)],
-                              ['SET X read_permission Y WHERE X is EEType, X name "EEType", Y eid 2',
-                               'SET X read_permission Y WHERE X is EEType, X name "EEType", Y eid 0',
-                               'SET X read_permission Y WHERE X is EEType, X name "EEType", Y eid 1',
-                               'SET X add_permission Y WHERE X is EEType, X name "EEType", Y eid 0',
-                               'SET X update_permission Y WHERE X is EEType, X name "EEType", Y eid 0',
-                               'SET X update_permission Y WHERE X is EEType, X name "EEType", Y eid 3',
-                               'SET X delete_permission Y WHERE X is EEType, X name "EEType", Y eid 0',
+        self.assertListEquals([rql for rql, kwargs in erperms2rql(schema.eschema('CWEType'), self.GROUP_MAPPING)],
+                              ['SET X read_permission Y WHERE X is CWEType, X name "CWEType", Y eid 2',
+                               'SET X read_permission Y WHERE X is CWEType, X name "CWEType", Y eid 0',
+                               'SET X read_permission Y WHERE X is CWEType, X name "CWEType", Y eid 1',
+                               'SET X add_permission Y WHERE X is CWEType, X name "CWEType", Y eid 0',
+                               'SET X update_permission Y WHERE X is CWEType, X name "CWEType", Y eid 0',
+                               'SET X update_permission Y WHERE X is CWEType, X name "CWEType", Y eid 3',
+                               'SET X delete_permission Y WHERE X is CWEType, X name "CWEType", Y eid 0',
                                ])
         
     def test_rperms2rql2(self):
         self.assertListEquals([rql for rql, kwargs in erperms2rql(schema.rschema('read_permission'), self.GROUP_MAPPING)],
-                              ['SET X read_permission Y WHERE X is ERType, X name "read_permission", Y eid 2',
-                               'SET X read_permission Y WHERE X is ERType, X name "read_permission", Y eid 0',
-                               'SET X read_permission Y WHERE X is ERType, X name "read_permission", Y eid 1',
-                               'SET X add_permission Y WHERE X is ERType, X name "read_permission", Y eid 0',
-                               'SET X delete_permission Y WHERE X is ERType, X name "read_permission", Y eid 0',
+                              ['SET X read_permission Y WHERE X is CWRType, X name "read_permission", Y eid 2',
+                               'SET X read_permission Y WHERE X is CWRType, X name "read_permission", Y eid 0',
+                               'SET X read_permission Y WHERE X is CWRType, X name "read_permission", Y eid 1',
+                               'SET X add_permission Y WHERE X is CWRType, X name "read_permission", Y eid 0',
+                               'SET X delete_permission Y WHERE X is CWRType, X name "read_permission", Y eid 0',
                                ])
         
     def test_rperms2rql3(self):
         self.assertListEquals([rql for rql, kwargs in erperms2rql(schema.rschema('name'), self.GROUP_MAPPING)],
-                              ['SET X read_permission Y WHERE X is ERType, X name "name", Y eid 2',
-                               'SET X read_permission Y WHERE X is ERType, X name "name", Y eid 0',
-                               'SET X read_permission Y WHERE X is ERType, X name "name", Y eid 1',
-                               'SET X add_permission Y WHERE X is ERType, X name "name", Y eid 2',
-                               'SET X add_permission Y WHERE X is ERType, X name "name", Y eid 0',
-                               'SET X add_permission Y WHERE X is ERType, X name "name", Y eid 1',
-                               'SET X delete_permission Y WHERE X is ERType, X name "name", Y eid 2',
-                               'SET X delete_permission Y WHERE X is ERType, X name "name", Y eid 0',
-                               'SET X delete_permission Y WHERE X is ERType, X name "name", Y eid 1',
+                              ['SET X read_permission Y WHERE X is CWRType, X name "name", Y eid 2',
+                               'SET X read_permission Y WHERE X is CWRType, X name "name", Y eid 0',
+                               'SET X read_permission Y WHERE X is CWRType, X name "name", Y eid 1',
+                               'SET X add_permission Y WHERE X is CWRType, X name "name", Y eid 2',
+                               'SET X add_permission Y WHERE X is CWRType, X name "name", Y eid 0',
+                               'SET X add_permission Y WHERE X is CWRType, X name "name", Y eid 1',
+                               'SET X delete_permission Y WHERE X is CWRType, X name "name", Y eid 2',
+                               'SET X delete_permission Y WHERE X is CWRType, X name "name", Y eid 0',
+                               'SET X delete_permission Y WHERE X is CWRType, X name "name", Y eid 1',
                                ])
         
     #def test_perms2rql(self):
     #    self.assertListEquals(perms2rql(schema, self.GROUP_MAPPING),
-    #                         ['INSERT EEType X: X name 'Societe', X final FALSE'])
+    #                         ['INSERT CWEType X: X name 'Societe', X final FALSE'])
         
 
 
--- a/server/test/unittest_security.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_security.py	Fri Apr 24 19:46:47 2009 +0200
@@ -41,12 +41,12 @@
             
     def test_upassword_not_selectable(self):
         self.assertRaises(Unauthorized,
-                          self.execute, 'Any X,P WHERE X is EUser, X upassword P')
+                          self.execute, 'Any X,P WHERE X is CWUser, X upassword P')
         self.rollback()
         cnx = self.login('iaminusersgrouponly')
         cu = cnx.cursor()
         self.assertRaises(Unauthorized,
-                          cu.execute, 'Any X,P WHERE X is EUser, X upassword P')
+                          cu.execute, 'Any X,P WHERE X is CWUser, X upassword P')
         
     
 class SecurityTC(BaseSecurityTC):
@@ -57,7 +57,7 @@
         self.execute("INSERT Affaire X: X sujet 'cool'")
         self.execute("INSERT Societe X: X nom 'logilab'")
         self.execute("INSERT Personne X: X nom 'bidule'")
-        self.execute('INSERT EGroup X: X name "staff"')
+        self.execute('INSERT CWGroup X: X name "staff"')
         self.commit()
 
     def test_insert_security(self):
@@ -134,11 +134,11 @@
         # exception is raised
         #user._groups = {'guests':1}
         #self.assertRaises(Unauthorized,
-        #                  self.o.execute, user, "DELETE EUser X WHERE X login 'bidule'")
+        #                  self.o.execute, user, "DELETE CWUser X WHERE X login 'bidule'")
         # check local security
         cnx = self.login('iaminusersgrouponly')
         cu = cnx.cursor()
-        self.assertRaises(Unauthorized, cu.execute, "DELETE EGroup Y WHERE Y name 'staff'")
+        self.assertRaises(Unauthorized, cu.execute, "DELETE CWGroup Y WHERE Y name 'staff'")
         
     def test_delete_rql_permission(self):
         self.execute("SET A concerne S WHERE A is Affaire, S is Societe")
@@ -369,11 +369,11 @@
 
     def test_attribute_read_security(self):
         # anon not allowed to see users'login, but they can see users
-        self.repo.schema['EUser'].set_groups('read', ('guests', 'users', 'managers'))
+        self.repo.schema['CWUser'].set_groups('read', ('guests', 'users', 'managers'))
         self.repo.schema['login'].set_groups('read', ('users', 'managers'))
         cnx = self.login('anon')
         cu = cnx.cursor()
-        rset = cu.execute('EUser X')
+        rset = cu.execute('CWUser X')
         self.failUnless(rset)
         x = rset.get_entity(0, 0)
         self.assertEquals(x.login, None)
@@ -420,20 +420,20 @@
         # anonymous user can only read itself
         rset = cu.execute('Any L WHERE X owned_by U, U login L')
         self.assertEquals(rset.rows, [['anon']])
-        rset = cu.execute('EUser X')
+        rset = cu.execute('CWUser X')
         self.assertEquals(rset.rows, [[anon.eid]])
         # anonymous user can read groups (necessary to check allowed transitions for instance)
-        self.assert_(cu.execute('EGroup X'))
+        self.assert_(cu.execute('CWGroup X'))
         # should only be able to read the anonymous user, not another one
         origuser = self.session.user
         self.assertRaises(Unauthorized, 
-                          cu.execute, 'EUser X WHERE X eid %(x)s', {'x': origuser.eid}, 'x')
+                          cu.execute, 'CWUser X WHERE X eid %(x)s', {'x': origuser.eid}, 'x')
         # nothing selected, nothing updated, no exception raised
         #self.assertRaises(Unauthorized,
         #                  cu.execute, 'SET X login "toto" WHERE X eid %(x)s',
         #                  {'x': self.user.eid})
         
-        rset = cu.execute('EUser X WHERE X eid %(x)s', {'x': anon.eid}, 'x')
+        rset = cu.execute('CWUser X WHERE X eid %(x)s', {'x': anon.eid}, 'x')
         self.assertEquals(rset.rows, [[anon.eid]])
         # but can't modify it
         cu.execute('SET X login "toto" WHERE X eid %(x)s', {'x': anon.eid})
--- a/server/test/unittest_session.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_session.py	Fri Apr 24 19:46:47 2009 +0200
@@ -21,9 +21,9 @@
 
 class MakeDescriptionTC(TestCase):
     def test_known_values(self):
-        solution = {'A': 'Int', 'B': 'EUser'}
+        solution = {'A': 'Int', 'B': 'CWUser'}
         self.assertEquals(_make_description((Function('max', 'A'), Variable('B')), {}, solution),
-                          ['Int','EUser'])
+                          ['Int','CWUser'])
 
 if __name__ == '__main__':
     unittest_main()
--- a/server/test/unittest_ssplanner.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/server/test/unittest_ssplanner.py	Fri Apr 24 19:46:47 2009 +0200
@@ -21,12 +21,12 @@
         self._test('Any XN ORDERBY XN WHERE X name XN',
                    [('OneFetchStep', [('Any XN ORDERBY XN WHERE X name XN',
                                        [{'X': 'Basket', 'XN': 'String'},
-                                        {'X': 'ECache', 'XN': 'String'},
-                                        {'X': 'EConstraintType', 'XN': 'String'},
-                                        {'X': 'EEType', 'XN': 'String'},
-                                        {'X': 'EGroup', 'XN': 'String'},
-                                        {'X': 'EPermission', 'XN': 'String'},
-                                        {'X': 'ERType', 'XN': 'String'},
+                                        {'X': 'CWCache', 'XN': 'String'},
+                                        {'X': 'CWConstraintType', 'XN': 'String'},
+                                        {'X': 'CWEType', 'XN': 'String'},
+                                        {'X': 'CWGroup', 'XN': 'String'},
+                                        {'X': 'CWPermission', 'XN': 'String'},
+                                        {'X': 'CWRType', 'XN': 'String'},
                                         {'X': 'File', 'XN': 'String'},
                                         {'X': 'Folder', 'XN': 'String'},
                                         {'X': 'Image', 'XN': 'String'},
@@ -40,12 +40,12 @@
         self._test('Any XN,COUNT(X) GROUPBY XN WHERE X name XN',
                    [('OneFetchStep', [('Any XN,COUNT(X) GROUPBY XN WHERE X name XN',
                                        [{'X': 'Basket', 'XN': 'String'},
-                                        {'X': 'ECache', 'XN': 'String'},
-                                        {'X': 'EConstraintType', 'XN': 'String'},
-                                        {'X': 'EEType', 'XN': 'String'},
-                                        {'X': 'EGroup', 'XN': 'String'},
-                                        {'X': 'EPermission', 'XN': 'String'},
-                                        {'X': 'ERType', 'XN': 'String'},
+                                        {'X': 'CWCache', 'XN': 'String'},
+                                        {'X': 'CWConstraintType', 'XN': 'String'},
+                                        {'X': 'CWEType', 'XN': 'String'},
+                                        {'X': 'CWGroup', 'XN': 'String'},
+                                        {'X': 'CWPermission', 'XN': 'String'},
+                                        {'X': 'CWRType', 'XN': 'String'},
                                         {'X': 'File', 'XN': 'String'},
                                         {'X': 'Folder', 'XN': 'String'},
                                         {'X': 'Image', 'XN': 'String'},
--- a/skeleton/__pkginfo__.py.tmpl	Wed Apr 22 09:45:54 2009 +0200
+++ b/skeleton/__pkginfo__.py.tmpl	Fri Apr 24 19:46:47 2009 +0200
@@ -31,7 +31,8 @@
 def listdir(dirpath):
     return [join(dirpath, fname) for fname in _listdir(dirpath)
             if fname[0] != '.' and not fname.endswith('.pyc')
-            and not fname.endswith('~')]
+            and not fname.endswith('~')
+            and not isdir(join(dirpath, fname))]¶
 
 from glob import glob
 try:
--- a/skeleton/debian/rules.tmpl	Wed Apr 22 09:45:54 2009 +0200
+++ b/skeleton/debian/rules.tmpl	Fri Apr 24 19:46:47 2009 +0200
@@ -5,12 +5,12 @@
 # Uncomment this to turn on verbose mode.
 #export DH_VERBOSE=1
 build: build-stamp
-build-stamp: 
+build-stamp:
 	dh_testdir
 	python setup.py -q build
 	touch build-stamp
 
-clean: 
+clean:
 	dh_testdir
 	dh_testroot
 	rm -f build-stamp configure-stamp
@@ -24,6 +24,8 @@
 	dh_clean -k
 	dh_installdirs -i
 	python setup.py -q install --no-compile --prefix=debian/%(distname)s/usr/
+	# remove generated .egg-info file
+	rm -rf debian/cubicweb-comment/usr/lib/python*
 
 
 # Build architecture-independent files here.
@@ -39,13 +41,13 @@
 	dh_compress -i -X.py -X.ini -X.xml -Xtest
 	dh_fixperms -i
 	dh_installdeb -i
-	dh_gencontrol -i 
+	dh_gencontrol -i
 	dh_md5sums -i
 	dh_builddeb -i
 
 
 # Build architecture-dependent files here.
-binary-arch: 
+binary-arch:
 
-binary: binary-indep 
+binary: binary-indep
 .PHONY: build clean binary-arch binary-indep binary
--- a/skeleton/migration/precreate.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/skeleton/migration/precreate.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,3 +1,3 @@
 # Instructions here will be read before reading the schema
 # You could create your own groups here, like in :
-#   add_entity('EGroup', name=u'mygroup')
+#   add_entity('CWGroup', name=u'mygroup')
--- a/sobjects/hooks.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/sobjects/hooks.py	Fri Apr 24 19:46:47 2009 +0200
@@ -11,10 +11,10 @@
 from cubicweb.server.pool import PreCommitOperation
 
 
-class AddUpdateEUserHook(Hook):
+class AddUpdateCWUserHook(Hook):
     """ensure user logins are stripped"""
     events = ('before_add_entity', 'before_update_entity',)
-    accepts = ('EUser',)
+    accepts = ('CWUser',)
     
     def call(self, session, entity):
         if 'login' in entity and entity['login']:
--- a/sobjects/notification.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/sobjects/notification.py	Fri Apr 24 19:46:47 2009 +0200
@@ -37,9 +37,9 @@
     """
     id = 'recipients_finder'
     __select__ = yes()
-    user_rql = ('Any X,E,A WHERE X is EUser, X in_state S, S name "activated",'
+    user_rql = ('Any X,E,A WHERE X is CWUser, X in_state S, S name "activated",'
                 'X primary_email E, E address A')
-    
+
     def recipients(self):
         mode = self.config['default-recipients-mode']
         if mode == 'users':
@@ -55,7 +55,7 @@
             dests = []
         return dests
 
-    
+
 # hooks #######################################################################
 
 class RenderAndSendNotificationView(PreCommitOperation):
@@ -64,12 +64,12 @@
         if self.view.rset[0][0] in self.session.query_data('pendingeids', ()):
             return # entity added and deleted in the same transaction
         self.view.render_and_send(**getattr(self, 'viewargs', {}))
-        
+
 class StatusChangeHook(Hook):
     """notify when a workflowable entity has its state modified"""
     events = ('after_add_entity',)
     accepts = ('TrInfo',)
-    
+
     def call(self, session, entity):
         if not entity.from_state: # not a transition
             return
@@ -133,11 +133,11 @@
       override call)
     """
     msgid_timestamp = True
-    
+
     def recipients(self):
         finder = self.vreg.select_component('recipients_finder', self.req, self.rset)
         return finder.recipients()
-        
+
     def subject(self):
         entity = self.entity(0, 0)
         subject = self.req._(self.message)
@@ -150,7 +150,7 @@
         # req is actually a session (we are on the server side), and we have to
         # prevent nested internal session
         return self.req.actual_session().user.login
-    
+
     def context(self, **kwargs):
         entity = self.entity(0, 0)
         for key, val in kwargs.iteritems():
@@ -162,7 +162,7 @@
                        'url': entity.absolute_url(),
                        'title': entity.dc_long_title(),})
         return kwargs
-    
+
     def cell_call(self, row, col=0, **kwargs):
         self.w(self.req._(self.content) % self.context(**kwargs))
 
@@ -237,7 +237,7 @@
     if appid != fromappid or host != gethostname():
         return None
     return values
-    
+
 
 class StatusChangeMixIn(object):
     id = 'notif_status_change'
@@ -263,7 +263,7 @@
 
 class ContentAddedView(NotificationView):
     __abstract__ = True
-    id = 'notif_after_add_entity' 
+    id = 'notif_after_add_entity'
     msgid_timestamp = False
     message = _('new')
     content = """
@@ -273,7 +273,7 @@
 
 url: %(url)s
 """
-    
+
     def context(self, **kwargs):
         entity = self.entity(0, 0)
         content = entity.printable_value(self.content_attr, format='text/plain')
@@ -281,17 +281,10 @@
             contentformat = getattr(entity, self.content_attr + '_format', 'text/rest')
             content = normalize_text(content, 80, rest=contentformat=='text/rest')
         return super(ContentAddedView, self).context(content=content, **kwargs)
-    
+
     def subject(self):
         entity = self.entity(0, 0)
         return  u'%s #%s (%s)' % (self.req.__('New %s' % entity.e_schema),
                                   entity.eid, self.user_login())
 
 NormalizedTextView = class_renamed('NormalizedTextView', ContentAddedView)
-
-class CardAddedView(ContentAddedView):
-    """get notified from new cards"""
-    __select__ = implements('Card')
-    content_attr = 'synopsis'
-    
-
--- a/sobjects/supervising.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/sobjects/supervising.py	Fri Apr 24 19:46:47 2009 +0200
@@ -29,7 +29,7 @@
             SupervisionMailOp(session)
         
     def _call(self, *args):
-        if self._event() == 'update_entity' and args[0].e_schema == 'EUser':
+        if self._event() == 'update_entity' and args[0].e_schema == 'CWUser':
             updated = set(args[0].iterkeys())
             if not (updated - frozenset(('eid', 'modification_date', 'last_login_time'))):
                 # don't record last_login_time update which are done 
--- a/sobjects/test/data/sobjects/__init__.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/sobjects/test/data/sobjects/__init__.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,6 +1,6 @@
 from cubicweb.sobjects.notification import StatusChangeMixIn, NotificationView
 
 class UserStatusChangeView(StatusChangeMixIn, NotificationView):
-    accepts = ('EUser',)
+    accepts = ('CWUser',)
     
     
--- a/sobjects/test/unittest_notification.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/sobjects/test/unittest_notification.py	Fri Apr 24 19:46:47 2009 +0200
@@ -43,10 +43,10 @@
 
 class RecipientsFinderTC(EnvBasedTC):
     def test(self):
-        urset = self.execute('EUser X WHERE X login "admin"')
+        urset = self.execute('CWUser X WHERE X login "admin"')
         self.execute('INSERT EmailAddress X: X address "admin@logilab.fr", U primary_email X '
                      'WHERE U eid %(x)s', {'x': urset[0][0]})
-        self.execute('INSERT EProperty X: X pkey "ui.language", X value "fr", X for_user U '
+        self.execute('INSERT CWProperty X: X pkey "ui.language", X value "fr", X for_user U '
                      'WHERE U eid %(x)s', {'x': urset[0][0]})
         self.commit() # commit so that admin get its properties updated
         finder = self.vreg.select_component('recipients_finder', self.request(), urset)
--- a/sobjects/test/unittest_supervising.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/sobjects/test/unittest_supervising.py	Fri Apr 24 19:46:47 2009 +0200
@@ -21,7 +21,7 @@
     def test_supervision(self):
         session = self.session()
         # do some modification
-        ueid = self.execute('INSERT EUser X: X login "toto", X upassword "sosafe", X in_group G, X in_state S '
+        ueid = self.execute('INSERT CWUser X: X login "toto", X upassword "sosafe", X in_group G, X in_state S '
                             'WHERE G name "users", S name "activated"')[0][0]        
         self.execute('SET X last_login_time NOW WHERE X eid %(x)s', {'x': ueid}, 'x')
         self.execute('SET X in_state S WHERE X login "anon", S name "deactivated"')
--- a/test/data/entities.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/test/data/entities.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,15 +1,15 @@
 from cubicweb.entities import AnyEntity, fetch_config
 
-class Personne(AnyEntity):
+class Societe(AnyEntity):
+    id = 'Societe'
+    fetch_attrs = ('nom',)
+
+class Personne(Societe):
     """customized class forne Person entities"""
     id = 'Personne'
     fetch_attrs, fetch_order = fetch_config(['nom', 'prenom'])
     rest_attr = 'nom'
 
 
-class Societe(AnyEntity):
-    id = 'Societe'
-    fetch_attrs = ('nom',)
-    
 class Note(AnyEntity):
     id = 'Note'
--- a/test/data/schema.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/test/data/schema.py	Fri Apr 24 19:46:47 2009 +0200
@@ -5,11 +5,11 @@
     travaille = SubjectRelation('Societe')
     evaluee = SubjectRelation(('Note', 'Personne'))
     connait = SubjectRelation('Personne', symetric=True)
-    
+
 class Societe(EntityType):
     nom = String()
     evaluee = SubjectRelation('Note')
-    
+
 class Note(EntityType):
     type = String()
     ecrit_par = SubjectRelation('Personne')
@@ -23,5 +23,5 @@
     object = ('Personne', 'Note')
 
 class evaluee(RelationDefinition):
-    subject = 'EUser'
+    subject = 'CWUser'
     object = 'Note'
--- a/test/unittest_dbapi.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/test/unittest_dbapi.py	Fri Apr 24 19:46:47 2009 +0200
@@ -29,7 +29,7 @@
     def test_api(self):
         cnx = self.cnx
         self.assertEquals(cnx.user(None).login, 'anon')
-        self.assertEquals(cnx.describe(1), (u'EGroup', u'system', None))
+        self.assertEquals(cnx.describe(1), (u'CWGroup', u'system', None))
         self.restore_connection() # proper way to close cnx
         self.assertRaises(ConnectionError, cnx.user, None)
         self.assertRaises(ConnectionError, cnx.describe, 1)
@@ -73,7 +73,7 @@
 
 #     def test_api(self):
 #         cu = self.cursor
-#         self.assertEquals(cu.describe(1), (u'EGroup', u'system', None))
+#         self.assertEquals(cu.describe(1), (u'CWGroup', u'system', None))
 #         #cu.close()
 #         #self.assertRaises(ConnectionError, cu.describe, 1)
 
--- a/test/unittest_entity.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/test/unittest_entity.py	Fri Apr 24 19:46:47 2009 +0200
@@ -17,7 +17,7 @@
 ##                         embed=False)
     
     def test_boolean_value(self):
-        e = self.etype_instance('EUser')
+        e = self.etype_instance('CWUser')
         self.failUnless(e)
 
     def test_yams_inheritance(self):
@@ -28,7 +28,7 @@
         self.assertIs(e.__class__, e2.__class__)
 
     def test_has_eid(self):
-        e = self.etype_instance('EUser')
+        e = self.etype_instance('CWUser')
         self.assertEquals(e.eid, None)
         self.assertEquals(e.has_eid(), False)
         e.eid = 'X'
@@ -68,7 +68,7 @@
         e = self.entity('Any X WHERE X eid %(x)s', {'x':user.eid}, 'x')
         self.assertEquals(e.use_email[0].address, "toto@logilab.org")
         self.assertEquals(e.use_email[0].eid, adeleid)
-        usereid = self.execute('INSERT EUser X: X login "toto", X upassword "toto", X in_group G, X in_state S '
+        usereid = self.execute('INSERT CWUser X: X login "toto", X upassword "toto", X in_group G, X in_state S '
                                'WHERE G name "users", S name "activated"')[0][0]
         e = self.entity('Any X WHERE X eid %(x)s', {'x':usereid}, 'x')
         e.copy_relations(user.eid)
@@ -77,12 +77,12 @@
         
     def test_copy_with_non_initial_state(self):
         user = self.user()
-        eid = self.execute('INSERT EUser X: X login "toto", X upassword %(pwd)s, X in_group G WHERE G name "users"',
+        eid = self.execute('INSERT CWUser X: X login "toto", X upassword %(pwd)s, X in_group G WHERE G name "users"',
                            {'pwd': 'toto'})[0][0]
         self.commit()
         self.execute('SET X in_state S WHERE X eid %(x)s, S name "deactivated"', {'x': eid}, 'x')
         self.commit()
-        eid2 = self.execute('INSERT EUser X: X login "tutu", X upassword %(pwd)s', {'pwd': 'toto'})[0][0]
+        eid2 = self.execute('INSERT CWUser X: X login "tutu", X upassword %(pwd)s', {'pwd': 'toto'})[0][0]
         e = self.entity('Any X WHERE X eid %(x)s', {'x': eid2}, 'x')
         e.copy_relations(eid)
         self.commit()
@@ -200,8 +200,8 @@
                           1)
         
     def test_new_entity_unrelated(self):
-        e = self.etype_instance('EUser')
-        unrelated = [r[0] for r in e.unrelated('in_group', 'EGroup', 'subject')]
+        e = self.etype_instance('CWUser')
+        unrelated = [r[0] for r in e.unrelated('in_group', 'CWGroup', 'subject')]
         # should be default groups but owners, i.e. managers, users, guests
         self.assertEquals(len(unrelated), 3)
 
@@ -210,10 +210,10 @@
                             content_format=u'text/rest')
         self.assertEquals(e.printable_value('content'),
                           '<p>du <a class="reference" href="http://testing.fr/cubicweb/egroup/managers">*ReST*</a></p>\n')
-        e['content'] = 'du <em>html</em> <ref rql="EUser X">users</ref>'
+        e['content'] = 'du <em>html</em> <ref rql="CWUser X">users</ref>'
         e['content_format'] = 'text/html'
         self.assertEquals(e.printable_value('content'),
-                          'du <em>html</em> <a href="http://testing.fr/cubicweb/view?rql=EUser%20X">users</a>')
+                          'du <em>html</em> <a href="http://testing.fr/cubicweb/view?rql=CWUser%20X">users</a>')
         e['content'] = 'du *texte*'
         e['content_format'] = 'text/plain'
         self.assertEquals(e.printable_value('content'),
@@ -341,7 +341,7 @@
 
     def test_request_cache(self):
         req = self.request()
-        user = self.entity('EUser X WHERE X login "admin"', req=req)
+        user = self.entity('CWUser X WHERE X login "admin"', req=req)
         state = user.in_state[0]
         samestate = self.entity('State X WHERE X name "activated"', req=req)
         self.failUnless(state is samestate)
--- a/test/unittest_rset.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/test/unittest_rset.py	Fri Apr 24 19:46:47 2009 +0200
@@ -26,8 +26,8 @@
     def test_relations_description(self):
         """tests relations_description() function"""
         queries = {
-            'Any U,L,M where U is EUser, U login L, U mail M' : [(1, 'login', 'subject'), (2, 'mail', 'subject')],
-            'Any U,L,M where U is EUser, L is Foo, U mail M' : [(2, 'mail', 'subject')],
+            'Any U,L,M where U is CWUser, U login L, U mail M' : [(1, 'login', 'subject'), (2, 'mail', 'subject')],
+            'Any U,L,M where U is CWUser, L is Foo, U mail M' : [(2, 'mail', 'subject')],
             'Any C,P where C is Company, C employs P' : [(1, 'employs', 'subject')],
             'Any C,P where C is Company, P employed_by P' : [],
             'Any C where C is Company, C employs P' : [],
@@ -39,7 +39,7 @@
     def test_relations_description_indexed(self):
         """tests relations_description() function"""
         queries = {
-            'Any C,U,P,L,M where C is Company, C employs P, U is EUser, U login L, U mail M' :
+            'Any C,U,P,L,M where C is Company, C employs P, U is CWUser, U login L, U mail M' :
             {0: [(2,'employs', 'subject')], 1: [(3,'login', 'subject'), (4,'mail', 'subject')]},
             }
         for rql, results in queries.items():
@@ -54,8 +54,8 @@
     def setUp(self):
         super(ResultSetTC, self).setUp()
         self.rset = ResultSet([[12, 'adim'], [13, 'syt']],
-                              'Any U,L where U is EUser, U login L',
-                              description=[['EUser', 'String'], ['Bar', 'String']])
+                              'Any U,L where U is CWUser, U login L',
+                              description=[['CWUser', 'String'], ['Bar', 'String']])
         self.rset.vreg = self.vreg
 
     def compare_urls(self, url1, url2):
@@ -83,16 +83,16 @@
         
     def test_resultset_build(self):
         """test basic build of a ResultSet"""
-        rs = ResultSet([1,2,3], 'EGroup X', description=['EGroup', 'EGroup', 'EGroup'])
+        rs = ResultSet([1,2,3], 'CWGroup X', description=['CWGroup', 'CWGroup', 'CWGroup'])
         self.assertEquals(rs.rowcount, 3)
         self.assertEquals(rs.rows, [1,2,3])
-        self.assertEquals(rs.description, ['EGroup', 'EGroup', 'EGroup'])
+        self.assertEquals(rs.description, ['CWGroup', 'CWGroup', 'CWGroup'])
 
 
     def test_resultset_limit(self):
         rs = ResultSet([[12000, 'adim'], [13000, 'syt'], [14000, 'nico']],
-                       'Any U,L where U is EUser, U login L',
-                       description=[['EUser', 'String']] * 3)
+                       'Any U,L where U is CWUser, U login L',
+                       description=[['CWUser', 'String']] * 3)
         rs.req = self.request()
         rs.vreg = self.env.vreg
 
@@ -106,8 +106,8 @@
 
     def test_resultset_filter(self):
         rs = ResultSet([[12000, 'adim'], [13000, 'syt'], [14000, 'nico']],
-                       'Any U,L where U is EUser, U login L',
-                       description=[['EUser', 'String']] * 3)
+                       'Any U,L where U is CWUser, U login L',
+                       description=[['CWUser', 'String']] * 3)
         rs.req = self.request()
         rs.vreg = self.env.vreg
         def test_filter(entity):
@@ -119,8 +119,8 @@
         
     def test_resultset_transform(self):
         rs = ResultSet([[12, 'adim'], [13, 'syt'], [14, 'nico']],
-                       'Any U,L where U is EUser, U login L',
-                       description=[['EUser', 'String']] * 3)
+                       'Any U,L where U is CWUser, U login L',
+                       description=[['CWUser', 'String']] * 3)
         rs.req = self.request()
         def test_transform(row, desc):
             return row[1:], desc[1:]
@@ -131,8 +131,8 @@
         
     def test_resultset_sort(self):
         rs = ResultSet([[12000, 'adim'], [13000, 'syt'], [14000, 'nico']],
-                       'Any U,L where U is EUser, U login L',
-                       description=[['EUser', 'String']] * 3)
+                       'Any U,L where U is CWUser, U login L',
+                       description=[['CWUser', 'String']] * 3)
         rs.req = self.request()
         rs.vreg = self.env.vreg
         
@@ -160,9 +160,9 @@
                         [13000, 'syt',  u'Le carrelage en 42 leçons'],
                         [14000, 'nico', u'La tarte tatin en 15 minutes'],
                         [14000, 'nico', u"L'épluchage du castor commun"]],
-                       'Any U, L, T WHERE U is EUser, U login L,'\
+                       'Any U, L, T WHERE U is CWUser, U login L,'\
                        'D created_by U, D title T',
-                       description=[['EUser', 'String', 'String']] * 5)
+                       description=[['CWUser', 'String', 'String']] * 5)
         rs.req = self.request()
         rs.vreg = self.env.vreg
         
@@ -206,7 +206,7 @@
         self.assert_(rqlst1 is rqlst2)
 
     def test_get_entity_simple(self):
-        self.add_entity('EUser', login=u'adim', upassword='adim',
+        self.add_entity('CWUser', login=u'adim', upassword='adim',
                         surname=u'di mascio', firstname=u'adrien')
         e = self.entity('Any X,T WHERE X login "adim", X surname T')
         self.assertEquals(e['surname'], 'di mascio')
@@ -251,7 +251,7 @@
         rset = self.execute('Any X,S WHERE X in_state S, X login "anon"')
         e = rset.get_entity(0, 0)
         seid = self.execute('State X WHERE X name "activated"')[0][0]
-        # for_user / in_group are prefetched in EUser __init__, in_state should
+        # for_user / in_group are prefetched in CWUser __init__, in_state should
         # be filed from our query rset
         self.assertEquals(pprelcachedict(e._related_cache),
                           [('in_state_subject', [seid])])
@@ -276,7 +276,7 @@
 
         
     def test_get_entity_cache_with_left_outer_join(self):
-        eid = self.execute('INSERT EUser E: E login "joe", E upassword "joe", E in_group G '
+        eid = self.execute('INSERT CWUser E: E login "joe", E upassword "joe", E in_group G '
                            'WHERE G name "users"')[0][0]
         rset = self.execute('Any X,E WHERE X eid %(x)s, X primary_email E?', {'x': eid})
         e = rset.get_entity(0, 0)
@@ -294,10 +294,10 @@
         rset = self.execute('Any X,N ORDERBY N WITH X,N BEING '
                             '((Any X,N WHERE X is Bookmark, X title N)'
                             ' UNION '
-                            ' (Any X,N WHERE X is EGroup, X name N))')
-        expected = (('EGroup', 'guests'), ('EGroup', 'managers'),
-                    ('Bookmark', 'manger'), ('EGroup', 'owners'),
-                    ('EGroup', 'users'))
+                            ' (Any X,N WHERE X is CWGroup, X name N))')
+        expected = (('CWGroup', 'guests'), ('CWGroup', 'managers'),
+                    ('Bookmark', 'manger'), ('CWGroup', 'owners'),
+                    ('CWGroup', 'users'))
         for entity in rset.entities(): # test get_entity for each row actually
             etype, n = expected[entity.row]
             self.assertEquals(entity.id, etype)
@@ -314,17 +314,17 @@
     def test_related_entity_union_subquery(self):
         e = self.add_entity('Bookmark', title=u'aaaa', path=u'path')
         rset = self.execute('Any X,N ORDERBY N WITH X,N BEING '
-                            '((Any X,N WHERE X is EGroup, X name N)'
+                            '((Any X,N WHERE X is CWGroup, X name N)'
                             ' UNION '
                             ' (Any X,N WHERE X is Bookmark, X title N))')
         entity, rtype = rset.related_entity(0, 1)
         self.assertEquals(entity.eid, e.eid)
         self.assertEquals(rtype, 'title')
         entity, rtype = rset.related_entity(1, 1)
-        self.assertEquals(entity.id, 'EGroup')
+        self.assertEquals(entity.id, 'CWGroup')
         self.assertEquals(rtype, 'name')
         rset = self.execute('Any X,N ORDERBY N WHERE X is Bookmark WITH X,N BEING '
-                            '((Any X,N WHERE X is EGroup, X name N)'
+                            '((Any X,N WHERE X is CWGroup, X name N)'
                             ' UNION '
                             ' (Any X,N WHERE X is Bookmark, X title N))')
         entity, rtype = rset.related_entity(0, 1)
@@ -336,14 +336,14 @@
         # make sure we have at least one element
         self.failUnless(rset)
         self.assertEquals(set(e.e_schema.type for e in rset.entities(0)),
-                          set(['EUser',]))
+                          set(['CWUser',]))
         self.assertEquals(set(e.e_schema.type for e in rset.entities(1)),
-                          set(['EGroup',]))
+                          set(['CWGroup',]))
 
     def test_printable_rql(self):        
-        rset = self.execute(u'EEType X WHERE X final FALSE, X meta FALSE')
+        rset = self.execute(u'CWEType X WHERE X final FALSE, X meta FALSE')
         self.assertEquals(rset.printable_rql(),
-                          'Any X WHERE X final FALSE, X meta FALSE, X is EEType')
+                          'Any X WHERE X final FALSE, X meta FALSE, X is CWEType')
 
 
     def test_searched_text(self):
--- a/test/unittest_schema.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/test/unittest_schema.py	Fri Apr 24 19:46:47 2009 +0200
@@ -141,9 +141,9 @@
         entities.sort()
         expected_entities = ['Bookmark', 'Boolean', 'Bytes', 'Card', 
                              'Date', 'Datetime', 'Decimal',
-                             'ECache', 'EConstraint', 'EConstraintType', 'EEType',
-                             'EFRDef', 'EGroup', 'EmailAddress', 'ENFRDef',
-                             'EPermission', 'EProperty', 'ERType', 'EUser',
+                             'CWCache', 'CWConstraint', 'CWConstraintType', 'CWEType',
+                             'CWAttribute', 'CWGroup', 'EmailAddress', 'CWRelation',
+                             'CWPermission', 'CWProperty', 'CWRType', 'CWUser',
                              'File', 'Float', 'Image', 'Int', 'Interval', 'Note',
                              'Password', 'Personne',
                              'RQLExpression', 
@@ -195,7 +195,7 @@
     
         self.assertListEquals(relations, expected_relations)
 
-        eschema = schema.eschema('EUser')
+        eschema = schema.eschema('CWUser')
         rels = sorted(str(r) for r in eschema.subject_relations())
         self.assertListEquals(rels, ['created_by', 'creation_date', 'eid',
                                      'evaluee', 'firstname', 'has_text', 'identity',
@@ -208,7 +208,7 @@
         self.assertListEquals(rels, ['bookmarked_by', 'created_by', 'for_user',
                                      'identity', 'owned_by', 'wf_info_for'])
         rschema = schema.rschema('relation_type')
-        properties = rschema.rproperties('EFRDef', 'ERType')
+        properties = rschema.rproperties('CWAttribute', 'CWRType')
         self.assertEquals(properties['cardinality'], '1*')
         constraints = properties['constraints']
         self.failUnlessEqual(len(constraints), 1, constraints)
@@ -218,7 +218,7 @@
 
     def test_fulltext_container(self):
         schema = loader.load(config)
-        self.failUnless('has_text' in schema['EUser'].subject_relations())
+        self.failUnless('has_text' in schema['CWUser'].subject_relations())
         self.failIf('has_text' in schema['EmailAddress'].subject_relations())
 
 
--- a/test/unittest_selectors.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/test/unittest_selectors.py	Fri Apr 24 19:46:47 2009 +0200
@@ -7,9 +7,9 @@
 
 from logilab.common.testlib import TestCase, unittest_main
 
+from cubicweb.devtools.testlib import EnvBasedTC
 from cubicweb.vregistry import Selector, AndSelector, OrSelector
 from cubicweb.selectors import implements
-
 from cubicweb.interfaces import IDownloadable
 
 class _1_(Selector):
@@ -48,7 +48,7 @@
         self.assertEquals(selector(None), 3)
         selector = _2_ & _1_()
         self.assertEquals(selector(None), 3)
-        
+
     def test_three_and(self):
         selector = _1_() & _1_() & _1_()
         self.assertEquals(selector(None), 3)
@@ -84,8 +84,7 @@
         self.assertIs(csel.search_selector(implements), sel)
         csel = AndSelector(Selector(), sel)
         self.assertIs(csel.search_selector(implements), sel)
-        
-from cubicweb.devtools.testlib import EnvBasedTC
+
 
 class ImplementsSelectorTC(EnvBasedTC):
     def test_etype_priority(self):
@@ -96,7 +95,11 @@
         self.failUnless(idownscore > anyscore, (idownscore, anyscore))
         filescore = implements('File').score_class(cls, req)
         self.failUnless(filescore > idownscore, (filescore, idownscore))
-    
+
+    def test_etype_inheritance_no_yams_inheritance(self):
+        cls = self.vreg.etype_class('Personne')
+        self.failIf(implements('Societe').score_class(cls, self.request()))
+
 if __name__ == '__main__':
     unittest_main()
 
--- a/utils.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/utils.py	Fri Apr 24 19:46:47 2009 +0200
@@ -9,7 +9,7 @@
 import locale
 from md5 import md5
 from datetime import datetime, timedelta, date
-from time import time, strftime
+from time import time
 from random import randint, seed
     
 # initialize random seed from current time
@@ -53,7 +53,7 @@
     """
     # date format may depend on the locale
     encoding = locale.getpreferredencoding(do_setlocale=False) or 'UTF-8'
-    return unicode(strftime(str(fmt), date.timetuple()), encoding)
+    return unicode(date.strftime(str(fmt)), encoding)
 
 def make_uid(key):
     """forge a unique identifier"""
--- a/view.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/view.py	Fri Apr 24 19:46:47 2009 +0200
@@ -17,8 +17,6 @@
 from cubicweb.selectors import require_group_compat, accepts_compat
 from cubicweb.appobject import AppRsetObject
 from cubicweb.utils import UStringIO, HTMLStream
-from cubicweb.vregistry import yes_registerer
-from cubicweb.common.registerers import accepts_registerer, priority_registerer, yes_registerer
 
 _ = unicode
 
@@ -66,9 +64,10 @@
  cubicweb:facetName         CDATA   #IMPLIED
   "> ] '''
 
-TRANSITIONAL_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" %s>\n'
-
-STRICT_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" %s>\n'
+TRANSITIONAL_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" %s>\n' % CW_XHTML_EXTENSIONS
+TRANSITIONAL_DOCTYPE_NOEXT = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n'
+STRICT_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" %s>\n' % CW_XHTML_EXTENSIONS
+STRICT_DOCTYPE_NOEXT = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
 
 # base view object ############################################################
 
@@ -92,7 +91,6 @@
     time to a write function to use.
     """
     __registry__ = 'views'
-    __registerer__ = priority_registerer
     registered = require_group_compat(AppRsetObject.registered)
 
     templatable = True
@@ -108,9 +106,7 @@
 
     @property
     def content_type(self):
-        if self.req.xhtml_browser():
-            return 'application/xhtml+xml'
-        return 'text/html'
+        return self.req.html_content_type()
 
     def set_stream(self, w=None):
         if self.w is not None:
@@ -206,12 +202,12 @@
         self.req.set_content_type(self.content_type)
 
     # view utilities ##########################################################
-    
+
     def wview(self, __vid, rset, __fallback_vid=None, **kwargs):
         """shortcut to self.view method automatically passing self.w as argument
         """
         self.view(__vid, rset, __fallback_vid, w=self.w, **kwargs)
-        
+
     # XXX Template bw compat
     template = obsolete('.template is deprecated, use .view')(wview)
 
@@ -307,21 +303,20 @@
         w(u'<div class="field">%s</div>' % value)
         if row:
             w(u'</div>')
-            
+
     def initialize_varmaker(self):
         varmaker = self.req.get_page_data('rql_varmaker')
         if varmaker is None:
             varmaker = self.req.varmaker
             self.req.set_page_data('rql_varmaker', varmaker)
         self.varmaker = varmaker
-        
+
 
 
 # concrete views base classes #################################################
 
 class EntityView(View):
     """base class for views applying on an entity (i.e. uniform result set)"""
-    __registerer__ = accepts_registerer
     __select__ = non_final_entity()
     registered = accepts_compat(View.registered)
 
@@ -332,12 +327,11 @@
     """base class for views which doesn't need a particular result set to be
     displayed (so they can always be displayed !)
     """
-    __registerer__ = priority_registerer
     __select__ = none_rset()
     registered = require_group_compat(View.registered)
-    
+
     category = 'startupview'
-    
+
     def url(self):
         """return the url associated with this view. We can omit rql here"""
         return self.build_url('view', vid=self.id)
@@ -411,7 +405,7 @@
             labels.append(label)
         return labels
 
-    
+
 # concrete template base classes ##############################################
 
 class MainTemplate(View):
@@ -419,26 +413,20 @@
     There is usually at least a regular main template and a simple fallback
     one to display error if the first one failed
     """
-    base_doctype = STRICT_DOCTYPE
     registered = require_group_compat(View.registered)
 
     @property
     def doctype(self):
         if self.req.xhtml_browser():
-            return self.base_doctype % CW_XHTML_EXTENSIONS
-        return self.base_doctype % ''
+            return STRICT_DOCTYPE
+        return STRICT_DOCTYPE_NOEXT
 
-    def set_stream(self, w=None, templatable=True):
-        if templatable and self.w is not None:
+    def set_stream(self, w=None):
+        if self.w is not None:
             return
-
         if w is None:
             if self.binary:
                 self._stream = stream = StringIO()
-            elif not templatable:
-                # not templatable means we're using a non-html view, we don't
-                # want the HTMLStream stuff to interfere during data generation
-                self._stream = stream = UStringIO()
             else:
                 self._stream = stream = HTMLStream(self.req)
             w = stream.write
@@ -455,12 +443,12 @@
 
     def linkable(self):
         return False
-    
+
 # concrete component base classes #############################################
 
 class ReloadableMixIn(object):
     """simple mixin for reloadable parts of UI"""
-    
+
     def user_callback(self, cb, args, msg=None, nonify=False):
         """register the given user callback and return an url to call it ready to be
         inserted in html
@@ -472,17 +460,17 @@
                 _cb(*args)
         cbname = self.req.register_onetime_callback(cb, *args)
         return self.build_js(cbname, html_escape(msg or ''))
-        
+
     def build_update_js_call(self, cbname, msg):
         rql = html_escape(self.rset.printable_rql())
         return "javascript:userCallbackThenUpdateUI('%s', '%s', '%s', '%s', '%s', '%s')" % (
             cbname, self.id, rql, msg, self.__registry__, self.div_id())
-    
+
     def build_reload_js_call(self, cbname, msg):
         return "javascript:userCallbackThenReloadPage('%s', '%s')" % (cbname, msg)
 
     build_js = build_update_js_call # expect updatable component by default
-    
+
     def div_id(self):
         return ''
 
@@ -490,12 +478,11 @@
 class Component(ReloadableMixIn, View):
     """base class for components"""
     __registry__ = 'components'
-    __registerer__ = yes_registerer
     __select__ = yes()
     property_defs = {
         _('visible'):  dict(type='Boolean', default=True,
                             help=_('display the component or not')),
-        }    
+        }
 
     def div_class(self):
         return '%s %s' % (self.propval('htmlclass'), self.id)
--- a/vregistry.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/vregistry.py	Fri Apr 24 19:46:47 2009 +0200
@@ -6,12 +6,7 @@
 
 * to interact with the vregistry, object should inherit from the
   VObject abstract class
-  
-* the registration procedure is delegated to a registerer. Each
-  registerable vobject must defines its registerer class using the
-  __registerer__ attribute.  A registerer is instantianted at
-  registration time after what the instance is lost
-  
+
 * the selection procedure has been generalized by delegating to a
   selector, which is responsible to score the vobject according to the
   current state (req, rset, row, col). At the end of the selection, if
@@ -53,48 +48,12 @@
     return _toload
 
 
-class registerer(object):
-    """do whatever is needed at registration time for the wrapped
-    class, according to current application schema and already
-    registered objects of the same kind (i.e. same registry name and
-    same id).
-
-    The wrapped class may be skipped, some previously selected object
-    may be kicked out... After whatever works needed, if the object or
-    a transformed object is returned, it will be added to previously
-    registered objects.
-    """
-
-    def __init__(self, registry, vobject):
-        self.registry = registry
-        self.vobject = vobject
-        self.config = registry.config
-        self.schema = registry.schema
-        self.kicked = set()
-    
-    def do_it_yourself(self, registered):
-        raise NotImplementedError(str(self.vobject))
-        
-    def kick(self, registered, kicked):
-        self.debug('kicking vobject %s', kicked)
-        registered.remove(kicked)
-        self.kicked.add(kicked.classid())
-        
-    def skip(self):
-        self.debug('no schema compat, skipping %s', self.vobject)
-
-class yes_registerer(registerer):
-    """register without any other action"""
-    def do_it_yourself(self, registered):
-        return self.vobject
-
-
 class VObject(object):
     """visual object, use to be handled somehow by the visual components
     registry.
 
     The following attributes should be set on concret vobject subclasses:
-    
+
     :__registry__:
       name of the registry for this object (string like 'views',
       'templates'...)
@@ -103,14 +62,13 @@
       'primary', 'folder_box')
     :__select__:
       class'selector
-      
+
     Moreover, the `__abstract__` attribute may be set to True to indicate
     that a vobject is abstract and should not be registered
     """
     # necessary attributes to interact with the registry
     id = None
     __registry__ = None
-    __registerer__ = yes_registerer
     __select__ = None
 
     @classmethod
@@ -127,7 +85,7 @@
     @classmethod
     def selected(cls, *args, **kwargs):
         """called by the registry when the vobject has been selected.
-        
+
         It must return the  object that will be actually returned by the
         .select method (this may be the right hook to create an
         instance for example). By default the selected object is
@@ -169,7 +127,7 @@
     elements used to build the web interface. Currently, we have templates,
     views, actions and components.
     """
-    
+
     def __init__(self, config):#, cache_size=1000):
         self.config = config
         # dictionnary of registry (themself dictionnary) by name
@@ -241,7 +199,7 @@
                 continue
             if oid:
                 self.register(obj)
-                
+
     def register(self, obj, registryname=None, oid=None, clear=False):
         """base method to add an object in the registry"""
         assert not '__abstract__' in obj.__dict__
@@ -288,9 +246,9 @@
 #                 else:
 #                     # if objects is empty, remove oid from registry
 #                     if not registry[obj.id]:
-#                         del regcontent[oid]                    
+#                         del regcontent[oid]
                 break
-    
+
     def register_and_replace(self, obj, replaced, registryname=None):
         if hasattr(replaced, 'classid'):
             replaced = replaced.classid()
@@ -304,7 +262,7 @@
         self.register(obj, registryname=registryname)
 
     # dynamic selection methods ###############################################
-    
+
     def select(self, vobjects, *args, **kwargs):
         """return an instance of the most specific object according
         to parameters
@@ -333,7 +291,7 @@
         winner = winners[0]
         # return the result of the .selected method of the vobject
         return winner.selected(*args, **kwargs)
-    
+
     def possible_objects(self, registry, *args, **kwargs):
         """return an iterator on possible objects in a registry for this result set
 
@@ -348,15 +306,15 @@
     def select_object(self, registry, cid, *args, **kwargs):
         """return the most specific component according to the resultset"""
         return self.select(self.registry_objects(registry, cid), *args, **kwargs)
-    
+
     # intialization methods ###################################################
-    
+
     def init_registration(self, path):
         # compute list of all modules that have to be loaded
         self._toloadmods, filemods = _toload_info(path)
         self._loadedmods = {}
         return filemods
-    
+
     def register_objects(self, path, force_reload=None):
         if force_reload is None:
             force_reload = self.config.mode == 'dev'
@@ -383,7 +341,7 @@
             if self.load_file(filepath, modname, force_reload):
                 change = True
         return change
-    
+
     def load_file(self, filepath, modname, force_reload=False):
         """load visual objects from a python file"""
         from logilab.common.modutils import load_module_from_name
@@ -410,7 +368,7 @@
         module = load_module_from_name(modname, use_sys=not force_reload)
         self.load_module(module)
         # if something was unregistered, we need to update places where it was
-        # referenced 
+        # referenced
         if unregistered:
             # oldnew_mapping = {}
             registered = self._loadedmods[modname]
@@ -430,7 +388,7 @@
                     continue
                 self._load_ancestors_then_object(module.__name__, obj)
         self.debug('loaded %s', module)
-    
+
     def _load_ancestors_then_object(self, modname, obj):
         # imported classes
         objmodname = getattr(obj, '__module__', None)
@@ -451,7 +409,7 @@
         for parent in obj.__bases__:
             self._load_ancestors_then_object(modname, parent)
         self.load_object(obj)
-            
+
     def load_object(self, obj):
         try:
             self.register_vobject_class(obj)
@@ -459,18 +417,16 @@
             if self.config.mode in ('test', 'dev'):
                 raise
             self.exception('vobject %s registration failed: %s', obj, ex)
-        
+
     # old automatic registration XXX deprecated ###############################
-    
+
     def register_vobject_class(self, cls):
         """handle vobject class registration
-        
+
         vobject class with __abstract__ == True in their local dictionnary or
         with a name starting starting by an underscore are not registered.
         Also a vobject class needs to have __registry__ and id attributes set
         to a non empty string to be registered.
-
-        Registration is actually handled by vobject's registerer.
         """
         if (cls.__dict__.get('__abstract__') or cls.__name__[0] == '_'
             or not cls.__registry__ or not cls.id):
@@ -478,13 +434,8 @@
         regname = cls.__registry__
         if '%s.%s' % (regname, cls.id) in self.config['disable-appobjects']:
             return
-        registry = self._registries.setdefault(regname, {})
-        vobjects = registry.setdefault(cls.id, [])
-        registerer = cls.__registerer__(self, cls)
-        cls = registerer.do_it_yourself(vobjects)
-        if cls:
-            self.register(cls)
-            
+        self.register(cls)
+
     def unregister_module_vobjects(self, modname):
         """removes registered objects coming from a given module
 
@@ -546,11 +497,10 @@
                         self.debug('updating %s.%s base classes',
                                   obj.__module__, obj.__name__)
                         obj.__bases__ = newbases
-        
-# init logging 
+
+# init logging
 set_log_methods(VObject, getLogger('cubicweb'))
 set_log_methods(VRegistry, getLogger('cubicweb.registry'))
-set_log_methods(registerer, getLogger('cubicweb.registration'))
 
 
 # selector base classes and operations ########################################
@@ -587,7 +537,7 @@
 
     def __str__(self):
         return self.__class__.__name__
-    
+
     def __and__(self, other):
         return AndSelector(self, other)
     def __rand__(self, other):
@@ -600,7 +550,7 @@
 
     def __invert__(self):
         return NotSelector(self)
-    
+
     # XXX (function | function) or (function & function) not managed yet
 
     def __call__(self, cls, *args, **kwargs):
@@ -609,7 +559,7 @@
 
 class MultiSelector(Selector):
     """base class for compound selector classes"""
-    
+
     def __init__(self, *selectors):
         self.selectors = self.merge_selectors(selectors)
 
@@ -650,7 +600,7 @@
                 return found
         return None
 
-    
+
 def objectify_selector(selector_func):
     """convenience decorator for simple selectors where a class definition
     would be overkill::
@@ -658,14 +608,14 @@
         @objectify_selector
         def yes(cls, *args, **kwargs):
             return 1
-        
+
     """
     return type(selector_func.__name__, (Selector,),
                 {'__call__': lambda self, *args, **kwargs: selector_func(*args, **kwargs)})
 
 def _instantiate_selector(selector):
     """ensures `selector` is a `Selector` instance
-    
+
     NOTE: This should only be used locally in build___select__()
     XXX: then, why not do it ??
     """
--- a/web/action.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/action.py	Fri Apr 24 19:46:47 2009 +0200
@@ -11,19 +11,17 @@
                                 one_line_rset, partial_may_add_relation, yes,
                                 accepts_compat, condition_compat, deprecate)
 from cubicweb.appobject import AppRsetObject
-from cubicweb.common.registerers import accepts_registerer
 
 _ = unicode
 
 
 class Action(AppRsetObject):
     """abstract action. Handle the .search_states attribute to match
-    request search state. 
+    request search state.
     """
     __registry__ = 'actions'
-    __registerer__ = accepts_registerer
     __select__ = yes()
-    
+
     property_defs = {
         'visible':  dict(type='Boolean', default=True,
                          help=_('display the action or not')),
@@ -36,11 +34,11 @@
     }
     site_wide = True # don't want user to configuration actions eproperties
     category = 'moreactions'
-    
+
     def url(self):
         """return the url associated with this action"""
         raise NotImplementedError
-    
+
     def html_class(self):
         if self.req.selected(self.url()):
             return 'selected'
@@ -54,13 +52,13 @@
     """
     category = None
     id = None
-    
+
     def __init__(self, req, rset, title, path, **kwargs):
         Action.__init__(self, req, rset)
         self.title = req._(title)
         self._path = path
         self.__dict__.update(kwargs)
-        
+
     def url(self):
         return self._path
 
@@ -76,9 +74,9 @@
                   & partial_relation_possible(action='add')
                   & partial_may_add_relation())
     registered = accepts_compat(Action.registered)
-    
+
     category = 'addrelated'
-                
+
     def url(self):
         current_entity = self.rset.get_entity(self.row or 0, self.col or 0)
         linkto = '%s:%s:%s' % (self.rtype, current_entity.eid, target(self))
@@ -93,4 +91,4 @@
     registered = deprecate(condition_compat(accepts_compat(Action.registered)),
                            msg='EntityAction is deprecated, use Action with '
                            'appropriate selectors')
-    
+
--- a/web/application.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/application.py	Fri Apr 24 19:46:47 2009 +0200
@@ -26,7 +26,7 @@
 class AbstractSessionManager(Component):
     """manage session data associated to a session identifier"""
     id = 'sessionmanager'
-    
+
     def __init__(self):
         self.session_time = self.vreg.config['http-session-time'] or None
         assert self.session_time is None or self.session_time > 0
@@ -39,7 +39,7 @@
             assert self.cleanup_anon_session_time < self.session_time
         self.authmanager = self.vreg.select_component('authmanager')
         assert self.authmanager, 'no authentication manager found'
-        
+
     def clean_sessions(self):
         """cleanup sessions which has not been unused since a given amount of
         time. Return the number of sessions which have been closed.
@@ -57,28 +57,28 @@
                 self.close_session(session)
                 closed += 1
         return closed, total - closed
-    
+
     def has_expired(self, session):
         """return True if the web session associated to the session is expired
         """
         return not (self.session_time is None or
                     time() < session.last_usage_time + self.session_time)
-                
+
     def current_sessions(self):
         """return currently open sessions"""
         raise NotImplementedError()
-            
+
     def get_session(self, req, sessionid):
         """return existing session for the given session identifier"""
         raise NotImplementedError()
 
     def open_session(self, req):
         """open and return a new session for the given request
-        
+
         :raise ExplicitLogin: if authentication is required
         """
         raise NotImplementedError()
-    
+
     def close_session(self, session):
         """close session on logout or on invalid session detected (expired out,
         corrupted...)
@@ -92,13 +92,13 @@
 
     def authenticate(self, req):
         """authenticate user and return corresponding user object
-        
+
         :raise ExplicitLogin: if authentication is required (no authentication
         info found or wrong user/password)
         """
         raise NotImplementedError()
 
-    
+
 class CookieSessionHandler(object):
     """a session handler using a cookie to store the session identifier
 
@@ -107,7 +107,7 @@
       identifier
     """
     SESSION_VAR = '__session'
-    
+
     def __init__(self, appli):
         self.session_manager = appli.vreg.select_component('sessionmanager')
         assert self.session_manager, 'no session manager found'
@@ -121,7 +121,7 @@
         time
         """
         self.session_manager.clean_sessions()
-        
+
     def set_session(self, req):
         """associate a session to the request
 
@@ -132,7 +132,7 @@
         if no session id is found, open a new session for the connected user
         or request authentification as needed
 
-        :raise Redirect: if authentication has occured and succeed        
+        :raise Redirect: if authentication has occured and succeed
         """
         assert req.cnx is None # at this point no cnx should be set on the request
         cookie = req.get_cookie()
@@ -154,7 +154,7 @@
 
     def get_session(self, req, sessionid):
         return self.session_manager.get_session(req, sessionid)
-    
+
     def open_session(self, req):
         session = self.session_manager.open_session(req)
         cookie = req.get_cookie()
@@ -177,7 +177,7 @@
         except:
             req.cnx.rollback()
             raise
-        
+
     def _postlogin(self, req):
         """postlogin: the user has been authenticated, redirect to the original
         page (index by default) with a welcome message
@@ -197,7 +197,7 @@
         if path == 'login':
             path = 'view'
         raise Redirect(req.build_url(path, **args))
-    
+
     def logout(self, req):
         """logout from the application by cleaning the session and raising
         `AuthenticationError`
@@ -211,7 +211,7 @@
     """Central registry for the web application. This is one of the central
     object in the web application, coupling dynamically loaded objects with
     the application's schema and the application's configuration objects.
-    
+
     It specializes the VRegistry by adding some convenience methods to
     access to stored objects. Currently we have the following registries
     of objects known by the web application (library may use some others
@@ -223,7 +223,7 @@
     * components
     * actions
     """
-    
+
     def __init__(self, config, debug=None,
                  session_handler_fact=CookieSessionHandler,
                  vreg=None):
@@ -243,14 +243,14 @@
             from threading import Lock
             self._query_log = open(config['query-log-file'], 'a')
             self.publish = self.log_publish
-            self._logfile_lock = Lock()            
+            self._logfile_lock = Lock()
         else:
             self._query_log = None
             self.publish = self.main_publish
         # instantiate session and url resolving helpers
         self.session_handler = session_handler_fact(self)
         self.url_resolver = vreg.select_component('urlpublisher')
-    
+
     def connect(self, req):
         """return a connection for a logged user object according to existing
         sessions (i.e. a new connection may be created or an already existing
@@ -266,9 +266,9 @@
                                req=req, appli=self)
         except NoSelectableObject:
             raise Unauthorized(req._('not authorized'))
-            
+
     # publish methods #########################################################
-        
+
     def log_publish(self, path, req):
         """wrapper around _publish to log all queries executed for a given
         accessed path
@@ -293,13 +293,13 @@
 
     def main_publish(self, path, req):
         """method called by the main publisher to process <path>
-        
+
         should return a string containing the resulting page or raise a
         `NotFound` exception
 
         :type path: str
         :param path: the path part of the url to publish
-        
+
         :type req: `web.Request`
         :param req: the request object
 
@@ -370,7 +370,7 @@
             req.set_session_data(req.form['__errorurl'], forminfo)
             raise Redirect(req.form['__errorurl'])
         self.error_handler(req, ex, tb=False)
-        
+
     def error_handler(self, req, ex, tb=False):
         excinfo = sys.exc_info()
         self.exception(repr(ex))
@@ -389,13 +389,13 @@
         except:
             content = self.vreg.main_template(req, 'error-template')
         raise StatusResponse(500, content)
-    
+
     def need_login_content(self, req):
         return self.vreg.main_template(req, 'login')
-    
+
     def loggedout_content(self, req):
         return self.vreg.main_template(req, 'loggedout')
-    
+
     def notfound_content(self, req):
         req.form['vid'] = '404'
         view = self.vreg.select_view('404', req, None)
@@ -407,7 +407,7 @@
         if template not in self.vreg.registry('views') :
             template = 'main-template'
         return template
-        
+
 
 set_log_methods(CubicWebPublisher, LOGGER)
 set_log_methods(CookieSessionHandler, LOGGER)
--- a/web/box.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/box.py	Fri Apr 24 19:46:47 2009 +0200
@@ -215,7 +215,7 @@
             return entity.unrelated(self.rtype, self.etype, get_role(self)).entities()
         # in other cases, use vocabulary functions
         entities = []
-        for _, eid in entity.vocabulary(self.rtype, x):
+        for _, eid in entity.vocabulary(self.rtype, get_role(self)):
             if eid is not None:
                 rset = self.req.eid_rset(eid)
                 entities.append(rset.get_entity(0, 0))
--- a/web/component.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/component.py	Fri Apr 24 19:46:47 2009 +0200
@@ -16,54 +16,52 @@
     paginated_rset, one_line_rset, primary_view, match_context_prop,
     partial_has_related_entities, condition_compat, accepts_compat,
     has_relation_compat)
-from cubicweb.common.registerers import accepts_registerer
 
 _ = unicode
 
 class EntityVComponent(Component):
     """abstract base class for additinal components displayed in content
     headers and footer according to:
-    
+
     * the displayed entity's type
     * a context (currently 'header' or 'footer')
 
     it should be configured using .accepts, .etype, .rtype, .target and
     .context class attributes
     """
-    
+
     __registry__ = 'contentnavigation'
-    __registerer__ = accepts_registerer    
     __select__ = one_line_rset() & primary_view() & match_context_prop()
     registered = accepts_compat(has_relation_compat(condition_compat(View.registered)))
-    
+
     property_defs = {
         _('visible'):  dict(type='Boolean', default=True,
                             help=_('display the box or not')),
         _('order'):    dict(type='Int', default=99,
                             help=_('display order of the component')),
         _('context'):  dict(type='String', default='header',
-                            vocabulary=(_('navtop'), _('navbottom'), 
+                            vocabulary=(_('navtop'), _('navbottom'),
                                         _('navcontenttop'), _('navcontentbottom')),
                             #vocabulary=(_('header'), _('incontext'), _('footer')),
                             help=_('context where this component should be displayed')),
         _('htmlclass'):dict(type='String', default='mainRelated',
                             help=_('html class of the component')),
     }
-    
+
     context = 'navcontentbottom' # 'footer' | 'header' | 'incontext'
-    
+
     def call(self, view=None):
         return self.cell_call(0, 0, view)
 
     def cell_call(self, row, col, view=None):
         raise NotImplementedError()
 
-    
+
 class NavigationComponent(Component):
     """abstract base class for navigation components"""
     id = 'navigation'
     __select__ = paginated_rset()
-    
+
     page_size_property = 'navigation.page-size'
     start_param = '__start'
     stop_param = '__stop'
@@ -71,7 +69,7 @@
     selected_page_link_templ = u'<span class="selectedSlice"><a href="%s" title="%s">%s</a></span>'
     previous_page_link_templ = next_page_link_templ = page_link_templ
     no_previous_page_link = no_next_page_link = u''
-    
+
     def __init__(self, req, rset, **kwargs):
         super(NavigationComponent, self).__init__(req, rset, **kwargs)
         self.starting_from = 0
@@ -92,9 +90,9 @@
 
     def set_page_size(self, page_size):
         self._page_size = page_size
-        
+
     page_size = property(get_page_size, set_page_size)
-    
+
     def page_boundaries(self):
         try:
             stop = int(self.req.form[self.stop_param]) + 1
@@ -103,7 +101,7 @@
             start, stop = 0, self.page_size
         self.starting_from = start
         return start, stop
-        
+
     def clean_params(self, params):
         if self.start_param in params:
             del params[self.start_param]
@@ -143,13 +141,13 @@
 class RelatedObjectsVComponent(EntityVComponent):
     """a section to display some related entities"""
     __select__ = EntityVComponent.__select__ & partial_has_related_entities()
-    
+
     vid = 'list'
-    
+
     def rql(self):
         """override this method if you want to use a custom rql query"""
         return None
-    
+
     def cell_call(self, row, col, view=None):
         rql = self.rql()
         if rql is None:
--- a/web/controller.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/controller.py	Fri Apr 24 19:46:47 2009 +0200
@@ -11,7 +11,6 @@
 
 from cubicweb import typed_eid
 from cubicweb.utils import strptime
-from cubicweb.common.registerers import priority_registerer
 from cubicweb.selectors import yes, require_group_compat
 from cubicweb.appobject import AppObject
 from cubicweb.web import LOGGER, Redirect, RequestError
@@ -48,7 +47,7 @@
         for subj in subjs.split('_'):
             for obj in objs.split('_'):
                 yield typed_eid(subj), rtype, typed_eid(obj)
-        
+
 def append_url_params(url, params):
     """append raw parameters to the url. Given parameters, if any, are expected
     to be already url-quoted.
@@ -68,7 +67,6 @@
     and another linked by forms to edit objects ("edit").
     """
     __registry__ = 'controllers'
-    __registerer__ = priority_registerer
     __select__ = yes()
     registered = require_group_compat(AppObject.registered)
 
@@ -77,7 +75,7 @@
         # attributes use to control after edition redirection
         self._after_deletion_path = None
         self._edited_entity = None
-        
+
     def publish(self, rset=None):
         """publish the current request, with an option input rql string
         (already processed if necessary)
@@ -96,7 +94,7 @@
             self.rset = pp.process_query(rql, self.req)
             return self.rset
         return None
-    
+
     def check_expected_params(self, params):
         """check that the given list of parameters are specified in the form
         dictionary
@@ -108,7 +106,7 @@
         if missing:
             raise RequestError('missing required parameter(s): %s'
                                % ','.join(missing))
-    
+
     def parse_datetime(self, value, etype='Datetime'):
         """get a datetime or time from a string (according to etype)
         Datetime formatted as Date are accepted
@@ -144,7 +142,7 @@
         #       relation) that might not be satisfied yet (in case of creations)
         if not self._edited_entity:
             self._edited_entity = entity
-        
+
     def delete_entities(self, eidtypes):
         """delete entities from the repository"""
         redirect_info = set()
@@ -163,7 +161,7 @@
             self.req.set_message(self.req._('entities deleted'))
         else:
             self.req.set_message(self.req._('entity deleted'))
-        
+
     def delete_relations(self, rdefs):
         """delete relations from the repository"""
         # FIXME convert to using the syntax subject:relation:eids
@@ -172,7 +170,7 @@
             rql = 'DELETE X %s Y where X eid %%(x)s, Y eid %%(y)s' % rtype
             execute(rql, {'x': subj, 'y': obj}, ('x', 'y'))
         self.req.set_message(self.req._('relations deleted'))
-    
+
     def insert_relations(self, rdefs):
         """insert relations into the repository"""
         execute = self.req.execute
@@ -180,7 +178,7 @@
             rql = 'SET X %s Y where X eid %%(x)s, Y eid %%(y)s' % rtype
             execute(rql, {'x': subj, 'y': obj}, ('x', 'y'))
 
-    
+
     def reset(self):
         """reset form parameters and redirect to a view determinated by given
         parameters
@@ -224,7 +222,7 @@
         url = self.build_url(path, **newparams)
         url = append_url_params(url, self.req.form.get('__redirectparams'))
         raise Redirect(url)
-    
+
 
     def _return_to_edition_view(self, newparams):
         """apply-button case"""
--- a/web/data/cubicweb.ajax.js	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.ajax.js	Fri Apr 24 19:46:47 2009 +0200
@@ -1,6 +1,6 @@
 /*
  *  :organization: Logilab
- *  :copyright: 2003-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+ *  :copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
  *  :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
  */
 
@@ -18,8 +18,7 @@
     jQuery(node).find('div.ajaxHtmlHead').appendTo(jQuery('head'));
 }
 
-function postAjaxLoad(node, req) {
-    // addStylesheets(evalJSON(req.getResponseHeader('X-Cubicweb-Stylesheets') || '[]'));
+function postAjaxLoad(node) {
     loadAjaxHtmlHead(node);
     // find sortable tables if there are some
     if (typeof(Sortable) != 'undefined') {
@@ -38,6 +37,7 @@
     if (typeof roundedCornersOnLoad != 'undefined') {
 	roundedCornersOnLoad();
     }
+    jQuery(CubicWeb).trigger('ajax-loaded');
 }
 
 // cubicweb loadxhtml plugin to make jquery handle xhtml response
@@ -71,7 +71,7 @@
 	} else if (mode == 'append') {
 	    jQuery(node).append(domnode);
 	}
-	postAjaxLoad(node, req);
+	postAjaxLoad(node);
 	while (jQuery.isFunction(callback)) {
 	    callback = callback.apply(this, [domnode]);
 	}
@@ -110,22 +110,6 @@
 
 //============= base AJAX functions to make remote calls =====================//
 
-
-/*
- * This function will call **synchronously** a remote method on the cubicweb server
- * @param fname: the function name to call (as exposed by the JSONController)
- * @param args: the list of arguments to pass the function
- */
-function remote_exec(fname) {
-    setProgressCursor();
-    var props = {'mode' : "remote", 'fname' : fname, 'pageid' : pageid,
-     		 'arg': map(jQuery.toJSON, sliceList(arguments, 1))};
-    var result  = jQuery.ajax({url: JSON_BASE_URL, data: props, async: false}).responseText;
-    result = evalJSON(result);
-    resetCursor();
-    return result;
-}
-
 function remoteCallFailed(err, req) {
     if (req.status == 500) {
 	updateMessage(err);
@@ -138,88 +122,66 @@
  * This function is the equivalent of MochiKit's loadJSONDoc but
  * uses POST instead of GET
  */
-function loadJSONDocUsingPOST(url, queryargs, mode) {
-    mode = mode || 'remote';
+function loadJSONDocUsingPOST(url, data) {
     setProgressCursor();
-    var dataType = (mode == 'remote') ? "json":null;
-    var deferred = loadJSON(url, queryargs, 'POST', dataType);
+    var deferred = loadJSON(url, data, 'POST');
     deferred = deferred.addErrback(remoteCallFailed);
-//     if (mode == 'remote') {
-// 	deferred = deferred.addCallbacks(evalJSONRequest);
-//     }
     deferred = deferred.addCallback(resetCursor);
     return deferred;
 }
 
 
-function _buildRemoteArgs(fname) {
-    return  {'mode' : "remote", 'fname' : fname, 'pageid' : pageid,
-     	     'arg': map(jQuery.toJSON, sliceList(arguments, 1))};
-}
-
 /*
- * This function will call **asynchronously** a remote method on the cubicweb server
- * This function is a low level one. You should use `async_remote_exec` or
- * `async_rawremote_exec` instead.
+ * This function will call **synchronously** a remote method on the cubicweb server
+ * @param fname: the function name to call (as exposed by the JSONController)
+ *
+ * additional arguments will be directly passed to the specified function
  *
- * @param fname: the function name to call (as exposed by the JSONController)
- * @param funcargs: the function's arguments
- * @param mode: rawremote or remote
+ * It looks at http headers to guess the response type.
  */
-function _async_exec(fname, funcargs, mode) {
-    var props = {'mode' : mode, 'fname' : fname, 'pageid' : pageid};
-    var args = map(urlEncode, map(jQuery.toJSON, funcargs));
-    args.unshift(''); // this is to be able to use join() directly
-    var queryargs = as_url(props) + args.join('&arg=');
-    return loadJSONDocUsingPOST(JSON_BASE_URL, queryargs, mode);
+function remoteExec(fname /* ... */) {
+    setProgressCursor();
+    var props = {'fname' : fname, 'pageid' : pageid,
+     		 'arg': map(jQuery.toJSON, sliceList(arguments, 1))};
+    var result  = jQuery.ajax({url: JSON_BASE_URL, data: props, async: false}).responseText;
+    if (result) {
+	result = evalJSON(result);
+    }
+    resetCursor();
+    return result;
 }
 
 /*
- * This function will call **asynchronously** a remote method on the cubicweb server
+ * This function will call **asynchronously** a remote method on the json
+ * controller of the cubicweb http server
+ *
  * @param fname: the function name to call (as exposed by the JSONController)
+ *
  * additional arguments will be directly passed to the specified function
- * Expected response type is Json.
- */
-function async_remote_exec(fname /* ... */) {
-    return _async_exec(fname, sliceList(arguments, 1), 'remote');
-}
-
-/*
- * This version of _async_exec doesn't expect a json response.
+ *
  * It looks at http headers to guess the response type.
  */
-function async_rawremote_exec(fname /* ... */) {
-    return _async_exec(fname, sliceList(arguments, 1), 'rawremote');
+function asyncRemoteExec(fname /* ... */) {
+    var props = {'fname' : fname, 'pageid' : pageid,
+     		 'arg': map(jQuery.toJSON, sliceList(arguments, 1))};
+    return loadJSONDocUsingPOST(JSON_BASE_URL, props);
 }
 
-/*
- * This function will call **asynchronously** a remote method on the cubicweb server
- * @param fname: the function name to call (as exposed by the JSONController)
- * @param varargs: the list of arguments to pass to the function
- * This is an alternative form of `async_remote_exec` provided for convenience
- */
-function async_remote_exec_varargs(fname, varargs) {
-    return _async_exec(fname, varargs, 'remote');
-}
 
 /* emulation of gettext's _ shortcut
  */
 function _(message) {
-    return remote_exec('i18n', [message])[0];
-}
-
-function rqlexec(rql) {
-    return async_remote_exec('rql', rql);
+    return remoteExec('i18n', [message])[0];
 }
 
 function userCallback(cbname) {
-    async_remote_exec('user_callback', cbname);
+    asyncRemoteExec('user_callback', cbname);
 }
 
 function unloadPageData() {
     // NOTE: do not make async calls on unload if you want to avoid
     //       strange bugs
-    remote_exec('unload_page_data');
+    remoteExec('unload_page_data');
 }
 
 function openHash() {
@@ -237,7 +199,7 @@
     nodeid = nodeid || (compid + 'Component');
     extraargs = extraargs || {};
     var node = getNode(nodeid);
-    var d = async_rawremote_exec('component', compid, rql, registry, extraargs);
+    var d = asyncRemoteExec('component', compid, rql, registry, extraargs);
     d.addCallback(function(result, req) {
 	var domnode = getDomFromResponse(result);
 	if (node) {
@@ -260,7 +222,7 @@
 }
 
 function userCallbackThenUpdateUI(cbname, compid, rql, msg, registry, nodeid) {
-    var d = async_remote_exec('user_callback', cbname);
+    var d = asyncRemoteExec('user_callback', cbname);
     d.addCallback(function() {
 	reloadComponent(compid, rql, registry, nodeid);
 	if (msg) { updateMessage(msg); }
@@ -274,7 +236,7 @@
 }
 
 function userCallbackThenReloadPage(cbname, msg) {
-    var d = async_remote_exec('user_callback', cbname);
+    var d = asyncRemoteExec('user_callback', cbname);
     d.addCallback(function() {
 	window.location.reload();
 	if (msg) { updateMessage(msg); }
@@ -292,7 +254,7 @@
  * while the page was generated.
  */
 function unregisterUserCallback(cbname) {
-    var d = async_remote_exec('unregister_user_callback', cbname);
+    var d = asyncRemoteExec('unregister_user_callback', cbname);
     d.addCallback(function() {resetCursor();});
     d.addErrback(function(xxx) {
 	updateMessage(_("an error occured"));
@@ -323,11 +285,11 @@
 	props['pageid'] = pageid;
 	if (vid) { props['vid'] = vid; }
 	if (extraparams) { jQuery.extend(props, extraparams); }
-	// FIXME we need to do as_url(props) manually instead of
+	// FIXME we need to do asURL(props) manually instead of
 	// passing `props` directly to loadxml because replacePageChunk
 	// is sometimes called (abusively) with some extra parameters in `vid`
 	var mode = swap?'swap':'replace';
-	var url = JSON_BASE_URL + as_url(props);
+	var url = JSON_BASE_URL + asURL(props);
 	jQuery(node).loadxhtml(url, params, 'get', mode);
     } else {
 	log('Node', nodeId, 'not found');
@@ -358,6 +320,22 @@
 jQuery(document).ready(buildWysiwygEditors);
 
 
+/*
+ * takes a list of DOM nodes and removes all empty text nodes
+ */
+function stripEmptyTextNodes(nodelist) {
+    var stripped = [];
+    for (var i=0; i < nodelist.length; i++) {
+	var node = nodelist[i];
+	if (isTextNode(node) && !node.textContent.strip()) {
+	    continue;
+	} else {
+	    stripped.push(node);
+	}
+    }
+    return stripped;
+}
+
 /* convenience function that returns a DOM node based on req's result. */
 function getDomFromResponse(response) {
     if (typeof(response) == 'string') {
@@ -369,6 +347,7 @@
 	// no child (error cases) => return the whole document
 	return doc.cloneNode(true);
     }
+    children = stripEmptyTextNodes(children);
     if (children.length == 1) {
 	// only one child => return it
 	return children[0].cloneNode(true);
--- a/web/data/cubicweb.bookmarks.js	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.bookmarks.js	Fri Apr 24 19:46:47 2009 +0200
@@ -1,7 +1,7 @@
 CubicWeb.require('ajax.js');
 
 function removeBookmark(beid) {
-    d = async_remote_exec('delete_bookmark', beid);
+    d = asyncRemoteExec('delete_bookmark', beid);
     d.addCallback(function(boxcontent) {
 	    reloadComponent('bookmarks_box', '', 'boxes', 'bookmarks_box');
   	document.location.hash = '#header';
--- a/web/data/cubicweb.calendar.js	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.calendar.js	Fri Apr 24 19:46:47 2009 +0200
@@ -235,7 +235,7 @@
     //      the only way understood by both IE and Mozilla. Otherwise,
     //      IE accepts innerText and mozilla accepts textContent
     var selectedDate = new Date(cal.year, cal.month, cell.innerHTML, 12);
-    var xxx = remote_exec("format_date", toISOTimestamp(selectedDate));
+    var xxx = remoteExec("format_date", toISOTimestamp(selectedDate));
     input.value = xxx;
     cal.hide();
 }
--- a/web/data/cubicweb.compat.js	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.compat.js	Fri Apr 24 19:46:47 2009 +0200
@@ -365,13 +365,12 @@
 };
 
 
-function loadJSON(url, data, type, dataType) {
+function loadJSON(url, data, type) {
     var d = new Deferred();
     jQuery.ajax({
 	url: url,
 	type: type,
 	data: data,
-	dataType: dataType,
 
 	beforeSend: function(xhr) {
 	    d.req = xhr;
--- a/web/data/cubicweb.edition.js	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.edition.js	Fri Apr 24 19:46:47 2009 +0200
@@ -1,6 +1,6 @@
 /*
  *  :organization: Logilab
- *  :copyright: 2003-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+ *  :copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
  *  :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
  */
 
@@ -22,7 +22,8 @@
 function setPropValueWidget(varname, tabindex) {
     var key = firstSelected(document.getElementById('pkey:'+varname));
     if (key) {
-	var args = _buildRemoteArgs('prop_widget', key, varname, tabindex);
+	var args = {fname: 'prop_widget', pageid: pageid,
+     		    arg: map(jQuery.toJSON, [key, varname, tabindex])};
 	jqNode('div:value:'+varname).loadxhtml(JSON_BASE_URL, args, 'post');
     }
 }
@@ -51,40 +52,25 @@
     });
 }
 
+
 function showMatchingSelect(selectedValue, eid) {
     if (selectedValue) {
 	divId = 'div' + selectedValue + '_' + eid;
 	var divNode = jQuery('#' + divId);
 	if (!divNode.length) {
 	    var args = {vid: 'unrelateddivs', relation: selectedValue,
-			rql: rql_for_eid(eid), pageid: pageid,
-			'__notemplate': 1};
-	    jQuery.get(JSON_BASE_URL, args, function(response) {
-		// append generated HTML to the cell
-		jQuery('#unrelatedDivs_' + eid).append(getDomFromResponse(response));
-		_showMatchingSelect(eid, jQuery('#' + divId));
-	    });
-	    // deferred = doXHR(JSON_BASE_URL + queryString(args));
-	    // deferred.addCallback(_buildAndShowMatchingSelect, eid, divId);
+			rql: rql_for_eid(eid), '__notemplate': 1,
+			callback: function() {_showMatchingSelect(eid, jQuery('#' + divId))}};
+	    jQuery('#unrelatedDivs_' + eid).loadxhtml(baseuri() + 'view', args, 'post', 'append');
 	} else {
 	    _showMatchingSelect(eid, divNode);
 	}
-    }
-    else {
+    } else {
 	_showMatchingSelect(eid, null);
     }
 }
 
 
-
-// @param divStr a HTML string returned by the server
-// function _buildAndShowMatchingSelect(eid, divId, req) {
-//     var tdNode = jQuery('#unrelatedDivs_' + eid);
-//     // append generated HTML to the cell
-//     tdNode.appendChild(getDomFromRequest(req));
-//     _showMatchingSelect(eid, jQuery('#' + divId));
-// }
-
 // @param divNode is a jQuery selection
 function _showMatchingSelect(eid, divNode) {
     // hide all divs, and then show the matching one
@@ -154,7 +140,7 @@
     // add hidden parameter
     var entityForm = jQuery('#entityForm');
     var oid = optionNode.id.substring(2); // option id is prefixed by "id"
-    remote_exec('add_pending_insert', oid.split(':'));
+    remoteExec('add_pending_inserts', [oid.split(':')]);
     var selectNode = optionNode.parentNode;
     // remove option node
     selectNode.removeChild(optionNode);
@@ -186,7 +172,7 @@
 	   options[options.length] = OPTION({'id' : elementId, 'value' : node_id}, entityView);
 	}
     }
-    remote_exec('remove_pending_insert', elementId.split(':'));
+    remoteExec('remove_pending_insert', elementId.split(':'));
 }
 
 // this function builds a Handle to cancel pending insertion
@@ -198,7 +184,7 @@
 
 // @param nodeId eid_from:r_type:eid_to
 function addPendingDelete(nodeId, eid) {
-    var d = async_remote_exec('add_pending_delete', nodeId.split(':'));
+    var d = asyncRemoteExec('add_pending_delete', nodeId.split(':'));
     d.addCallback(function () {
 	// and strike entity view
 	jqNode('span' + nodeId).addClass('pendingDelete');
@@ -209,7 +195,7 @@
 
 // @param nodeId eid_from:r_type:eid_to
 function cancelPendingDelete(nodeId, eid) {
-    var d = async_remote_exec('remove_pending_delete', nodeId.split(':'));
+    var d = asyncRemoteExec('remove_pending_delete', nodeId.split(':'));
     d.addCallback(function () {
 	// reset link's CSS class
 	jqNode('span' + nodeId).removeClass('pendingDelete');
@@ -232,11 +218,11 @@
 function selectForAssociation(tripletIdsString, originalEid) {
     var tripletlist = map(function (x) { return x.split(':'); },
 			  tripletIdsString.split('-'));
-    var d = async_remote_exec('add_pending_inserts', tripletlist);
+    var d = asyncRemoteExec('add_pending_inserts', tripletlist);
     d.addCallback(function () {
 	var args = {vid: 'edition', __mode: 'normal',
 		    rql: rql_for_eid(originalEid)};
-	document.location = 'view?' + as_url(args);
+	document.location = 'view?' + asURL(args);
     });
 
 }
@@ -246,13 +232,9 @@
     jQuery('#inline' + rtype + 'slot span.icounter').each(function (i) {
 	this.innerHTML = i+1;
     });
-    // var divnode = jQuery('#inline' + rtype + 'slot');
-    // var iforms = getElementsByTagAndClassName('span', 'icounter', divnode);
-    // for (var i=0; i<iforms.length; i++) {
-    //   iforms[i].innerHTML = i+1;
-    // }
 }
 
+
 /*
  * makes an AJAX request to get an inline-creation view's content
  * @param peid : the parent entity eid
@@ -260,21 +242,17 @@
  * @param rtype : the relation type between both entities
  */
 function addInlineCreationForm(peid, ttype, rtype, role) {
-    var d = async_rawremote_exec('inline_creation_form', peid, ttype, rtype, role);
+    var d = asyncRemoteExec('inline_creation_form', peid, ttype, rtype, role);
     d.addCallback(function (response) {
 	var linknode = getNode('add' + rtype + ':' + peid + 'link');
         var dom = getDomFromResponse(response);
 	var form = jQuery(dom);
 	form.css('display', 'none');
 	form.insertBefore(linknode.parentNode).slideDown('fast');
-	// setStyle(form, {display: 'none'});
-	// insertSiblingNodesBefore(linknode.parentNode, form);
 	updateInlinedEntitiesCounters(rtype);
-	// slideDown(form, {'duration':0.6});
 	reorderTabindex();
 	form.trigger('inlinedform-added');
         postAjaxLoad(dom);
-	// MochiKit.Signal.signal(CubicWeb, 'inlinedform-added', form);
     });
     d.addErrback(function (xxx) {
 	log('xxx =', xxx);
@@ -300,15 +278,13 @@
  */
 function removeInlinedEntity(peid, rtype, eid) {
     var nodeid = ['rel', peid, rtype, eid].join('-');
-    var divid = ['div', peid, rtype, eid].join('-');
-    var noticeid = ['notice', peid, rtype, eid].join('-');
     var node = jqNode(nodeid);
     if (node && node.length) {
 	node.remove();
+	var divid = ['div', peid, rtype, eid].join('-');
 	jqNode(divid).fadeTo('fast', 0.5);
-	// setOpacity(divid, 0.4);
+	var noticeid = ['notice', peid, rtype, eid].join('-');
 	jqNode(noticeid).fadeIn('fast');
-	// appear(jQuery('#' + noticeid), {'duration': 0.5});
     }
 }
 
@@ -321,11 +297,8 @@
 	node = INPUT({type: 'hidden', id: nodeid,
 		      name: rtype+':'+peid, value: eid});
 	jqNode(['fs', peid, rtype, eid].join('-')).append(node);
-	// appendChildNodes(fs, node);
 	jqNode(divid).fadeTo('fast', 1);
-	// setOpacity(divid, 1);
 	jqNode(noticeid).hide();
-	// jQuery('#' + noticeid).hide();
     }
 }
 
@@ -433,8 +406,8 @@
 	var target = form.attr('cubicweb:target');
 	if (target) {
 	    form.attr('target', target);
-	    /* do not use display: none because some browser ignore iframe
-             *     with no display */
+	    /* do not use display: none because some browsers ignore iframe
+             * with no display */
 	    form.append(IFRAME({name: target, id: target,
 				src: 'javascript: void(0)',
 				width: '0px', height: '0px'}));
@@ -444,10 +417,6 @@
 
 $(document).ready(setFormsTarget);
 
-function _sendForm(formid, action) {
-    var zipped = formContents(formid);
-    return async_remote_exec('validate_form', action, zipped[0], zipped[1]);
-}
 
 /*
  * called on traditionnal form submission : the idea is to try
@@ -457,7 +426,8 @@
  */
 function validateForm(formid, action, onsuccess) {
     try {
-	var d = _sendForm(formid, action);
+	var zipped = formContents(formid);
+	var d = asyncRemoteExec('validate_form', action, zipped[0], zipped[1]);
     } catch (ex) {
 	log('got exception', ex);
 	return false;
@@ -465,11 +435,11 @@
     function _callback(result, req) {
 	handleFormValidationResponse(formid, onsuccess, result);
     }
-    // d.addCallback(handleFormValidationResponse, formid, onsuccess);
     d.addCallback(_callback);
     return false;
 }
 
+
 /*
  * called by live-edit forms to submit changes
  * @param formid : the dom id of the form used
@@ -489,7 +459,7 @@
 	    }
 	}
 	var zipped = formContents(form);
-	var d = async_remote_exec('edit_field', 'apply', zipped[0], zipped[1], rtype, eid);
+	var d = asyncRemoteExec('edit_field', 'apply', zipped[0], zipped[1], rtype, eid);
     } catch (ex) {
 	log('got exception', ex);
 	return false;
--- a/web/data/cubicweb.form.css	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.form.css	Fri Apr 24 19:46:47 2009 +0200
@@ -56,7 +56,8 @@
 table.attributeForm {
   border: 1px solid #E4EAD8;
   margin-bottom: 1em;
-  padding: 0.8em;
+  padding: 0.8em 1.2em;
+  width: 100%;
 }
 
 fieldset.subentity table td {
@@ -77,11 +78,12 @@
 
 table.attributeForm th,
 table.attributeForm td {
-  padding : 0px 2px;
+  padding : .7em 2px;
 }
 
 table.attributeForm th {
-  text-align: right;
+  text-align: left;
+  width: 12em;
 }
 
 table.attributeForm div#comfirmPsw {
@@ -100,7 +102,7 @@
 
 table.attributeForm label,
 .entityForm .label {
-  padding : 0.2em  10px 0.2em 0.4em;
+  padding : 0.2em  1em 0.2em 0;
 }
 
 table.attributeForm label.required {
--- a/web/data/cubicweb.formfilter.js	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.formfilter.js	Fri Apr 24 19:46:47 2009 +0200
@@ -43,7 +43,7 @@
     var zipped = facetFormContent(form);
     zipped[0].push('facetargs');
     zipped[1].push(vidargs);
-    var d = async_remote_exec('filter_build_rql', zipped[0], zipped[1]);
+    var d = asyncRemoteExec('filter_build_rql', zipped[0], zipped[1]);
     d.addCallback(function(result) {
 	var rql = result[0];
 	var $bkLink = jQuery('#facetBkLink');
@@ -80,7 +80,7 @@
 		reloadComponent('edit_box', rql, 'boxes', 'edit_box');
 	    }
 	}
-	var d = async_remote_exec('filter_select_content', toupdate, rql);
+	var d = asyncRemoteExec('filter_select_content', toupdate, rql);
 	d.addCallback(function(updateMap) {
 	    for (facetId in updateMap) {
 		var values = updateMap[facetId];
--- a/web/data/cubicweb.htmlhelpers.js	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.htmlhelpers.js	Fri Apr 24 19:46:47 2009 +0200
@@ -111,13 +111,13 @@
 }
 
 /* builds an url from an object (used as a dictionnary)
- * Notable difference with MochiKit's queryString: as_url does not
+ * Notable difference with MochiKit's queryString: asURL does not
  * *url_quote* each value found in the dictionnary
  *
- * >>> as_url({'rql' : "RQL", 'x': [1, 2], 'itemvid' : "oneline"})
+ * >>> asURL({'rql' : "RQL", 'x': [1, 2], 'itemvid' : "oneline"})
  * rql=RQL&vid=list&itemvid=oneline&x=1&x=2
  */
-function as_url(props) {
+function asURL(props) {
     var chunks = [];
     for(key in props) {
 	var value = props[key];
--- a/web/data/cubicweb.mailform.css	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.mailform.css	Fri Apr 24 19:46:47 2009 +0200
@@ -5,7 +5,7 @@
  *  :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
  */
 
-div#compose {
+form#sendmail {
   border: 1px solid #DBDCE3;
   background-color: #E9F5F7;
   font-family:Verdana,Tahoma,Arial,sans-serif;
@@ -16,7 +16,7 @@
   width: 100%;
 }
 
-div#compose td#buttonbar {
+form#sendmail td#buttonbar {
   padding: 0.5ex 0ex;
 }
 
@@ -36,12 +36,12 @@
   width: 47em; 
 }
 
-div#compose div#toolbar {
+form#sendmail div#toolbar {
   margin: 0.5em 0em;
   height: 29px;
 }
 
-div#compose div#toolbar ul {
+form#sendmail div#toolbar ul {
   list-style-image: none;
   list-style-position: outside;
   list-style-type:none;
@@ -50,13 +50,13 @@
   /* border: 1px solid #DBDCE3; */
 }
 
-div#compose div#toolbar li {
+form#sendmail div#toolbar li {
   background: none;
   padding-left: 1em;
   float: left;
 }
 
-div#compose div#toolbar li a {
+form#sendmail div#toolbar li a {
   font-family: Verdana,Tahoma,Arial,sans-serif;
   color: #444444;
 }
--- a/web/data/cubicweb.preferences.js	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.preferences.js	Fri Apr 24 19:46:47 2009 +0200
@@ -5,6 +5,6 @@
  */
 function toggle_and_remember_visibility(elemId, cookiename) {
     jqNode(elemId).toggleClass('hidden');
-    async_remote_exec('set_cookie', cookiename,
+    asyncRemoteExec('set_cookie', cookiename,
                       jQuery('#' + elemId).attr('class'));
 }
--- a/web/data/cubicweb.tabs.js	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.tabs.js	Fri Apr 24 19:46:47 2009 +0200
@@ -1,6 +1,6 @@
 function set_tab(tabname, cookiename) {
     // set appropriate cookie
-    async_remote_exec('set_cookie', cookiename, tabname);
+    asyncRemoteExec('set_cookie', cookiename, tabname);
     // trigger show + tabname event
     trigger_load(tabname);
 }
--- a/web/data/cubicweb.widgets.js	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/data/cubicweb.widgets.js	Fri Apr 24 19:46:47 2009 +0200
@@ -222,41 +222,46 @@
 
     __init__ : function(wdgnode) {
 	this.variables = getNodeAttribute(wdgnode, 'cubicweb:variables').split(',');
-	this.options = {'name' : wdgnode.getAttribute('cubicweb:inputname'),
-			'id'   : wdgnode.getAttribute('cubicweb:inputid'),
+	this.options = {'name'   : wdgnode.getAttribute('cubicweb:inputid'),
 			'rows' : wdgnode.getAttribute('cubicweb:rows') || 40,
 			'cols' : wdgnode.getAttribute('cubicweb:cols') || 80
 		       };
 	// this.variableRegexp = /%\((\w+)\)s/;
-	this.errorField = DIV({'class' : "textfieldErrors"});
+	this.errorField = DIV({'class' : "errorMessage"});
 	this.textField = TEXTAREA(this.options);
 	jQuery(this.textField).bind('keyup', {'self': this}, this.highlightInvalidVariables);
+	jQuery('#substitutions').prepend(this.errorField);
+	jQuery('#substitutions .errorMessage').hide();
 	wdgnode.appendChild(this.textField);
-	wdgnode.appendChild(this.errorField);
     },
 
     /* signal callbacks */
 
-    highlightInvalidVariables : function() {
-	var text = this.textField.value;
+    highlightInvalidVariables : function(event) {
+	var self = event.data.self;
+	var text = self.textField.value;
 	var unknownVariables = [];
-	var it=0;
+	var it = 0;
 	var group = null;
 	var variableRegexp = /%\((\w+)\)s/g;
 	// emulates rgx.findAll()
 	while ( group=variableRegexp.exec(text) ) {
-	    if ( !this.variables.contains(group[1]) ) {
+	    if ( !self.variables.contains(group[1]) ) {
 		unknownVariables.push(group[1]);
 	    }
 	    it++;
-	    if (it > 5)
+	    if (it > 5) {
 		break;
+	    }
 	}
 	var errText = '';
 	if (unknownVariables.length) {
 	    errText = "Detected invalid variables : " + ", ".join(unknownVariables);
+	    jQuery('#substitutions .errorMessage').show();
+	} else {
+	    jQuery('#substitutions .errorMessage').hide();
 	}
-	this.errorField.innerHTML = errText;
+	self.errorField.innerHTML = errText;
     }
 
 });
@@ -277,14 +282,14 @@
 	  this.eid_to = name[1];
           this.etype_to = wdgnode.getAttribute('cubicweb:etype_to');
           this.etype_from = wdgnode.getAttribute('cubicweb:etype_from');
-     	  var d = async_remote_exec('add_and_link_new_entity', this.etype_to, this.rel, this.eid_to, this.etype_from, 'new_val');
+     	  var d = asyncRemoteExec('add_and_link_new_entity', this.etype_to, this.rel, this.eid_to, this.etype_from, 'new_val');
           d.addCallback(function (eid) {
-          jQuery(wdgnode).find("option[selected]").removeAttr("selected");
-          var new_option = OPTION({'value':eid, 'selected':'selected'}, value=new_val);
-          wdgnode.appendChild(new_option);
+	      jQuery(wdgnode).find("option[selected]").removeAttr("selected");
+              var new_option = OPTION({'value':eid, 'selected':'selected'}, value=new_val);
+              wdgnode.appendChild(new_option);
           });
           d.addErrback(function (xxx) {
-             log('xxx =', xxx);
+              log('xxx =', xxx);
           });
      });
    }
--- a/web/facet.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/facet.py	Fri Apr 24 19:46:47 2009 +0200
@@ -21,7 +21,6 @@
 from cubicweb import Unauthorized, typed_eid
 from cubicweb.selectors import match_context_prop, partial_relation_possible
 from cubicweb.appobject import AppRsetObject
-from cubicweb.common.registerers import priority_registerer
 from cubicweb.web.htmlwidgets import HTMLWidget
 
 ## rqlst manipulation functions used by facets ################################
@@ -239,7 +238,6 @@
 
 ## base facet classes #########################################################
 class AbstractFacet(AppRsetObject):
-    __registerer__ = priority_registerer
     __abstract__ = True
     __registry__ = 'facets'
     property_defs = {
@@ -341,7 +339,7 @@
     __select__ = partial_relation_possible() & match_context_prop()
     # class attributes to configure the rel ation facet
     rtype = None
-    role = 'subject' 
+    role = 'subject'
     target_attr = 'eid'
     # set this to a stored procedure name if you want to sort on the result of
     # this function's result instead of direct value
--- a/web/form.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/form.py	Fri Apr 24 19:46:47 2009 +0200
@@ -29,7 +29,7 @@
     controller = 'edit'
     http_cache_manager = NoHTTPCacheManager
     add_to_breadcrumbs = False
-    
+
     def __init__(self, req, rset, **kwargs):
         super(FormViewMixIn, self).__init__(req, rset, **kwargs)
         # get validation session data which may have been previously set.
@@ -51,7 +51,7 @@
                     break
             else:
                 errex.eid = foreid
-        
+
     def html_headers(self):
         """return a list of html headers (eg something to be inserted between
         <head> and </head> of the returned page
@@ -59,7 +59,7 @@
         by default forms are neither indexed nor followed
         """
         return [NOINDEX, NOFOLLOW]
-        
+
     def linkable(self):
         """override since forms are usually linked by an action,
         so we don't want them to be listed by appli.possible_views
@@ -67,7 +67,7 @@
         return False
 
 
-# XXX should disappear 
+# XXX should disappear
 class FormMixIn(object):
     """abstract form mix-in
     XXX: you should inherit from this FIRST (obscure pb with super call)
@@ -81,13 +81,13 @@
         self.varmaker = varmaker
 
     # XXX deprecated with new form system. Should disappear
-    
+
     domid = 'entityForm'
     category = 'form'
     controller = 'edit'
     http_cache_manager = NoHTTPCacheManager
     add_to_breadcrumbs = False
-    
+
     def __init__(self, req, rset, **kwargs):
         super(FormMixIn, self).__init__(req, rset, **kwargs)
         # get validation session data which may have been previously set.
@@ -108,8 +108,8 @@
                     errex.eid = var
                     break
             else:
-                errex.eid = foreid    
-        
+                errex.eid = foreid
+
     def html_headers(self):
         """return a list of html headers (eg something to be inserted between
         <head> and </head> of the returned page
@@ -117,7 +117,7 @@
         by default forms are neither indexed nor followed
         """
         return [NOINDEX, NOFOLLOW]
-        
+
     def linkable(self):
         """override since forms are usually linked by an action,
         so we don't want them to be listed by appli.possible_views
@@ -140,7 +140,7 @@
                   **kwargs):
         label = self.req._(label or stdmsgs.BUTTON_OK).capitalize()
         return self.button(label, name=name, type=type, **kwargs)
-    
+
     def button_apply(self, label=None, type='button', **kwargs):
         label = self.req._(label or stdmsgs.BUTTON_APPLY).capitalize()
         return self.action_button(label, __action='apply', type=type, **kwargs)
@@ -148,11 +148,11 @@
     def button_delete(self, label=None, type='button', **kwargs):
         label = self.req._(label or stdmsgs.BUTTON_DELETE).capitalize()
         return self.action_button(label, __action='delete', type=type, **kwargs)
-    
+
     def button_cancel(self, label=None, type='button', **kwargs):
         label = self.req._(label or stdmsgs.BUTTON_CANCEL).capitalize()
         return self.action_button(label, __action='cancel', type=type, **kwargs)
-    
+
     def button_reset(self, label=None, type='reset', name='__action_cancel',
                      **kwargs):
         label = self.req._(label or stdmsgs.BUTTON_CANCEL).capitalize()
@@ -174,7 +174,7 @@
                 if inlined_entity.get_widget(irschema, x).need_multipart:
                     return True
         return False
-    
+
     def error_message(self):
         """return formatted error message
 
@@ -189,7 +189,7 @@
                             if not field in displayed)
             if errors:
                 if len(errors) > 1:
-                    templstr = '<li>%s</li>\n' 
+                    templstr = '<li>%s</li>\n'
                 else:
                     templstr = '&nbsp;%s\n'
                 for field, err in errors:
@@ -206,8 +206,8 @@
 ###############################################################################
 
 class metafieldsform(type):
-    """metaclass for FieldsForm to retreive fields defined as class attribute
-    and put them into a single ordered list, '_fields_'.
+    """metaclass for FieldsForm to retrieve fields defined as class attributes
+    and put them into a single ordered list: '_fields_'.
     """
     def __new__(mcs, name, bases, classdict):
         allfields = []
@@ -223,19 +223,19 @@
         classdict['_fields_'] = allfields
         return super(metafieldsform, mcs).__new__(mcs, name, bases, classdict)
 
-    
+
 class FieldNotFound(Exception):
     """raised by field_by_name when a field with the given name has not been
     found
     """
-    
+
 class FieldsForm(FormMixIn, AppRsetObject):
     __metaclass__ = metafieldsform
     __registry__ = 'forms'
     __select__ = yes()
-    
+
     is_subform = False
-    
+
     # attributes overrideable through __init__
     internal_fields = ('__errorurl',) + NAV_FORM_PARAMETERS
     needs_js = ('cubicweb.ajax.js', 'cubicweb.edition.js',)
@@ -251,21 +251,25 @@
     set_error_url = True
     copy_nav_params = False
     form_buttons = None # form buttons (button widgets instances)
-                 
+
     def __init__(self, req, rset=None, row=None, col=None, submitmsg=None,
                  **kwargs):
         super(FieldsForm, self).__init__(req, rset, row=row, col=col)
+        self.fields = list(self.__class__._fields_)
         for key, val in kwargs.items():
-            assert hasattr(self.__class__, key) and not key[0] == '_', key
-            setattr(self, key, val)
-        self.fields = list(self.__class__._fields_)
+            if key in NAV_FORM_PARAMETERS:
+                self.form_add_hidden(key, val)
+            else:
+                assert hasattr(self.__class__, key) and not key[0] == '_', key
+                setattr(self, key, val)
         if self.set_error_url:
             self.form_add_hidden('__errorurl', req.url())
         if self.copy_nav_params:
             for param in NAV_FORM_PARAMETERS:
-                value = kwargs.get(param, req.form.get(param))
-                if value:
-                    self.form_add_hidden(param, value)
+                if not param in kwargs:
+                    value = req.form.get(param)
+                    if value:
+                        self.form_add_hidden(param, value)
         if submitmsg is not None:
             self.form_add_hidden('__message', submitmsg)
         self.context = None
@@ -281,7 +285,7 @@
             if field.name == name and field.role == role:
                 return field
         raise FieldNotFound(name)
-    
+
     @iclassmethod
     def remove_field(cls_or_self, field):
         """remove a field from form class or instance"""
@@ -290,7 +294,7 @@
         else:
             fields = cls_or_self.fields
         fields.remove(field)
-    
+
     @iclassmethod
     def append_field(cls_or_self, field):
         """append a field to form class or instance"""
@@ -299,11 +303,11 @@
         else:
             fields = cls_or_self.fields
         fields.append(field)
-    
+
     @property
     def form_needs_multipart(self):
         """true if the form needs enctype=multipart/form-data"""
-        return any(field.needs_multipart for field in self.fields) 
+        return any(field.needs_multipart for field in self.fields)
 
     def form_add_hidden(self, name, value=None, **kwargs):
         """add an hidden field to the form"""
@@ -313,9 +317,9 @@
             # by default, hidden input don't set id attribute. If one is
             # explicitly specified, ensure it will be set
             field.widget.setdomid = True
-        self.fields.append(field)
+        self.append_field(field)
         return field
-    
+
     def add_media(self):
         """adds media (CSS & JS) required by this widget"""
         if self.needs_js:
@@ -357,7 +361,7 @@
 
     def form_field_display_value(self, field, rendervalues, load_bytes=False):
         """return field's *string* value to use for display
-        
+
         looks in
         1. previously submitted form values if any (eg on validation error)
         2. req.form
@@ -378,7 +382,7 @@
                 value = self.form_field_value(field, load_bytes)
                 if callable(value):
                     value = value(self)
-            if value != INTERNAL_FIELD_VALUE: 
+            if value != INTERNAL_FIELD_VALUE:
                 value = field.format_value(self.req, value)
         return value
 
@@ -388,7 +392,7 @@
         if callable(value):
             value = value(self)
         return value
-    
+
     def form_field_error(self, field):
         """return validation error for widget's field, if any"""
         errex = self.req.data.get('formerrors')
@@ -400,11 +404,11 @@
     def form_field_format(self, field):
         """return MIME type used for the given (text or bytes) field"""
         return self.req.property_value('ui.default-text-format')
-    
+
     def form_field_encoding(self, field):
         """return encoding used for the given (text) field"""
         return self.req.encoding
-    
+
     def form_field_name(self, field):
         """return qualified name for the given field"""
         return field.name
@@ -412,7 +416,7 @@
     def form_field_id(self, field):
         """return dom id for the given field"""
         return field.id
-   
+
     def form_field_vocabulary(self, field, limit=None):
         """return vocabulary for the given field. Should be overriden in
         specific forms using fields which requires some vocabulary
@@ -424,13 +428,13 @@
         """
         return field.name in errex.errors
 
-   
+
 class EntityFieldsForm(FieldsForm):
     __select__ = (match_kwargs('entity') | (one_line_rset & non_final_entity()))
-    
+
     internal_fields = FieldsForm.internal_fields + ('__type', 'eid')
     domid = 'entityForm'
-    
+
     def __init__(self, *args, **kwargs):
         self.edited_entity = kwargs.pop('entity', None)
         msg = kwargs.pop('submitmsg', None)
@@ -445,7 +449,7 @@
                 self.form_add_hidden('__linkto', linkto)
                 msg = '%s %s' % (msg, self.req._('and linked'))
             self.form_add_hidden('__message', msg)
-    
+
     def _errex_match_field(self, errex, field):
         """return true if the field has some error in given validation exception
         """
@@ -480,7 +484,7 @@
             value = super(EntityFieldsForm, self).form_field_value(field,
                                                                    load_bytes)
         return value
-        
+
     def form_build_context(self, values=None):
         """overriden to add edit[s|o] hidden fields and to ensure schema fields
         have eidparam set to True
@@ -499,7 +503,7 @@
                     field.eidparam = True
                     self.fields.append(HiddenInitialValueField(field))
         return super(EntityFieldsForm, self).form_build_context(values)
-        
+
     def form_field_value(self, field, load_bytes=False):
         """return field's *typed* value
 
@@ -547,7 +551,7 @@
         else:
             value = self._form_field_default_value(field, load_bytes)
         return value
-        
+
     def form_field_format(self, field):
         """return MIME type used for the given (text or bytes) field"""
         entity = self.edited_entity
@@ -562,8 +566,8 @@
         if field.eidparam and entity.e_schema.has_metadata(field.name, 'encoding') and (
             entity.has_eid() or '%s_encoding' % field.name in entity):
             return self.edited_entity.attr_metadata(field.name, 'encoding')
-        return super(EntityFieldsForm, self).form_field_encoding(field)    
-    
+        return super(EntityFieldsForm, self).form_field_encoding(field)
+
     def form_field_name(self, field):
         """return qualified name for the given field"""
         if field.eidparam:
@@ -575,7 +579,7 @@
         if field.eidparam:
             return eid_param(field.id, self.edited_entity.eid)
         return field.id
-        
+
     def form_field_vocabulary(self, field, limit=None):
         """return vocabulary for the given field"""
         role, rtype = field.role, field.name
@@ -604,7 +608,7 @@
         """
         entity = self.edited_entity
         if isinstance(rtype, basestring):
-            rtype = entity.schema.rschema(rtype)
+            rtype = self.schema.rschema(rtype)
         done = None
         assert not rtype.is_final(), rtype
         if entity.has_eid():
@@ -626,7 +630,7 @@
         """
         entity = self.edited_entity
         if isinstance(rtype, basestring):
-            rtype = entity.schema.rschema(rtype)
+            rtype = self.schema.rschema(rtype)
         done = None
         if entity.has_eid():
             done = set(e.eid for e in getattr(entity, 'reverse_%s' % rtype))
@@ -641,7 +645,7 @@
                 break
         return result
 
-    def subject_in_state_vocabulary(self, rschema, limit=None):
+    def subject_in_state_vocabulary(self, rtype, limit=None):
         """vocabulary method for the in_state relation, looking for relation's
         object entities (i.e. self is the subject) according to initial_state,
         state_of and next_state relation
@@ -663,7 +667,7 @@
 
 class CompositeForm(FieldsForm):
     """form composed for sub-forms"""
-    
+
     def __init__(self, *args, **kwargs):
         super(CompositeForm, self).__init__(*args, **kwargs)
         self.forms = []
--- a/web/formfields.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/formfields.py	Fri Apr 24 19:46:47 2009 +0200
@@ -17,7 +17,7 @@
 from cubicweb.web import INTERNAL_FIELD_VALUE
 from cubicweb.web.formwidgets import (
     HiddenInput, TextInput, FileInput, PasswordInput, TextArea, FCKEditor,
-    Radio, Select, DateTimePicker) 
+    Radio, Select, DateTimePicker)
 
 class Field(object):
     """field class is introduced to control what's displayed in forms. It makes
@@ -28,7 +28,7 @@
     ----------
     all the attributes described below have sensible default value which may be
     overriden by value given to field's constructor.
-    
+
     :name:
        name of the field (basestring), should be unique in a form.
     :id:
@@ -60,7 +60,7 @@
     :role:
        when the field is linked to an entity attribute or relation, tells the
        role of the entity in the relation (eg 'subject' or 'object')
-    
+
     """
     # default widget associated to this class of fields. May be overriden per
     # instance
@@ -70,7 +70,7 @@
     # class attribute used for ordering of fields in a form
     __creation_rank = 0
 
-    def __init__(self, name=None, id=None, label=None, help=None, 
+    def __init__(self, name=None, id=None, label=None, help=None,
                  widget=None, required=False, initial=None,
                  choices=None, sort=True, internationalizable=False,
                  eidparam=False, role='subject'):
@@ -92,7 +92,7 @@
         # ordering number for this field instance
         self.creation_rank = Field.__creation_rank
         Field.__creation_rank += 1
-    
+
     def __unicode__(self):
         return u'<%s name=%r label=%r id=%r initial=%r @%x>' % (
             self.__class__.__name__, self.name, self.label,
@@ -109,17 +109,17 @@
             self.id = name
         if not self.label:
             self.label = name
-            
+
     def is_visible(self):
         """return true if the field is not an hidden field"""
         return not isinstance(self.widget, HiddenInput)
-    
+
     def actual_fields(self, form):
         """return actual fields composing this field in case of a compound
         field, usually simply return self
         """
         yield self
-    
+
     def format_value(self, req, value):
         """return value suitable for display where value may be a list or tuple
         of values
@@ -127,7 +127,7 @@
         if isinstance(value, (list, tuple)):
             return [self.format_single_value(req, val) for val in value]
         return self.format_single_value(req, value)
-    
+
     def format_single_value(self, req, value):
         """return value suitable for display"""
         if value is None or value is False:
@@ -139,11 +139,11 @@
     def get_widget(self, form):
         """return the widget instance associated to this field"""
         return self.widget
-    
+
     def example_format(self, req):
         """return a sample string describing what can be given as input for this
         field
-        """        
+        """
         return u''
 
     def render(self, form, renderer):
@@ -154,7 +154,7 @@
 
     def vocabulary(self, form):
         """return vocabulary for this field. This method will be called by
-        widgets which desire it."""        
+        widgets which desire it."""
         if self.choices is not None:
             if callable(self.choices):
                 vocab = self.choices(req=form.req)
@@ -169,13 +169,13 @@
         if self.sort:
             vocab = sorted(vocab)
         return vocab
-    
+
     def form_init(self, form):
         """method called before by form_build_context to trigger potential field
         initialization requiring the form instance
         """
         pass
-    
+
 class StringField(Field):
     def __init__(self, max_length=None, **kwargs):
         super(StringField, self).__init__(**kwargs)
@@ -227,13 +227,13 @@
                                 choices=choices)
             req.data[self] = field
             return field
-    
+
     def actual_fields(self, form):
         yield self
         format_field = self.get_format_field(form)
         if format_field:
             yield format_field
-            
+
     def use_fckeditor(self, form):
         """return True if fckeditor should be used to edit entity's attribute named
         `attr`, according to user preferences
@@ -250,16 +250,16 @@
             result = u''
         return result + self.get_widget(form).render(form, self)
 
-    
+
 class FileField(StringField):
     widget = FileInput
     needs_multipart = True
-    
+
     def __init__(self, format_field=None, encoding_field=None, **kwargs):
         super(FileField, self).__init__(**kwargs)
         self.format_field = format_field
         self.encoding_field = encoding_field
-        
+
     def actual_fields(self, form):
         yield self
         if self.format_field:
@@ -281,7 +281,7 @@
                 wdgs.append(self.render_subfield(form, self.format_field, renderer))
             if self.encoding_field:
                 wdgs.append(self.render_subfield(form, self.encoding_field, renderer))
-            wdgs.append(u'</div>')            
+            wdgs.append(u'</div>')
         if not self.required and form.context[self]['value']:
             # trick to be able to delete an uploaded file
             wdgs.append(u'<br/>')
@@ -296,10 +296,10 @@
                 + renderer.render_help(form, field)
                 + u'<br/>')
 
-        
+
 class EditableFileField(FileField):
     editable_formats = ('text/plain', 'text/html', 'text/rest')
-    
+
     def render(self, form, renderer):
         wdgs = [super(EditableFileField, self).render(form, renderer)]
         if form.form_field_format(self) in self.editable_formats:
@@ -326,7 +326,7 @@
                     # XXX restore form context?
         return '\n'.join(wdgs)
 
-        
+
 class IntField(Field):
     def __init__(self, min=None, max=None, **kwargs):
         super(IntField, self).__init__(**kwargs)
@@ -335,14 +335,14 @@
 
 class BooleanField(Field):
     widget = Radio
-        
+
     def vocabulary(self, form):
         if self.choices:
             return self.choices
         return [(form.req._('yes'), '1'), (form.req._('no'), '')]
 
 
-class FloatField(IntField):    
+class FloatField(IntField):
     def format_single_value(self, req, value):
         formatstr = req.property_value('ui.float-format')
         if value is None:
@@ -356,7 +356,7 @@
 class DateField(StringField):
     format_prop = 'ui.date-format'
     widget = DateTimePicker
-    
+
     def format_single_value(self, req, value):
         return value and ustrftime(value, req.property_value(self.format_prop)) or u''
 
@@ -378,8 +378,8 @@
         super(HiddenInitialValueField, self).__init__(
             name=name, widget=HiddenInput, eidparam=True)
         self.visible_field = visible_field
-    
-                 
+
+
 class RelationField(Field):
     def __init__(self, **kwargs):
         super(RelationField, self).__init__(**kwargs)
@@ -387,7 +387,7 @@
     @staticmethod
     def fromcardinality(card, **kwargs):
         return RelationField(widget=Select(multiple=card in '*+'), **kwargs)
-        
+
     def vocabulary(self, form):
         entity = form.edited_entity
         req = entity.req
@@ -407,7 +407,7 @@
         else:
             relatedvocab = []
         return res + form.form_field_vocabulary(self) + relatedvocab
-    
+
     def format_single_value(self, req, value):
         return value
 
@@ -436,12 +436,11 @@
     kwargs.setdefault('cols', cols)
 
 
-def guess_field(eclass, rschema, role='subject', skip_meta_attr=True, **kwargs):
+def guess_field(eschema, rschema, role='subject', skip_meta_attr=True, **kwargs):
     """return the most adapated widget to edit the relation
     'subjschema rschema objschema' according to information found in the schema
     """
     fieldclass = None
-    eschema = eclass.e_schema
     if role == 'subject':
         targetschema = rschema.objects(eschema)[0]
         card = rschema.rproperty(eschema, targetschema, 'cardinality')[0]
@@ -484,7 +483,7 @@
             for metadata in ('format', 'encoding'):
                 metaschema = eschema.has_metadata(rschema, metadata)
                 if metaschema is not None:
-                    kwargs['%s_field' % metadata] = guess_field(eclass, metaschema,
+                    kwargs['%s_field' % metadata] = guess_field(eschema, metaschema,
                                                                 skip_meta_attr=False)
         return fieldclass(**kwargs)
     kwargs['role'] = role
--- a/web/formrenderers.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/formrenderers.py	Fri Apr 24 19:46:47 2009 +0200
@@ -19,28 +19,38 @@
 
 class FormRenderer(object):
     """basic renderer displaying fields in a two columns table label | value
+
+    +--------------+--------------+
+    | field1 label | field1 input |
+    +--------------+--------------+
+    | field1 label | field2 input |
+    +--------------+--------------+
+    +---------+
+    | buttons |
+    +---------+
     """
+    _options = ('display_fields', 'display_label', 'display_help',
+                'display_progress_div', 'button_bar_class')
     display_fields = None # None -> all fields
     display_label = True
     display_help = True
     display_progress_div = True
     button_bar_class = u'formButtonBar'
-    
+
     def __init__(self, **kwargs):
         if self._set_options(kwargs):
             raise ValueError('unconsumed arguments %s' % kwargs)
 
     def _set_options(self, kwargs):
-        for key in ('display_fields', 'display_label', 'display_help',
-                    'display_progress_div', 'button_bar_class'):
+        for key in self._options:
             try:
                 setattr(self, key, kwargs.pop(key))
             except KeyError:
                 continue
         return kwargs
-    
+
     # renderer interface ######################################################
-    
+
     def render(self, form, values):
         self._set_options(values)
         form.add_media()
@@ -60,7 +70,7 @@
         w(u'</form>')
         errormsg = self.error_message(form)
         if errormsg:
-            data.insert(0, errormsg)          
+            data.insert(0, errormsg)
         return '\n'.join(data)
 
     def render_label(self, form, field):
@@ -98,7 +108,7 @@
                             if not field in displayed)
             if errors:
                 if len(errors) > 1:
-                    templstr = '<li>%s</li>\n' 
+                    templstr = '<li>%s</li>\n'
                 else:
                     templstr = '&nbsp;%s\n'
                 for field, err in errors:
@@ -110,7 +120,7 @@
                     errormsg = '<ul>%s</ul>' % errormsg
             return u'<div class="errorMessage">%s</div>' % errormsg
         return u''
-    
+
     def open_form(self, form, values):
         if form.form_needs_multipart:
             enctype = 'multipart/form-data'
@@ -133,21 +143,21 @@
         if form.cwtarget:
             tag += ' cubicweb:target="%s"' % html_escape(form.cwtarget)
         return tag + '>'
-    
+
     def display_field(self, form, field):
         return (self.display_fields is None
                 or field.name in self.display_fields
                 or field.name in form.internal_fields)
-    
+
     def render_fields(self, w, form, values):
         form.form_build_context(values)
         fields = self._render_hidden_fields(w, form)
         if fields:
-            self._render_fields(fields, w, form, values)
+            self._render_fields(fields, w, form)
         self.render_child_forms(w, form, values)
-        
+
     def render_child_forms(self, w, form, values):
-        # render 
+        # render
         for childform in getattr(form, 'forms', []):
             self.render_fields(w, childform, values)
 
@@ -160,19 +170,19 @@
                 w(field.render(form, self))
                 fields.remove(field)
         return fields
-    
-    def _render_fields(self, fields, w, form, values):
-        w(u'<table class="attributeForm" style="width:100%;">')
+
+    def _render_fields(self, fields, w, form):
+        w(u'<table class="attributeForm">')
         for field in fields:
             w(u'<tr>')
             if self.display_label:
                 w(u'<th class="labelCol">%s</th>' % self.render_label(form, field))
             error = form.form_field_error(field)
             if error:
-                w(u'<td class="error" style="width:100%;">')
+                w(u'<td class="error">')
                 w(error)
             else:
-                w(u'<td style="width:100%;">')
+                w(u'<td>')
             w(field.render(form, self))
             if self.display_help:
                 w(self.render_help(form, field))
@@ -186,20 +196,62 @@
         w(u'</tr></table>')
 
 
-    
+class HTableFormRenderer(FormRenderer):
+    """display fields horizontally in a table
+
+    +--------------+--------------+---------+
+    | field1 label | field2 label |         |
+    +--------------+--------------+---------+
+    | field1 input | field2 input | buttons
+    +--------------+--------------+---------+
+    """
+    display_help = False
+    def _render_fields(self, fields, w, form):
+        w(u'<table border="0">')
+        w(u'<tr>')
+        for field in fields:
+            if self.display_label:
+                w(u'<th class="labelCol">%s</th>' % self.render_label(form, field))
+            if self.display_help:
+                w(self.render_help(form, field))
+        # empty slot for buttons
+        w(u'<th class="labelCol">&nbsp;</th>')
+        w(u'</tr>')
+        w(u'<tr>')
+        for field in fields:
+            error = form.form_field_error(field)
+            if error:
+                w(u'<td class="error" style="width:100%;">')
+                w(error)
+            else:
+                w(u'<td style="width:100%;">')
+            w(field.render(form, self))
+            w(u'</td>')
+        w(u'<td>')
+        for button in form.form_buttons:
+            w(button.render(form))
+        w(u'</td>')
+        w(u'</tr>')
+        w(u'</table>')
+
+    def render_buttons(self, w, form):
+        pass
+
+
 class EntityCompositeFormRenderer(FormRenderer):
     """specific renderer for multiple entities edition form (muledit)"""
+
     def render_fields(self, w, form, values):
         if not form.is_subform:
             w(u'<table class="listing">')
         super(EntityCompositeFormRenderer, self).render_fields(w, form, values)
         if not form.is_subform:
             w(u'</table>')
-        
-    def _render_fields(self, fields, w, form, values):
+
+    def _render_fields(self, fields, w, form):
         if form.is_subform:
             entity = form.edited_entity
-            values = form.req.data.get('formvalues', ())
+            values = form._previous_values
             qeid = eid_param('eid', entity.eid)
             cbsetstate = "setCheckboxesState2('eid', %s, 'checked')" % html_escape(dumps(entity.eid))
             w(u'<tr class="%s">' % (entity.row % 2 and u'even' or u'odd'))
@@ -228,16 +280,18 @@
                 if self.display_field(form, field) and field.is_visible():
                     w(u'<th>%s</th>' % form.req._(field.label))
         w(u'</tr>')
-            
+
 
-            
+
 class EntityFormRenderer(FormRenderer):
     """specific renderer for entity edition form (edition)"""
-        
+    _options = FormRenderer._options + ('display_relations_form',)
+    display_relations_form = True
+
     def render(self, form, values):
         rendered = super(EntityFormRenderer, self).render(form, values)
         return rendered + u'</div>' # close extra div introducted by open_form
-        
+
     def open_form(self, form, values):
         attrs_fs_label = ('<div class="iformTitle"><span>%s</span></div>'
                           % form.req._('main informations'))
@@ -247,13 +301,13 @@
     def render_fields(self, w, form, values):
         super(EntityFormRenderer, self).render_fields(w, form, values)
         self.inline_entities_form(w, form)
-        if form.edited_entity.has_eid():
+        if form.edited_entity.has_eid() and self.display_relations_form:
             self.relations_form(w, form)
 
-    def _render_fields(self, fields, w, form, values):
+    def _render_fields(self, fields, w, form):
         if not form.edited_entity.has_eid() or form.edited_entity.has_perm('update'):
-            super(EntityFormRenderer, self)._render_fields(fields, w, form, values)
-            
+            super(EntityFormRenderer, self)._render_fields(fields, w, form)
+
     def render_buttons(self, w, form):
         if len(form.form_buttons) == 3:
             w("""<table width="100%%">
@@ -268,7 +322,7 @@
  </table>""" % tuple(button.render(form) for button in form.form_buttons))
         else:
             super(EntityFormRenderer, self).render_buttons(w, form)
-        
+
     def relations_form(self, w, form):
         srels_by_cat = form.srelations_by_category(('generic', 'metadata'), 'add')
         if not srels_by_cat:
@@ -290,7 +344,7 @@
                     w(u'<li class="invisible">%s<div id="span%s" class="%s">%s</div></li>'
                       % (viewparams[1], viewparams[0], viewparams[2], viewparams[3]))
                 if not form.force_display and form.maxrelitems < len(related):
-                    link = (u'<span class="invisible">' 
+                    link = (u'<span class="invisible">'
                             '[<a href="javascript: window.location.href+=\'&amp;__force_display=1\'">%s</a>]'
                             '</span>' % form.req._('view all'))
                     w(u'<li class="invisible">%s</li>' % link)
@@ -328,7 +382,7 @@
         w(u'</tr>')
         w(u'</table>')
         w(u'</fieldset>')
-        
+
     def inline_entities_form(self, w, form):
         """create a form to edit entity's inlined relations"""
         entity = form.edited_entity
@@ -347,7 +401,7 @@
                 existant = entity.has_eid() and entity.related(rschema)
                 if existant:
                     # display inline-edition view for all existing related entities
-                    w(form.view('inline-edition', existant, rtype=rschema, role=role, 
+                    w(form.view('inline-edition', existant, rtype=rschema, role=role,
                                 ptype=entity.e_schema, peid=entity.eid))
                 if role == 'subject':
                     card = rschema.rproperty(entity.e_schema, targettype, 'cardinality')[0]
@@ -375,7 +429,7 @@
                     w(u'<div class="trame_grise">&nbsp;</div>')
                 w(u'</div>')
 
-    
+
 class EntityInlinedFormRenderer(EntityFormRenderer):
     """specific renderer for entity inlined edition form
     (inline-[creation|edition])
@@ -400,7 +454,7 @@
         self.render_fields(w, form, values)
         w(u'</div></div>')
         return '\n'.join(data)
-    
+
     def render_fields(self, w, form, values):
         form.form_build_context(values)
         w(u'<fieldset id="fs-%(divid)s">' % values)
@@ -408,8 +462,8 @@
         w(u'</fieldset>')
         w(u'<fieldset class="subentity">')
         if fields:
-            self._render_fields(fields, w, form, values)
+            self._render_fields(fields, w, form)
         self.render_child_forms(w, form, values)
         self.inline_entities_form(w, form)
         w(u'</fieldset>')
-    
+
--- a/web/formwidgets.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/formwidgets.py	Fri Apr 24 19:46:47 2009 +0200
@@ -20,7 +20,7 @@
     # automatically set id and tabindex attributes ?
     setdomid = True
     settabindex = True
-    
+
     def __init__(self, attrs=None, setdomid=None, settabindex=None):
         if attrs is None:
             attrs = {}
@@ -38,7 +38,7 @@
             form.req.add_js(self.needs_js)
         if self.needs_css:
             form.req.add_css(self.needs_css)
-        
+
     def render(self, form, field):
         """render the widget for the given `field` of `form`.
         To override in concrete class
@@ -63,10 +63,10 @@
 class Input(FieldWidget):
     """abstract widget class for <input> tag based widgets"""
     type = None
-    
+
     def render(self, form, field):
         """render the widget for the given `field` of `form`.
-        
+
         Generate one <input> tag for each field's value
         """
         self.add_media(form)
@@ -88,7 +88,7 @@
     <field's name>-confirm as name)
     """
     type = 'password'
-    
+
     def render(self, form, field):
         self.add_media(form)
         name, values, attrs = self._render_attrs(form, field)
@@ -109,20 +109,20 @@
 class FileInput(Input):
     """<input type='file'>"""
     type = 'file'
-    
+
     def _render_attrs(self, form, field):
         # ignore value which makes no sense here (XXX even on form validation error?)
         name, values, attrs = super(FileInput, self)._render_attrs(form, field)
         return name, ('',), attrs
 
-        
+
 class HiddenInput(Input):
     """<input type='hidden'>"""
     type = 'hidden'
     setdomid = False # by default, don't set id attribute on hidden input
     settabindex = False
 
-    
+
 class ButtonInput(Input):
     """<input type='button'>
 
@@ -151,20 +151,22 @@
     def __init__(self, *args, **kwargs):
         super(FCKEditor, self).__init__(*args, **kwargs)
         self.attrs['cubicweb:type'] = 'wysiwyg'
-    
+
     def render(self, form, field):
         form.req.fckeditor_config()
         return super(FCKEditor, self).render(form, field)
 
 
 class Select(FieldWidget):
-    """<select>, for field having a specific vocabulary""" 
+    """<select>, for field having a specific vocabulary"""
     def __init__(self, attrs=None, multiple=False):
         super(Select, self).__init__(attrs)
         self.multiple = multiple
-        
+
     def render(self, form, field):
         name, curvalues, attrs = self._render_attrs(form, field)
+        if not 'size' in attrs:
+            attrs['size'] = '5'
         options = []
         for label, value in field.vocabulary(form):
             if value is None:
@@ -181,9 +183,9 @@
 class CheckBox(Input):
     """<input type='checkbox'>, for field having a specific vocabulary. One
     input will be generated for each possible value.
-    """ 
+    """
     type = 'checkbox'
-    
+
     def render(self, form, field):
         name, curvalues, attrs = self._render_attrs(form, field)
         options = []
@@ -197,13 +199,13 @@
             options.append(tag + label)
         return '<br/>\n'.join(options)
 
-        
+
 class Radio(Input):
     """<input type='radio'>, for field having a specific vocabulary. One
     input will be generated for each possible value.
-    """ 
+    """
     type = 'radio'
-    
+
     def render(self, form, field):
         name, curvalues, attrs = self._render_attrs(form, field)
         domid = attrs.pop('id', None)
@@ -233,7 +235,7 @@
 
     needs_js = ('cubicweb.calendar.js',)
     needs_css = ('cubicweb.calendar_popup.css',)
-    
+
     @classmethod
     def add_localized_infos(cls, req):
         """inserts JS variables defining localized months and days"""
@@ -243,13 +245,13 @@
         daynames = [_(dname) for dname in cls.daynames]
         req.html_headers.define_var('MONTHNAMES', monthnames)
         req.html_headers.define_var('DAYNAMES', daynames)
-    
+
     def render(self, form, field):
         txtwidget = super(DateTimePicker, self).render(form, field)
         self.add_localized_infos(form.req)
         cal_button = self._render_calendar_popup(form, field)
         return txtwidget + cal_button
-    
+
     def _render_calendar_popup(self, form, field):
         value = form.form_field_value(field)
         if not value:
@@ -263,7 +265,7 @@
                    form.req.external_resource('CALENDAR_ICON'),
                    form.req._('calendar'), helperid) )
 
-        
+
 
 # ajax widgets ################################################################
 
@@ -283,13 +285,13 @@
         init_ajax_attributes(self.attrs, wdgtype)
         if inputid is not None:
             self.attrs['cubicweb:inputid'] = inputid
-            
+
     def render(self, form, field):
         self.add_media(form)
         attrs = self._render_attrs(form, field)[-1]
         return tags.div(**attrs)
 
-    
+
 class AutoCompletionWidget(TextInput):
     """ajax widget for StringField, proposing matching existing values as you
     type.
@@ -298,7 +300,7 @@
     needs_css = ('jquery.autocomplete.css',)
     wdgtype = 'SuggestField'
     loadtype = 'auto'
-    
+
     def _render_attrs(self, form, field):
         name, values, attrs = super(AutoCompletionWidget, self)._render_attrs(form, field)
         if not values[0]:
@@ -307,7 +309,7 @@
         # XXX entity form specific
         attrs['cubicweb:dataurl'] = self._get_url(form.edited_entity)
         return name, values, attrs
-    
+
     def _get_url(self, entity):
         return entity.req.build_url('json', fname=entity.autocomplete_initfuncs[self.rschema],
                                 pageid=entity.req.pageid, mode='remote')
@@ -316,14 +318,14 @@
 class StaticFileAutoCompletionWidget(AutoCompletionWidget):
     """XXX describe me"""
     wdgtype = 'StaticFileSuggestField'
-    
+
     def _get_url(self, entity):
         return entity.req.datadir_url + entity.autocomplete_initfuncs[self.rschema]
 
 
 class RestrictedAutoCompletionWidget(AutoCompletionWidget):
     """XXX describe me"""
-    wdgtype = 'RestrictedSuggestField'    
+    wdgtype = 'RestrictedSuggestField'
 
 
 class AddComboBoxWidget(Select):
@@ -335,7 +337,7 @@
         attrs['cubicweb:etype_to'] = entity.e_schema
         etype_from = entity.e_schema.subject_relation(self.name).objects(entity.e_schema)[0]
         attrs['cubicweb:etype_from'] = etype_from
-        
+
     def render(self, form, field):
         return super(AddComboBoxWidget, self).render(form, field) + u'''
 <div id="newvalue">
@@ -362,7 +364,7 @@
         self.onclick = onclick
         self.cwaction = cwaction
         self.attrs.setdefault('klass', 'validateButton')
-                
+
     def render(self, form, field=None):
         label = form.req._(self.label)
         attrs = self.attrs.copy()
@@ -380,12 +382,12 @@
             attrs['tabindex'] = form.req.next_tabindex()
         return tags.input(value=label, type=self.type, **attrs)
 
-    
+
 class SubmitButton(Button):
     """<input type='submit'>, main button to submit a form"""
     type = 'submit'
 
-    
+
 class ResetButton(Button):
     """<input type='reset'>, main button to reset a form.
     You usually don't want this.
@@ -405,7 +407,7 @@
         self.href = href
         self.imgressource = imgressource
         self.label = label
-        
+
     def render(self, form, field=None):
         label = form.req._(self.label)
         imgsrc = form.req.external_resource(self.imgressource)
@@ -413,7 +415,7 @@
                '<img src="%(imgsrc)s" alt="%(label)s"/>%(label)s</a>' % {
             'label': label, 'imgsrc': imgsrc,
             'domid': self.domid, 'href': self.href}
-            
+
 
-    
+
 # XXX EntityLinkComboBoxWidget, [Raw]DynamicComboBoxWidget
--- a/web/request.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/request.py	Fri Apr 24 19:46:47 2009 +0200
@@ -56,8 +56,8 @@
 
 
 class CubicWebRequestBase(DBAPIRequest):
-    """abstract HTTP request, should be extended according to the HTTP backend"""    
-    
+    """abstract HTTP request, should be extended according to the HTTP backend"""
+
     def __init__(self, vreg, https, form=None):
         super(CubicWebRequestBase, self).__init__(vreg)
         self.message = None
@@ -73,7 +73,7 @@
         self.data = {}
         # search state: 'normal' or 'linksearch' (eg searching for an object
         # to create a relation with another)
-        self.search_state = ('normal',) 
+        self.search_state = ('normal',)
         # tabindex generator
         self.tabindexgen = count()
         self.next_tabindex = self.tabindexgen.next
@@ -106,27 +106,27 @@
                     return
         # 3. default language
         self.set_default_language(vreg)
-            
+
     def set_language(self, lang):
         self._ = self.__ = self.translations[lang]
         self.lang = lang
         self.debug('request language: %s', lang)
-        
+
     # input form parameters management ########################################
-    
+
     # common form parameters which should be protected against html values
     # XXX can't add 'eid' for instance since it may be multivalued
     # dont put rql as well, if query contains < and > it will be corrupted!
-    no_script_form_params = set(('vid', 
-                                 'etype', 
+    no_script_form_params = set(('vid',
+                                 'etype',
                                  'vtitle', 'title',
                                  '__message',
                                  '__redirectvid', '__redirectrql'))
-        
+
     def setup_params(self, params):
         """WARNING: we're intentionaly leaving INTERNAL_FIELD_VALUE here
 
-        subclasses should overrides to 
+        subclasses should overrides to
         """
         if params is None:
             params = {}
@@ -146,7 +146,7 @@
                 del self.form[k]
             else:
                 self.form[k] = v
-    
+
     def no_script_form_param(self, param, default=None, value=None):
         """ensure there is no script in a user form param
 
@@ -167,11 +167,11 @@
                 value = value[0]
             return remove_html_tags(value)
         return value
-        
+
     def list_form_param(self, param, form=None, pop=False):
         """get param from form parameters and return its value as a list,
         skipping internal markers if any
-        
+
         * if the parameter isn't defined, return an empty list
         * if the parameter is a single (unicode) value, return a list
           containing that value
@@ -182,8 +182,8 @@
         """
         if form is None:
             form = self.form
-        return list_form_param(form, param, pop)            
-    
+        return list_form_param(form, param, pop)
+
 
     def reset_headers(self):
         """used by AutomaticWebTest to clear html headers between tests on
@@ -193,11 +193,11 @@
         return self
 
     # web state helpers #######################################################
-    
+
     def set_message(self, msg):
         assert isinstance(msg, unicode)
         self.message = msg
-    
+
     def update_search_state(self):
         """update the current search state"""
         searchstate = self.form.get('__mode')
@@ -247,7 +247,7 @@
     def register_onetime_callback(self, func, *args):
         cbname = 'cb_%s' % (
             sha.sha('%s%s%s%s' % (time.time(), func.__name__,
-                                  random.random(), 
+                                  random.random(),
                                   self.user.login)).hexdigest())
         def _cb(req):
             try:
@@ -255,12 +255,12 @@
             except TypeError:
                 from warnings import warn
                 warn('user callback should now take request as argument')
-                ret = func(*args)            
+                ret = func(*args)
             self.unregister_callback(self.pageid, cbname)
             return ret
         self.set_page_data(cbname, _cb)
         return cbname
-    
+
     def unregister_callback(self, pageid, cbname):
         assert pageid is not None
         assert cbname.startswith('cb_')
@@ -273,9 +273,9 @@
             callbacks = [key for key in sessdata if key.startswith('cb_')]
             for callback in callbacks:
                 self.del_session_data(callback)
-    
+
     # web edition helpers #####################################################
-    
+
     @cached # so it's writed only once
     def fckeditor_config(self):
         self.add_js('fckeditor/fckeditor.js')
@@ -330,7 +330,7 @@
             print eid, params
             raise RequestError(self._('missing parameters for entity %s') % eid)
         return params
-    
+
     def get_pending_operations(self, entity, relname, role):
         operations = {'insert' : [], 'delete' : []}
         for optype in ('insert', 'delete'):
@@ -342,7 +342,7 @@
                     if role == 'object' and entity.eid == eidto:
                         operations[optype].append(eidfrom)
         return operations
-    
+
     def get_pending_inserts(self, eid=None):
         """shortcut to access req's pending_insert entry
 
@@ -377,7 +377,7 @@
         """
         self.del_session_data(errorurl)
         self.remove_pending_operations()
-    
+
     # high level methods for HTTP headers management ##########################
 
     # must be cached since login/password are popped from the form dictionary
@@ -395,7 +395,7 @@
                 return None, None
         else:
             return self.header_authorization()
-    
+
     def get_cookie(self):
         """retrieve request cookies, returns an empty cookie if not found"""
         try:
@@ -423,7 +423,7 @@
         morsel['Max-Age'] = 0
         # The only way to set up cookie age for IE is to use an old "expired"
         # syntax. IE doesn't support Max-Age there is no library support for
-        # managing 
+        # managing
         # ===> Do _NOT_ comment this line :
         morsel['expires'] = 'Thu, 01-Jan-1970 00:00:00 GMT'
         self.add_header('Set-Cookie', morsel.OutputString())
@@ -476,9 +476,9 @@
             if localfile:
                 cssfile = self.datadir_url + cssfile
             add_css(cssfile, media)
-    
+
     # urls/path management ####################################################
-    
+
     def url(self, includeparams=True):
         """return currently accessed url"""
         return self.base_url() + self.relative_path(includeparams)
@@ -486,7 +486,7 @@
     def _datadir_url(self):
         """return url of the application's data directory"""
         return self.base_url() + 'data%s/' % self.vreg.config.instance_md5_version()
-    
+
     def selected(self, url):
         """return True if the url is equivalent to currently accessed url"""
         reqpath = self.relative_path().lower()
@@ -502,7 +502,7 @@
     def base_url_path(self):
         """returns the absolute path of the base url"""
         return urlsplit(self.base_url())[2]
-        
+
     @cached
     def from_controller(self):
         """return the id (string) of the controller issuing the request"""
@@ -512,7 +512,7 @@
         if controller in registered_controllers:
             return controller
         return 'view'
-    
+
     def external_resource(self, rid, default=_MARKER):
         """return a path to an external resource, using its identifier
 
@@ -541,9 +541,9 @@
         self._validate_cache()
         if self.http_method() == 'HEAD':
             raise StatusResponse(200, '')
-        
+
     # abstract methods to override according to the web front-end #############
-        
+
     def http_method(self):
         """returns 'POST', 'GET', 'HEAD', etc."""
         raise NotImplementedError()
@@ -553,7 +553,7 @@
         exists and is still usable
         """
         raise NotImplementedError()
-        
+
     def relative_path(self, includeparams=True):
         """return the normalized path of the request (ie at least relative
         to the application's root, but some other normalization may be needed
@@ -577,11 +577,11 @@
     def add_header(self, header, value):
         """add an output HTTP header"""
         raise NotImplementedError()
-    
+
     def remove_header(self, header):
         """remove an output HTTP header"""
         raise NotImplementedError()
-        
+
     def header_authorization(self):
         """returns a couple (auth-type, auth-value)"""
         auth = self.get_header("Authorization", None)
@@ -619,21 +619,21 @@
         mx date time value (GMT), else return None
         """
         raise NotImplementedError()
-    
+
     # page data management ####################################################
 
     def get_page_data(self, key, default=None):
         """return value associated to `key` in curernt page data"""
         page_data = self.cnx.get_session_data(self.pageid, {})
         return page_data.get(key, default)
-        
+
     def set_page_data(self, key, value):
         """set value associated to `key` in current page data"""
         self.html_headers.add_unload_pagedata()
         page_data = self.cnx.get_session_data(self.pageid, {})
         page_data[key] = value
         return self.cnx.set_session_data(self.pageid, page_data)
-        
+
     def del_page_data(self, key=None):
         """remove value associated to `key` in current page data
         if `key` is None, all page data will be cleared
@@ -654,16 +654,21 @@
     def ie_browser(self):
         useragent = self.useragent()
         return useragent and 'MSIE' in useragent
-    
+
     def xhtml_browser(self):
         useragent = self.useragent()
-        # MSIE does not support xml content-type
-        # quick fix: Opera supports xhtml and handles namespaces
-        # properly but it breaks jQuery.attr()
+        # * MSIE/Konqueror does not support xml content-type
+        # * Opera supports xhtml and handles namespaces properly but it breaks
+        #   jQuery.attr()
         if useragent and ('MSIE' in useragent or 'KHTML' in useragent
                           or 'Opera' in useragent):
             return False
         return True
 
+    def html_content_type(self):
+        if self.xhtml_browser():
+            return 'application/xhtml+xml'
+        return 'text/html'
+
 from cubicweb import set_log_methods
 set_log_methods(CubicWebRequestBase, LOGGER)
--- a/web/test/data/schema/relations.rel	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/data/schema/relations.rel	Fri Apr 24 19:46:47 2009 +0200
@@ -1,2 +1,2 @@
 Personne travaille Societe
-EUser connait Personne
+CWUser connait Personne
--- a/web/test/data/schema/testschema.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/data/schema/testschema.py	Fri Apr 24 19:46:47 2009 +0200
@@ -4,11 +4,11 @@
     
 class tags(RelationDefinition):
     subject = 'Tag'
-    object = ('BlogEntry', 'EUser')
+    object = ('BlogEntry', 'CWUser')
 
 class checked_by(RelationType):
     subject = 'BlogEntry'
-    object = 'EUser'
+    object = 'CWUser'
     cardinality = '?*'
     permissions = {
         'add': ('managers',),
--- a/web/test/test_views.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/test_views.py	Fri Apr 24 19:46:47 2009 +0200
@@ -4,9 +4,9 @@
 from cubicweb.view import AnyRsetView
 
 AutomaticWebTest.application_rql = [
-    'Any L,F WHERE E is EUser, E login L, E firstname F',
-    'Any L,F,E WHERE E is EUser, E login L, E firstname F',
-    'Any COUNT(X) WHERE X is EUser',
+    'Any L,F WHERE E is CWUser, E login L, E firstname F',
+    'Any L,F,E WHERE E is CWUser, E login L, E firstname F',
+    'Any COUNT(X) WHERE X is CWUser',
     ]
 
 class ComposityCopy(WebTest):
@@ -15,7 +15,7 @@
         """regression test: make sure we can ask a copy of a
         composite entity
         """
-        rset = self.execute('EUser X WHERE X login "admin"')
+        rset = self.execute('CWUser X WHERE X login "admin"')
         self.view('copy', rset)
 
 
@@ -33,21 +33,21 @@
         self.auto_populate(10)
 
     def test_manual_tests(self):
-        rset = self.execute('Any P,F,S WHERE P is EUser, P firstname F, P surname S')
+        rset = self.execute('Any P,F,S WHERE P is CWUser, P firstname F, P surname S')
         self.view('table', rset, template=None, displayfilter=True, displaycols=[0,2])        
 
     def test_sortable_js_added(self):
-        rset = self.execute('EUser X')
+        rset = self.execute('CWUser X')
         # sortable.js should not be included by default
         self.failIf('jquery.tablesorter.js' in self.view('oneline', rset))
         # but should be included by the tableview
-        rset = self.execute('Any P,F,S LIMIT 1 WHERE P is EUser, P firstname F, P surname S')
+        rset = self.execute('Any P,F,S LIMIT 1 WHERE P is CWUser, P firstname F, P surname S')
         self.failUnless('jquery.tablesorter.js' in self.view('table', rset))
 
     def test_js_added_only_once(self):
         self.vreg._loadedmods[__name__] = {}
         self.vreg.register_vobject_class(SomeView)
-        rset = self.execute('EUser X')
+        rset = self.execute('CWUser X')
         source = self.view('someview', rset).source
         self.assertEquals(source.count('spam.js'), 1)
 
@@ -56,8 +56,8 @@
 class ExplicitViewsTest(WebTest):
     
     def test_unrelateddivs(self):
-        rset = self.execute('Any X WHERE X is EUser, X login "admin"')
-        group = self.add_entity('EGroup', name=u'R&D')
+        rset = self.execute('Any X WHERE X is CWUser, X login "admin"')
+        group = self.add_entity('CWGroup', name=u'R&D')
         req = self.request(relation='in_group_subject')
         self.view('unrelateddivs', rset, req)
         
--- a/web/test/unittest_application.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_application.py	Fri Apr 24 19:46:47 2009 +0200
@@ -170,7 +170,7 @@
         self.commit()
     
     def test_nonregr_publish1(self):
-        req = self.request(u'EEType X WHERE X final FALSE, X meta FALSE')
+        req = self.request(u'CWEType X WHERE X final FALSE, X meta FALSE')
         self.app.publish('view', req)
         
     def test_nonregr_publish2(self):
@@ -183,7 +183,7 @@
         user = self.user()
         req.form = {
             'eid':       `user.eid`,
-            '__type:'+`user.eid`:    'EUser',
+            '__type:'+`user.eid`:    'CWUser',
             'login:'+`user.eid`:     '', # ERROR: no login specified
             'edits-login:'+`user.eid`: unicode(user.login),
              # just a sample, missing some necessary information for real life
@@ -207,7 +207,7 @@
         """        
         req = self.request()
         form = {'eid': ['X', 'Y'],
-                '__type:X': 'EUser',
+                '__type:X': 'CWUser',
                 # missing required field
                 'login:X': u'', 'edits-login:X': '', 
                 'surname:X': u'Mr Ouaoua', 'edits-surname:X': '',
@@ -253,7 +253,7 @@
         vreg = self.app.vreg
         # default value
         self.assertEquals(vreg.property_value('ui.language'), 'en')
-        self.execute('INSERT EProperty X: X value "fr", X pkey "ui.language"')
+        self.execute('INSERT CWProperty X: X value "fr", X pkey "ui.language"')
         self.assertEquals(vreg.property_value('ui.language'), 'en')
         self.commit()
         self.assertEquals(vreg.property_value('ui.language'), 'fr')
@@ -261,7 +261,7 @@
         self.assertEquals(vreg.property_value('ui.language'), 'fr')
         self.commit()
         self.assertEquals(vreg.property_value('ui.language'), 'de')
-        self.execute('DELETE EProperty X WHERE X pkey "ui.language"')
+        self.execute('DELETE CWProperty X WHERE X pkey "ui.language"')
         self.assertEquals(vreg.property_value('ui.language'), 'de')
         self.commit()
         self.assertEquals(vreg.property_value('ui.language'), 'en')
--- a/web/test/unittest_form.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_form.py	Fri Apr 24 19:46:47 2009 +0200
@@ -14,7 +14,7 @@
     def test_form_field_format(self):
         form = FieldsForm(self.request(), None)
         self.assertEquals(form.form_field_format(None), 'text/html')
-        self.execute('INSERT EProperty X: X pkey "ui.default-text-format", X value "text/rest", X for_user U WHERE U login "admin"')
+        self.execute('INSERT CWProperty X: X pkey "ui.default-text-format", X value "text/rest", X for_user U WHERE U login "admin"')
         self.commit()
         self.assertEquals(form.form_field_format(None), 'text/rest')
 
@@ -43,7 +43,7 @@
         self.failIf(t.eid in unrelated, unrelated)
         
     def test_form_field_vocabulary_new_entity(self):
-        e = self.etype_instance('EUser')
+        e = self.etype_instance('CWUser')
         form = EntityFieldsForm(self.request(), None, entity=e)
         unrelated = [rview for rview, reid in form.subject_relation_vocabulary('in_group')]
         # should be default groups but owners, i.e. managers, users, guests
@@ -51,7 +51,7 @@
 
     def test_subject_in_state_vocabulary(self):
         # on a new entity
-        e = self.etype_instance('EUser')
+        e = self.etype_instance('CWUser')
         form = EntityFieldsForm(self.request(), None, entity=e)
         states = list(form.subject_in_state_vocabulary('in_state'))
         self.assertEquals(len(states), 1)
@@ -69,8 +69,8 @@
         
     def test_massmailing_formview(self):
         self.execute('INSERT EmailAddress X: X address L + "@cubicweb.org", '
-                     'U use_email X WHERE U is EUser, U login L')
-        rset = self.execute('EUser X')
+                     'U use_email X WHERE U is CWUser, U login L')
+        rset = self.execute('CWUser X')
         self.view('massmailing', rset, template=None)
         
 
--- a/web/test/unittest_formfields.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_formfields.py	Fri Apr 24 19:46:47 2009 +0200
@@ -5,82 +5,79 @@
 from cubicweb.web.formwidgets import PasswordInput
 from cubicweb.web.formfields import *
 from cubicweb.entities.lib import Card
-from cubicweb.entities.authobjs import EUser
+from cubicweb.entities.authobjs import CWUser
 from cubes.file.entities import File
 
 config = TestServerConfiguration('data')
 config.bootstrap_cubes()
 schema = config.load_schema()
-Card.schema = schema
-Card.__initialize__()
-EUser.schema = schema
-EUser.__initialize__()
-File.schema = schema
-File.__initialize__()
-        
+card_schema = schema['Card']
+cwuser_schema = schema['CWUser']
+file_schema.schema = schema['File']
+
 class GuessFieldTC(TestCase):
-    
+
     def test_card_fields(self):
-        title_field = guess_field(Card, schema['title'])
+        title_field = guess_field(card_schema, schema['title'])
         self.assertIsInstance(title_field, StringField)
         self.assertEquals(title_field.required, True)
-        
-        synopsis_field = guess_field(Card, schema['synopsis'])
+
+        synopsis_field = guess_field(card_schema, schema['synopsis'])
         self.assertIsInstance(synopsis_field, TextField)
         self.assertEquals(synopsis_field.required, False)
         self.assertEquals(synopsis_field.help, 'an abstract for this card')
-        
-        content_field = guess_field(Card, schema['content'])
+
+        content_field = guess_field(card_schema, schema['content'])
         self.assertIsInstance(content_field, RichTextField)
         self.assertEquals(content_field.required, False)
         self.assertEquals(content_field.format_field, None)
-                          
-        content_format_field = guess_field(Card, schema['content_format'])
+
+        content_format_field = guess_field(card_schema, schema['content_format'])
         self.assertEquals(content_format_field, None)
-        
-        content_format_field = guess_field(Card, schema['content_format'], skip_meta_attr=False)
+
+        content_format_field = guess_field(card_schema, schema['content_format'], skip_meta_attr=False)
         self.assertEquals(content_format_field.internationalizable, True)
         self.assertEquals(content_format_field.sort, True)
         self.assertEquals(content_format_field.initial, 'text/rest')
 
-        wikiid_field = guess_field(Card, schema['wikiid'])
+        wikiid_field = guess_field(card_schema, schema['wikiid'])
         self.assertIsInstance(wikiid_field, StringField)
         self.assertEquals(wikiid_field.required, False)
 
-        
+
     def test_euser_fields(self):
-        upassword_field = guess_field(EUser, schema['upassword'])
+        upassword_field = guess_field(cwuser_schema, schema['upassword'])
         self.assertIsInstance(upassword_field, StringField)
         self.assertIsInstance(upassword_field.widget, PasswordInput)
         self.assertEquals(upassword_field.required, True)
 
-        last_login_time_field = guess_field(EUser, schema['last_login_time'])
+        last_login_time_field = guess_field(cwuser_schema, schema['last_login_time'])
         self.assertIsInstance(last_login_time_field, DateTimeField)
         self.assertEquals(last_login_time_field.required, False)
 
-        in_group_field = guess_field(EUser, schema['in_group'])
+        in_group_field = guess_field(cwuser_schema, schema['in_group'])
         self.assertIsInstance(in_group_field, RelationField)
         self.assertEquals(in_group_field.required, True)
         self.assertEquals(in_group_field.role, 'subject')
         self.assertEquals(in_group_field.help, 'groups grant permissions to the user')
 
-        owned_by_field = guess_field(EUser, schema['owned_by'], 'object')
+        owned_by_field = guess_field(cwuser_schema, schema['owned_by'], 'object')
         self.assertIsInstance(owned_by_field, RelationField)
         self.assertEquals(owned_by_field.required, False)
         self.assertEquals(owned_by_field.role, 'object')
 
 
     def test_file_fields(self):
-        data_format_field = guess_field(File, schema['data_format'])
+        data_format_field = guess_field(file_schema, schema['data_format'])
         self.assertEquals(data_format_field, None)
-        data_encoding_field = guess_field(File, schema['data_encoding'])
+        data_encoding_field = guess_field(file_schema, schema['data_encoding'])
         self.assertEquals(data_encoding_field, None)
 
-        data_field = guess_field(File, schema['data'])
+        data_field = guess_field(file_schema, schema['data'])
         self.assertIsInstance(data_field, FileField)
         self.assertEquals(data_field.required, True)
         self.assertIsInstance(data_field.format_field, StringField)
         self.assertIsInstance(data_field.encoding_field, StringField)
-        
+
 if __name__ == '__main__':
     unittest_main()
--- a/web/test/unittest_magicsearch.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_magicsearch.py	Fri Apr 24 19:46:47 2009 +0200
@@ -11,7 +11,7 @@
 
 
 translations = {
-    u'EUser' : u"Utilisateur",
+    u'CWUser' : u"Utilisateur",
 #    u'Workcase' : u"Affaire",
     u'EmailAddress' : u"Adresse",
 #    u'Division' : u"Division",
@@ -54,7 +54,7 @@
         self.assertEquals(rql, "Any P WHERE P use_email C, C is EmailAddress, C alias 'Logilab'")
         rql = "Any P WHERE P is Utilisateur, P adel C, P nom 'Smith'"
         rql, = self.proc.preprocess_query(rql, self.req)
-        self.assertEquals(rql, "Any P WHERE P is EUser, P use_email C, P surname 'Smith'")
+        self.assertEquals(rql, "Any P WHERE P is CWUser, P use_email C, P surname 'Smith'")
 
 
 class QSPreProcessorTC(EnvBasedTC):
@@ -79,7 +79,7 @@
     def test_attribute_translation(self):
         """tests QSPreProcessor._get_attribute_name"""
         translate = self.proc._get_attribute_name
-        eschema = self.schema.eschema('EUser')
+        eschema = self.schema.eschema('CWUser')
         self.assertEquals(translate(u'prénom', eschema), "firstname")
         self.assertEquals(translate(u'nom', eschema), 'surname')
         #self.assert_(translate(u'nom') in ('name', 'surname'))
@@ -95,10 +95,10 @@
         transform = self.proc._one_word_query
         self.assertEquals(transform('123'),
                           ('Any X WHERE X eid %(x)s', {'x': 123}, 'x'))
-        self.assertEquals(transform('EUser'),
-                          ('EUser E',))
+        self.assertEquals(transform('CWUser'),
+                          ('CWUser E',))
         self.assertEquals(transform('Utilisateur'),
-                          ('EUser E',))
+                          ('CWUser E',))
         self.assertEquals(transform('Adresse'),
                           ('EmailAddress E',))
         self.assertEquals(transform('adresse'),
@@ -108,37 +108,37 @@
     def test_two_words_query(self):
         """tests the 'two words shortcut queries'"""
         transform = self.proc._two_words_query
-        self.assertEquals(transform('EUser', 'E'),
-                          ("EUser E",))
-        self.assertEquals(transform('EUser', 'Smith'),
-                          ('EUser E WHERE E has_text %(text)s', {'text': 'Smith'}))
+        self.assertEquals(transform('CWUser', 'E'),
+                          ("CWUser E",))
+        self.assertEquals(transform('CWUser', 'Smith'),
+                          ('CWUser E WHERE E has_text %(text)s', {'text': 'Smith'}))
         self.assertEquals(transform('utilisateur', 'Smith'),
-                          ('EUser E WHERE E has_text %(text)s', {'text': 'Smith'}))
+                          ('CWUser E WHERE E has_text %(text)s', {'text': 'Smith'}))
         self.assertEquals(transform(u'adresse', 'Logilab'),
                           ('EmailAddress E WHERE E has_text %(text)s', {'text': 'Logilab'}))
         self.assertEquals(transform(u'adresse', 'Logi%'),
                           ('EmailAddress E WHERE E alias LIKE %(text)s', {'text': 'Logi%'}))
         self.assertRaises(BadRQLQuery, transform, "pers", "taratata")
-        #self.assertEquals(transform('EUser', '%mi'), 'EUser E WHERE P surname LIKE "%mi"')
+        #self.assertEquals(transform('CWUser', '%mi'), 'CWUser E WHERE P surname LIKE "%mi"')
 
     def test_three_words_query(self):
         """tests the 'three words shortcut queries'"""
         transform = self.proc._three_words_query
         self.assertEquals(transform('utilisateur', u'prénom', 'cubicweb'),
-                          ('EUser E WHERE E firstname %(text)s', {'text': 'cubicweb'}))
+                          ('CWUser E WHERE E firstname %(text)s', {'text': 'cubicweb'}))
         self.assertEquals(transform('utilisateur', 'nom', 'cubicweb'),
-                          ('EUser E WHERE E surname %(text)s', {'text': 'cubicweb'}))
+                          ('CWUser E WHERE E surname %(text)s', {'text': 'cubicweb'}))
         self.assertEquals(transform(u'adresse', 'nom', 'cubicweb'),
                           ('EmailAddress E WHERE E alias %(text)s', {'text': 'cubicweb'}))
         self.assertEquals(transform('EmailAddress', 'nom', 'cubicweb'),
                           ('EmailAddress E WHERE E alias %(text)s', {'text': 'cubicweb'})) 
         self.assertEquals(transform('utilisateur', u'prénom', 'cubicweb%'),
-                          ('EUser E WHERE E firstname LIKE %(text)s', {'text': 'cubicweb%'}))
+                          ('CWUser E WHERE E firstname LIKE %(text)s', {'text': 'cubicweb%'}))
         # expanded shortcuts
-        self.assertEquals(transform('EUser', 'use_email', 'Logilab'),
-                          ('EUser E WHERE E use_email E1, E1 has_text %(text)s', {'text': 'Logilab'}))
-        self.assertEquals(transform('EUser', 'use_email', '%Logilab'),
-                          ('EUser E WHERE E use_email E1, E1 alias LIKE %(text)s', {'text': '%Logilab'}))
+        self.assertEquals(transform('CWUser', 'use_email', 'Logilab'),
+                          ('CWUser E WHERE E use_email E1, E1 has_text %(text)s', {'text': 'Logilab'}))
+        self.assertEquals(transform('CWUser', 'use_email', '%Logilab'),
+                          ('CWUser E WHERE E use_email E1, E1 alias LIKE %(text)s', {'text': '%Logilab'}))
         self.assertRaises(BadRQLQuery, transform, 'word1', 'word2', 'word3')
         
     def test_multiple_words_query(self):
@@ -150,24 +150,24 @@
         """tests how quoted queries are handled"""
         queries = [
             (u'Adresse "My own EmailAddress"', ('EmailAddress E WHERE E has_text %(text)s', {'text': u'My own EmailAddress'})),
-            (u'Utilisateur prénom "Jean Paul"', ('EUser E WHERE E firstname %(text)s', {'text': 'Jean Paul'})),
-            (u'Utilisateur firstname "Jean Paul"', ('EUser E WHERE E firstname %(text)s', {'text': 'Jean Paul'})),
-            (u'EUser firstname "Jean Paul"', ('EUser E WHERE E firstname %(text)s', {'text': 'Jean Paul'})),
+            (u'Utilisateur prénom "Jean Paul"', ('CWUser E WHERE E firstname %(text)s', {'text': 'Jean Paul'})),
+            (u'Utilisateur firstname "Jean Paul"', ('CWUser E WHERE E firstname %(text)s', {'text': 'Jean Paul'})),
+            (u'CWUser firstname "Jean Paul"', ('CWUser E WHERE E firstname %(text)s', {'text': 'Jean Paul'})),
             ]
         transform = self.proc._quoted_words_query
         for query, expected in queries:
             self.assertEquals(transform(query), expected)
         self.assertRaises(BadRQLQuery, transform, "unquoted rql")
         self.assertRaises(BadRQLQuery, transform, 'pers "Jean Paul"')
-        self.assertRaises(BadRQLQuery, transform, 'EUser firstname other "Jean Paul"')
+        self.assertRaises(BadRQLQuery, transform, 'CWUser firstname other "Jean Paul"')
     
     def test_process_query(self):
         """tests how queries are processed"""
         queries = [
-            (u'Utilisateur', (u"EUser E",)),
-            (u'Utilisateur P', (u"EUser P",)),
-            (u'Utilisateur cubicweb', (u'EUser E WHERE E has_text %(text)s', {'text': u'cubicweb'})),
-            (u'EUser prénom cubicweb', (u'EUser E WHERE E firstname %(text)s', {'text': 'cubicweb'},)),
+            (u'Utilisateur', (u"CWUser E",)),
+            (u'Utilisateur P', (u"CWUser P",)),
+            (u'Utilisateur cubicweb', (u'CWUser E WHERE E has_text %(text)s', {'text': u'cubicweb'})),
+            (u'CWUser prénom cubicweb', (u'CWUser E WHERE E firstname %(text)s', {'text': 'cubicweb'},)),
             (u'Any X WHERE X is Something', (u"Any X WHERE X is Something",)),
             ]
         for query, expected in queries:
@@ -195,11 +195,11 @@
             # XXX this sounds like a language translator test...
             # and it fail
             (u'Utilisateur Smith',
-             ('EUser E WHERE E has_text %(text)s', {'text': u'Smith'})),
+             ('CWUser E WHERE E has_text %(text)s', {'text': u'Smith'})),
             (u'utilisateur nom Smith',
-             ('EUser E WHERE E surname %(text)s', {'text': u'Smith'})),
+             ('CWUser E WHERE E surname %(text)s', {'text': u'Smith'})),
             (u'Any P WHERE P is Utilisateur, P nom "Smith"',
-             ('Any P WHERE P is EUser, P surname "Smith"', None)),
+             ('Any P WHERE P is CWUser, P surname "Smith"', None)),
             ]
         for query, expected in queries:
             rset = self.proc.process_query(query, self.req)
@@ -213,9 +213,9 @@
 
     def test_explicit_component(self):
         self.assertRaises(RQLSyntaxError,
-                          self.proc.process_query, u'rql: EUser E WHERE E noattr "Smith",', self.req)
+                          self.proc.process_query, u'rql: CWUser E WHERE E noattr "Smith",', self.req)
         self.assertRaises(BadRQLQuery,
-                          self.proc.process_query, u'rql: EUser E WHERE E noattr "Smith"', self.req)
+                          self.proc.process_query, u'rql: CWUser E WHERE E noattr "Smith"', self.req)
         rset = self.proc.process_query(u'text: utilisateur Smith', self.req)
         self.assertEquals(rset.rql, 'Any X WHERE X has_text %(text)s')
         self.assertEquals(rset.args, {'text': u'utilisateur Smith'})
--- a/web/test/unittest_urlpublisher.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_urlpublisher.py	Fri Apr 24 19:46:47 2009 +0200
@@ -41,32 +41,32 @@
 
     def test_rest_path(self):
         """tests the rest path resolution"""
-        ctrl, rset = self.process('EUser')
+        ctrl, rset = self.process('CWUser')
         self.assertEquals(ctrl, 'view')
-        self.assertEquals(rset.description[0][0], 'EUser')
+        self.assertEquals(rset.description[0][0], 'CWUser')
         self.assertEquals(rset.printable_rql(),
-                          "Any X,AA,AB,AC,AD ORDERBY AA WHERE X is EUser, X login AA, X firstname AB, X surname AC, X modification_date AD")
-        ctrl, rset = self.process('EUser/login/admin')
+                          "Any X,AA,AB,AC,AD ORDERBY AA WHERE X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD")
+        ctrl, rset = self.process('CWUser/login/admin')
         self.assertEquals(ctrl, 'view')
         self.assertEquals(len(rset), 1)
-        self.assertEquals(rset.description[0][0], 'EUser')
-        self.assertEquals(rset.printable_rql(), 'Any X WHERE X is EUser, X login "admin"')
+        self.assertEquals(rset.description[0][0], 'CWUser')
+        self.assertEquals(rset.printable_rql(), 'Any X WHERE X is CWUser, X login "admin"')
         ctrl, rset = self.process('euser/admin')
         self.assertEquals(ctrl, 'view')
         self.assertEquals(len(rset), 1)
-        self.assertEquals(rset.description[0][0], 'EUser')
-        self.assertEquals(rset.printable_rql(), 'Any X WHERE X is EUser, X login "admin"')
+        self.assertEquals(rset.description[0][0], 'CWUser')
+        self.assertEquals(rset.printable_rql(), 'Any X WHERE X is CWUser, X login "admin"')
         ctrl, rset = self.process('euser/eid/%s'%rset[0][0])
         self.assertEquals(ctrl, 'view')
         self.assertEquals(len(rset), 1)
-        self.assertEquals(rset.description[0][0], 'EUser')
-        self.assertEquals(rset.printable_rql(), 'Any X WHERE X is EUser, X eid 5')
+        self.assertEquals(rset.description[0][0], 'CWUser')
+        self.assertEquals(rset.printable_rql(), 'Any X WHERE X is CWUser, X eid 5')
         # test non-ascii paths
-        ctrl, rset = self.process('EUser/login/%C3%BFsa%C3%BFe')
+        ctrl, rset = self.process('CWUser/login/%C3%BFsa%C3%BFe')
         self.assertEquals(ctrl, 'view')
         self.assertEquals(len(rset), 1)
-        self.assertEquals(rset.description[0][0], 'EUser')
-        self.assertEquals(rset.printable_rql(), u'Any X WHERE X is EUser, X login "ÿsaÿe"')
+        self.assertEquals(rset.description[0][0], 'CWUser')
+        self.assertEquals(rset.printable_rql(), u'Any X WHERE X is CWUser, X login "ÿsaÿe"')
         # test quoted paths
         ctrl, rset = self.process('BlogEntry/title/hell%27o')
         self.assertEquals(ctrl, 'view')
@@ -74,9 +74,9 @@
         self.assertEquals(rset.description[0][0], 'BlogEntry')
         self.assertEquals(rset.printable_rql(), u'Any X WHERE X is BlogEntry, X title "hell\'o"')
         # errors
-        self.assertRaises(NotFound, self.process, 'EUser/eid/30000')
+        self.assertRaises(NotFound, self.process, 'CWUser/eid/30000')
         self.assertRaises(NotFound, self.process, 'Workcases')
-        self.assertRaises(NotFound, self.process, 'EUser/inexistant_attribute/joe')
+        self.assertRaises(NotFound, self.process, 'CWUser/inexistant_attribute/joe')
     
     def test_action_path(self):
         """tests the action path resolution"""
@@ -85,7 +85,7 @@
         self.assertRaises(Redirect, self.process, 'Tag/yo/edit')
         self.assertRaises(NotFound, self.process, 'view/edit')
         self.assertRaises(NotFound, self.process, '1/non_action')
-        self.assertRaises(NotFound, self.process, 'EUser/login/admin/non_action')
+        self.assertRaises(NotFound, self.process, 'CWUser/login/admin/non_action')
 
 
     def test_regexp_path(self):
--- a/web/test/unittest_urlrewrite.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_urlrewrite.py	Fri Apr 24 19:46:47 2009 +0200
@@ -28,7 +28,7 @@
             ('/manage', dict(vid='manage')),
             ('/notfound', {'vid': '404'}),
             ('/error', {'vid': 'error'}),
-            ('/schema/([^/]+?)/?$', {'rql': r'Any X WHERE X is EEType, X name "\1"', 'vid': 'eschema'}),
+            ('/schema/([^/]+?)/?$', {'rql': r'Any X WHERE X is CWEType, X name "\1"', 'vid': 'eschema'}),
             ('/add/([^/]+?)/?$' , dict(vid='creation', etype=r'\1')),
             ('/doc/images/(.+?)/?$', dict(fid='\\1', vid='wdocimages')),
             ('/doc/?$', dict(fid='main', vid='wdoc')),
--- a/web/test/unittest_views_actions.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_views_actions.py	Fri Apr 24 19:46:47 2009 +0200
@@ -4,11 +4,11 @@
 
 class ActionsTC(EnvBasedTC):
     def test_view_action(self):
-        req = self.request(__message='bla bla bla', vid='rss', rql='EUser X')
-        rset = self.execute('EUser X')
+        req = self.request(__message='bla bla bla', vid='rss', rql='CWUser X')
+        rset = self.execute('CWUser X')
         vaction = [action for action in self.vreg.possible_vobjects('actions', req, rset)
                    if action.id == 'view'][0]
-        self.assertEquals(vaction.url(), 'http://testing.fr/cubicweb/view?rql=EUser%20X')
+        self.assertEquals(vaction.url(), 'http://testing.fr/cubicweb/view?rql=CWUser%20X')
 
     def test_sendmail_action(self):
         req = self.request()
--- a/web/test/unittest_views_basecontrollers.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_views_basecontrollers.py	Fri Apr 24 19:46:47 2009 +0200
@@ -11,34 +11,34 @@
 from cubicweb.common.uilib import rql_for_eid
 
 from cubicweb.web import INTERNAL_FIELD_VALUE, Redirect, RequestError
-from cubicweb.web.views.basecontrollers import xmlize
+from cubicweb.web.views.basecontrollers import xhtml_wrap
 
-from cubicweb.entities.authobjs import EUser
+from cubicweb.entities.authobjs import CWUser
 
 
 class EditControllerTC(ControllerTC):
     def setUp(self):
         ControllerTC.setUp(self)
-        self.failUnless('users' in self.schema.eschema('EGroup').get_groups('read'))
-        
+        self.failUnless('users' in self.schema.eschema('CWGroup').get_groups('read'))
+
     def tearDown(self):
         ControllerTC.tearDown(self)
-        self.failUnless('users' in self.schema.eschema('EGroup').get_groups('read'))
-        
+        self.failUnless('users' in self.schema.eschema('CWGroup').get_groups('read'))
+
     def test_noparam_edit(self):
         """check behaviour of this controller without any form parameter
         """
-        
+
         self.req.form = {}
         self.assertRaises(ValidationError, self.publish, self.req)
-        
+
     def test_validation_unique(self):
         """test creation of two linked entities
-        """        
+        """
         user = self.user()
-        self.req.form = {'eid': 'X', '__type:X': 'EUser',
-                         'login:X': u'admin', 'edits-login:X': u'', 
-                         'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'', 
+        self.req.form = {'eid': 'X', '__type:X': 'CWUser',
+                         'login:X': u'admin', 'edits-login:X': u'',
+                         'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
                          }
         self.assertRaises(ValidationError, self.publish, self.req)
 
@@ -47,13 +47,13 @@
         """checking that a manager user can edit itself
         """
         user = self.user()
-        basegroups = [str(eid) for eid, in self.execute('EGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
-        groupeids = [eid for eid, in self.execute('EGroup G WHERE G name in ("managers", "users")')]
+        basegroups = [str(eid) for eid, in self.execute('CWGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
+        groupeids = [eid for eid, in self.execute('CWGroup G WHERE G name in ("managers", "users")')]
         groups = [str(eid) for eid in groupeids]
         stateeid = [eid for eid, in self.execute('State S WHERE S name "activated"')][0]
         self.req.form = {
             'eid':       `user.eid`,
-            '__type:'+`user.eid`:    'EUser',
+            '__type:'+`user.eid`:    'CWUser',
             'login:'+`user.eid`:     unicode(user.login),
             'firstname:'+`user.eid`: u'Th\xe9nault',
             'surname:'+`user.eid`:   u'Sylvain',
@@ -78,10 +78,10 @@
         user = self.create_user('user')
         cnx = self.login('user')
         req = self.request()
-        #self.assertEquals(self.ctrl.schema['EUser']._groups['read'],
+        #self.assertEquals(self.ctrl.schema['CWUser']._groups['read'],
         #                  ('managers', 'users'))
         req.form = {
-            'eid': `user.eid`, '__type:'+`user.eid`: 'EUser',
+            'eid': `user.eid`, '__type:'+`user.eid`: 'CWUser',
             '__maineid' : str(user.eid),
             'upassword:'+`user.eid`: 'tournicoton',
             'upassword-confirm:'+`user.eid`: 'tournicoton',
@@ -97,10 +97,10 @@
         relations (meaning no changes)
         """
         user = self.user()
-        groupeids = [eid for eid, in self.execute('EGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
+        groupeids = [eid for eid, in self.execute('CWGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
         self.req.form = {
             'eid':       `user.eid`,
-            '__type:'+`user.eid`:    'EUser',
+            '__type:'+`user.eid`:    'CWUser',
             'login:'+`user.eid`:     unicode(user.login),
             'firstname:'+`user.eid`: u'Th\xe9nault',
             'surname:'+`user.eid`:   u'Sylvain',
@@ -117,23 +117,23 @@
         self.assertEquals([g.eid for g in e.in_group], groupeids)
         stateeids = [eid for eid, in self.execute('State S WHERE S name "activated"')]
         self.assertEquals([s.eid for s in e.in_state], stateeids)
-        
-        
+
+
     def test_create_multiple_linked(self):
-        gueid = self.execute('EGroup G WHERE G name "users"')[0][0]
+        gueid = self.execute('CWGroup G WHERE G name "users"')[0][0]
         self.req.form = {'eid': ['X', 'Y'],
-                         
-                         '__type:X': 'EUser',
+
+                         '__type:X': 'CWUser',
                          '__maineid' : 'X',
-                         'login:X': u'adim', 'edits-login:X': u'', 
-                         'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'', 
+                         'login:X': u'adim', 'edits-login:X': u'',
+                         'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
                          'surname:X': u'Di Mascio', 'edits-surname:X': '',
 
-                         'in_group:X': `gueid`, 'edits-in_group:X': INTERNAL_FIELD_VALUE, 
-                         
+                         'in_group:X': `gueid`, 'edits-in_group:X': INTERNAL_FIELD_VALUE,
+
                          '__type:Y': 'EmailAddress',
                          'address:Y': u'dima@logilab.fr', 'edits-address:Y': '',
-                         'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE, 
+                         'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE,
                          }
         path, params = self.expect_redirect_publish()
         # should be redirected on the created person
@@ -142,17 +142,17 @@
         self.assertEquals(e.surname, 'Di Mascio')
         email = e.use_email[0]
         self.assertEquals(email.address, 'dima@logilab.fr')
-        
+
     def test_edit_multiple_linked(self):
         peid = self.create_user('adim').eid
         self.req.form = {'eid': [`peid`, 'Y'],
-                         '__type:%s'%peid: 'EUser',
+                         '__type:%s'%peid: 'CWUser',
                          'surname:%s'%peid: u'Di Masci', 'edits-surname:%s'%peid: '',
-                         
+
                          '__type:Y': 'EmailAddress',
                          'address:Y': u'dima@logilab.fr', 'edits-address:Y': '',
                          'use_email:%s'%peid: 'Y', 'edits-use_email:%s'%peid: INTERNAL_FIELD_VALUE,
-                         
+
                          '__redirectrql': 'Any X WHERE X eid %s'%peid,
                          }
         path, params = self.expect_redirect_publish()
@@ -162,14 +162,14 @@
         self.assertEquals(e.surname, 'Di Masci')
         email = e.use_email[0]
         self.assertEquals(email.address, 'dima@logilab.fr')
-        
+
         emaileid = email.eid
         self.req.form = {'eid': [`peid`, `emaileid`],
-                         '__type:%s'%peid: 'EUser',
+                         '__type:%s'%peid: 'CWUser',
                          'surname:%s'%peid: u'Di Masci', 'edits-surname:%s'%peid: 'Di Masci',
                          '__type:%s'%emaileid: 'EmailAddress',
                          'address:%s'%emaileid: u'adim@logilab.fr', 'edits-address:%s'%emaileid: 'dima@logilab.fr',
-                         'use_email:%s'%peid: `emaileid`, 'edits-use_email:%s'%peid: `emaileid`, 
+                         'use_email:%s'%peid: `emaileid`, 'edits-use_email:%s'%peid: `emaileid`,
                          '__redirectrql': 'Any X WHERE X eid %s'%peid,
                          }
         path, params = self.expect_redirect_publish()
@@ -180,21 +180,21 @@
         email = e.use_email[0]
         self.assertEquals(email.address, 'adim@logilab.fr')
 
-        
+
     def test_password_confirm(self):
         """test creation of two linked entities
-        """        
+        """
         user = self.user()
         self.req.form = {'__cloned_eid:X': user.eid,
-                         'eid': 'X', '__type:X': 'EUser',
-                         'login:X': u'toto', 'edits-login:X': u'', 
-                         'upassword:X': u'toto', 'edits-upassword:X': u'', 
+                         'eid': 'X', '__type:X': 'CWUser',
+                         'login:X': u'toto', 'edits-login:X': u'',
+                         'upassword:X': u'toto', 'edits-upassword:X': u'',
                          }
         self.assertRaises(ValidationError, self.publish, self.req)
         self.req.form = {'__cloned_eid:X': user.eid,
-                         'eid': 'X', '__type:X': 'EUser',
-                         'login:X': u'toto', 'edits-login:X': u'', 
-                         'upassword:X': u'toto', 'upassword-confirm:X': u'tutu', 'edits-upassword:X': u'', 
+                         'eid': 'X', '__type:X': 'CWUser',
+                         'login:X': u'toto', 'edits-login:X': u'',
+                         'upassword:X': u'toto', 'upassword-confirm:X': u'tutu', 'edits-upassword:X': u'',
                          }
         self.assertRaises(ValidationError, self.publish, self.req)
 
@@ -220,14 +220,14 @@
                          'described_by_test:X': str(feid), 'edits-described_by_test:X': INTERNAL_FIELD_VALUE,
                          }
         self.expect_redirect_publish()
-        # should be redirected on the created 
+        # should be redirected on the created
         #eid = params['rql'].split()[-1]
         e = self.execute('Salesterm X').get_entity(0, 0)
         self.assertEquals(e.amount, 10)
 
     def test_req_pending_insert(self):
         """make sure req's pending insertions are taken into account"""
-        tmpgroup = self.add_entity('EGroup', name=u"test")
+        tmpgroup = self.add_entity('CWGroup', name=u"test")
         user = self.user()
         self.req.set_session_data('pending_insert', set([(user.eid, 'in_group', tmpgroup.eid)]))
         path, params = self.expect_redirect_publish()
@@ -240,7 +240,7 @@
     def test_req_pending_delete(self):
         """make sure req's pending deletions are taken into account"""
         user = self.user()
-        groupeid = self.execute('INSERT EGroup G: G name "test", U in_group G WHERE U eid %(x)s',
+        groupeid = self.execute('INSERT CWGroup G: G name "test", U in_group G WHERE U eid %(x)s',
                                 {'x': user.eid})[0][0]
         usergroups = [gname for gname, in
                       self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
@@ -258,13 +258,13 @@
         def custom_login_edit(self, formparams, value, relations):
             formparams['login'] = value.upper()
             relations.append('X login %(login)s')
-        EUser.custom_login_edit = custom_login_edit
+        CWUser.custom_login_edit = custom_login_edit
         try:
             user = self.user()
             eid = repr(user.eid)
             self.req.form = {
                 'eid': eid,
-                '__type:'+eid:  'EUser',
+                '__type:'+eid:  'CWUser',
                 'login:'+eid: u'foo',
                 'edits-login:'+eid:  unicode(user.login),
                 }
@@ -272,8 +272,8 @@
             rset = self.execute('Any L WHERE X eid %(x)s, X login L', {'x': user.eid}, 'x')
             self.assertEquals(rset[0][0], 'FOO')
         finally:
-            del EUser.custom_login_edit
-        
+            del CWUser.custom_login_edit
+
     def test_redirect_apply_button(self):
         redirectrql = rql_for_eid(4012) # whatever
         self.req.form = {
@@ -342,74 +342,74 @@
         self.assertEquals(params, {u'__message': u'entities deleted'})
 
     def test_nonregr_egroup_etype_editing(self):
-        """non-regression test checking that a manager user can edit a EEType entity (EGroup)
+        """non-regression test checking that a manager user can edit a CWEType entity (CWGroup)
         """
-        groupeids = [eid for eid, in self.execute('EGroup G WHERE G name "managers"')]
+        groupeids = [eid for eid, in self.execute('CWGroup G WHERE G name "managers"')]
         groups = [str(eid) for eid in groupeids]
-        eeetypeeid = self.execute('EEType X WHERE X name "EGroup"')[0][0]
-        basegroups = [str(eid) for eid, in self.execute('EGroup G WHERE X read_permission G, X eid %(x)s', {'x': eeetypeeid})]
+        eeetypeeid = self.execute('CWEType X WHERE X name "CWGroup"')[0][0]
+        basegroups = [str(eid) for eid, in self.execute('CWGroup G WHERE X read_permission G, X eid %(x)s', {'x': eeetypeeid})]
         self.req.form = {
                 'eid':      `eeetypeeid`,
-                '__type:'+`eeetypeeid`:   'EEType',
-                'name:'+`eeetypeeid`:     u'EGroup',
+                '__type:'+`eeetypeeid`:   'CWEType',
+                'name:'+`eeetypeeid`:     u'CWGroup',
                 'final:'+`eeetypeeid`:    False,
                 'meta:'+`eeetypeeid`:     True,
-                'description:'+`eeetypeeid`:     u'users group', 
+                'description:'+`eeetypeeid`:     u'users group',
                 'read_permission:'+`eeetypeeid`:  groups,
                 #
-                'edits-name:'+`eeetypeeid`:     u'EGroup',
+                'edits-name:'+`eeetypeeid`:     u'CWGroup',
                 'edits-final:'+`eeetypeeid`:    False,
                 'edits-meta:'+`eeetypeeid`:     True,
-                'edits-description:'+`eeetypeeid`:     u'users group', 
+                'edits-description:'+`eeetypeeid`:     u'users group',
                 'edits-read_permission:'+`eeetypeeid`:  basegroups,
                 }
         try:
             path, params = self.expect_redirect_publish()
             e = self.execute('Any X WHERE X eid %(x)s', {'x': eeetypeeid}, 'x').get_entity(0, 0)
-            self.assertEquals(e.name, 'EGroup')
+            self.assertEquals(e.name, 'CWGroup')
             self.assertEquals([g.eid for g in e.read_permission], groupeids)
         finally:
             # restore
-            self.execute('SET X read_permission Y WHERE X name "EGroup", Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
+            self.execute('SET X read_permission Y WHERE X name "CWGroup", Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
             self.commit()
-            
+
     def test_nonregr_eetype_etype_editing(self):
-        """non-regression test checking that a manager user can edit a EEType entity (EEType)
+        """non-regression test checking that a manager user can edit a CWEType entity (CWEType)
         """
-        groupeids = sorted(eid for eid, in self.execute('EGroup G WHERE G name in ("managers", "users")'))
+        groupeids = sorted(eid for eid, in self.execute('CWGroup G WHERE G name in ("managers", "users")'))
         groups = [str(eid) for eid in groupeids]
-        eeetypeeid = self.execute('EEType X WHERE X name "EEType"')[0][0]
-        basegroups = [str(eid) for eid, in self.execute('EGroup G WHERE X read_permission G, X eid %(x)s', {'x': eeetypeeid})]
+        eeetypeeid = self.execute('CWEType X WHERE X name "CWEType"')[0][0]
+        basegroups = [str(eid) for eid, in self.execute('CWGroup G WHERE X read_permission G, X eid %(x)s', {'x': eeetypeeid})]
         self.req.form = {
                 'eid':      `eeetypeeid`,
-                '__type:'+`eeetypeeid`:  'EEType',
-                'name:'+`eeetypeeid`:     u'EEType',
+                '__type:'+`eeetypeeid`:  'CWEType',
+                'name:'+`eeetypeeid`:     u'CWEType',
                 'final:'+`eeetypeeid`:    False,
                 'meta:'+`eeetypeeid`:     True,
-                'description:'+`eeetypeeid`:     u'users group', 
+                'description:'+`eeetypeeid`:     u'users group',
                 'read_permission:'+`eeetypeeid`:  groups,
 
-                'edits-name:'+`eeetypeeid`:     u'EEType',
+                'edits-name:'+`eeetypeeid`:     u'CWEType',
                 'edits-final:'+`eeetypeeid`:    False,
                 'edits-meta:'+`eeetypeeid`:     True,
-                'edits-description:'+`eeetypeeid`:     u'users group', 
+                'edits-description:'+`eeetypeeid`:     u'users group',
                 'edits-read_permission:'+`eeetypeeid`:  basegroups,
                 }
         try:
             path, params = self.expect_redirect_publish()
             e = self.execute('Any X WHERE X eid %(x)s', {'x': eeetypeeid}, 'x').get_entity(0, 0)
-            self.assertEquals(e.name, 'EEType')
+            self.assertEquals(e.name, 'CWEType')
             self.assertEquals(sorted(g.eid for g in e.read_permission), groupeids)
         finally:
             # restore
-            self.execute('SET X read_permission Y WHERE X name "EEType", Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
+            self.execute('SET X read_permission Y WHERE X name "CWEType", Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
             self.commit()
-        
+
     def test_nonregr_strange_text_input(self):
         """non-regression test checking text input containing "13:03:43"
 
         this seems to be postgres (tsearch?) specific
-        """        
+        """
         self.req.form = {
                          'eid': 'A', '__type:A': 'BlogEntry',
                          '__maineid' : 'A',
@@ -424,32 +424,32 @@
 
 
     def test_nonregr_multiple_empty_email_addr(self):
-        gueid = self.execute('EGroup G WHERE G name "users"')[0][0]
+        gueid = self.execute('CWGroup G WHERE G name "users"')[0][0]
         self.req.form = {'eid': ['X', 'Y'],
-                         
-                         '__type:X': 'EUser',
-                         'login:X': u'adim', 'edits-login:X': u'', 
-                         'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'', 
-                         'in_group:X': `gueid`, 'edits-in_group:X': INTERNAL_FIELD_VALUE, 
-                         
+
+                         '__type:X': 'CWUser',
+                         'login:X': u'adim', 'edits-login:X': u'',
+                         'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
+                         'in_group:X': `gueid`, 'edits-in_group:X': INTERNAL_FIELD_VALUE,
+
                          '__type:Y': 'EmailAddress',
                          'address:Y': u'', 'edits-address:Y': '',
                          'alias:Y': u'', 'edits-alias:Y': '',
-                         'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE, 
+                         'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE,
                          }
         self.assertRaises(ValidationError, self.publish, self.req)
 
     def test_nonregr_copy(self):
         user = self.user()
         self.req.form = {'__cloned_eid:X': user.eid,
-                         'eid': 'X', '__type:X': 'EUser',
+                         'eid': 'X', '__type:X': 'CWUser',
                          '__maineid' : 'X',
-                         'login:X': u'toto', 'edits-login:X': u'', 
-                         'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'', 
+                         'login:X': u'toto', 'edits-login:X': u'',
+                         'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
                          }
         path, params = self.expect_redirect_publish()
         self.assertEquals(path, 'euser/toto')
-        e = self.execute('Any X WHERE X is EUser, X login "toto"').get_entity(0, 0)
+        e = self.execute('Any X WHERE X is CWUser, X login "toto"').get_entity(0, 0)
         self.assertEquals(e.login, 'toto')
         self.assertEquals(e.in_group[0].name, 'managers')
 
@@ -464,8 +464,8 @@
             self.execute('SET P use_email E, P primary_email E WHERE P eid %(p)s, E eid %(e)s',
                          {'p' : p.eid, 'e' : e.eid})
             self.req.form = {'__cloned_eid:X': p.eid,
-                             'eid': 'X', '__type:X': 'EUser',
-                             'login': u'dodo', 'edits-login': u'dodo', 
+                             'eid': 'X', '__type:X': 'CWUser',
+                             'login': u'dodo', 'edits-login': u'dodo',
                              'surname:X': u'Boom', 'edits-surname:X': u'',
                              '__errorurl' : "whatever but required",
                              }
@@ -479,7 +479,7 @@
                 self.req.form['rql'] = 'Any X WHERE X eid %s' % p.eid
                 self.req.form['vid'] = 'copy'
                 self.env.app.publish('view', self.req)
-            rset = self.execute('EUser P WHERE P surname "Boom"')
+            rset = self.execute('CWUser P WHERE P surname "Boom"')
             self.assertEquals(len(rset), 0)
         finally:
             p.__class__.skip_copy_for = old_skips
@@ -510,7 +510,7 @@
         self.login('anon')
         req = self.request()
         self.assertRaises(Unauthorized, self.env.app.select_controller, 'sendmail', req)
-   
+
 
 
 class JSONControllerTC(EnvBasedTC):
@@ -527,10 +527,10 @@
 
     ## tests ##################################################################
     def test_simple_exec(self):
-        ctrl = self.ctrl(self.request(rql='EUser P WHERE P login "John"',
+        ctrl = self.ctrl(self.request(rql='CWUser P WHERE P login "John"',
                                       pageid='123'))
         self.assertTextEquals(ctrl.publish(),
-                              xmlize(self.john.view('primary')))
+                              xhtml_wrap(self.john.view('primary')))
 
     def test_json_exec(self):
         rql = 'Any T,N WHERE T is Tag, T name N'
@@ -542,26 +542,26 @@
         self.remote_call('tag_entity', self.john.eid, ['python'])
         self.assertUnorderedIterableEquals([tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
                              ['python', 'cubicweb'])
-        self.assertEquals(self.execute('Any N WHERE T tags P, P is EUser, T name N').rows,
+        self.assertEquals(self.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
                           [['python']])
-    
+
     def test_remote_add_new_tag(self):
         self.remote_call('tag_entity', self.john.eid, ['javascript'])
         self.assertUnorderedIterableEquals([tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
                              ['python', 'cubicweb', 'javascript'])
-        self.assertEquals(self.execute('Any N WHERE T tags P, P is EUser, T name N').rows,
+        self.assertEquals(self.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
                           [['javascript']])
 
     def test_edit_field(self):
-        nbusers = len(self.execute('EUser P'))
+        nbusers = len(self.execute('CWUser P'))
         eid = self.john.eid
         self.remote_call('edit_field', 'apply',
                          ('eid', 'firstname:%s' % eid, '__maineid', '__type:%s'% eid, 'edits-firstname:%s' % eid ),
-                         (str(eid), u'Remi', str(eid), 'EUser', self.john.firstname),
+                         (str(eid), u'Remi', str(eid), 'CWUser', self.john.firstname),
                          'firstname',
                          eid)
         self.commit()
-        rset = self.execute('EUser P')
+        rset = self.execute('CWUser P')
         # make sure we did not insert a new euser here
         self.assertEquals(len(rset), nbusers)
         john = self.execute('Any X WHERE X eid %(x)s', {'x': self.john.eid}, 'x').get_entity(0, 0)
@@ -617,7 +617,7 @@
         req.remove_pending_operations()
         self.assertEquals(req.get_pending_deletes(), [])
         self.assertEquals(req.get_pending_inserts(), [])
-        
+
 
     def test_add_inserts(self):
         res, req = self.remote_call('add_pending_inserts',
@@ -625,7 +625,7 @@
         inserts = req.get_pending_inserts()
         self.assertEquals(inserts, ['12:tags:13', '12:tags:14'])
         req.remove_pending_operations()
-        
+
 
     # silly tests
     def test_external_resource(self):
@@ -639,8 +639,8 @@
         self.assertEquals(self.remote_call('format_date', '"2007-01-01 12:00:00"')[0],
                           simplejson.dumps('2007/01/01'))
 
-        
+
 
-        
+
 if __name__ == '__main__':
     unittest_main()
--- a/web/test/unittest_views_baseforms.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_views_baseforms.py	Fri Apr 24 19:46:47 2009 +0200
@@ -49,7 +49,7 @@
         self.assertTextEquals(expected, cleanup_text(self._build_creation_form(etype)))
         
     def test_base(self):
-        self._test_view_for('EGroup', '''\
+        self._test_view_for('CWGroup', '''\
 <form id="entityForm" class="entityForm" cubicweb:target="eformframe"
 method="post" onsubmit="return freezeFormButtons('entityForm')" enctype="application/x-www-form-urlencoded" action="http://testing.fr/cubicweb/validateform">
 <div class="formTitle"><span>egroup (creation)</span></div>
@@ -57,7 +57,7 @@
 <div class="iformTitle"><span>main informations</span></div>
 <div class="formBody"><fieldset>
 <input type="hidden" name="eid" value="A" />
-<input type="hidden" name="__type:A" value="EGroup" />
+<input type="hidden" name="__type:A" value="CWGroup" />
 <input type="hidden" name="__maineid" value="A" />
 <input id="errorurl" type="hidden" name="__errorurl" value="http://testing.fr/cubicweb/view?rql=Blop&amp;vid=blop" />
 <input type="hidden" name="__form_id" value="edition" />
@@ -88,14 +88,14 @@
 
     def test_with_inline_view(self):
         activated = self.execute('Any X WHERE X is State, X name "activated"')[0][0]
-        self._test_view_for('EUser', '''<form id="entityForm" class="entityForm" cubicweb:target="eformframe"
+        self._test_view_for('CWUser', '''<form id="entityForm" class="entityForm" cubicweb:target="eformframe"
 method="post" onsubmit="return freezeFormButtons('entityForm')" enctype="application/x-www-form-urlencoded" action="http://testing.fr/cubicweb/validateform">
 <div class="formTitle"><span>euser (creation)</span></div>
 <div id="progress">validating...</div>
 <div class="iformTitle"><span>main informations</span></div>
 <div class="formBody"><fieldset>
 <input type="hidden" name="eid" value="A" />
-<input type="hidden" name="__type:A" value="EUser" />
+<input type="hidden" name="__type:A" value="CWUser" />
 <input type="hidden" name="__maineid" value="A" />
 <input id="errorurl" type="hidden" name="__errorurl" value="http://testing.fr/cubicweb/view?rql=Blop&amp;vid=blop" />
 <input type="hidden" name="__form_id" value="edition" />
@@ -159,7 +159,7 @@
 </table>
 <div id="inlineuse_emailslot">
 <div class="inlinedform" id="addNewEmailAddressuse_emailsubject:A" cubicweb:limit="true">
-<a class="addEntity" id="adduse_email:Alink" href="javascript: addInlineCreationForm('A', 'EUser', 'EmailAddress', 'use_email', 'subject')" >+ add a EmailAddress.</a>
+<a class="addEntity" id="adduse_email:Alink" href="javascript: addInlineCreationForm('A', 'CWUser', 'EmailAddress', 'use_email', 'subject')" >+ add a EmailAddress.</a>
 </div>
 <div class="trame_grise">&nbsp;</div>
 </div>
@@ -179,7 +179,7 @@
 
     def test_redirection_after_creation(self):
         req = self.request()
-        req.form['etype'] = 'EUser'
+        req.form['etype'] = 'CWUser'
         view = self.vreg.select_view('creation', req, None)
         self.assertEquals(view.redirect_url(), 'http://testing.fr/cubicweb/euser')
         req.form['__redirectrql'] = 'Any X WHERE X eid 3012'
@@ -229,7 +229,7 @@
 
 
     def test_cloned_elements_in_copy_form(self):
-        rset = self.execute('EUser P WHERE P login "Doe"')
+        rset = self.execute('CWUser P WHERE P login "Doe"')
         output = self.view('copy', rset)
         clones = [attrs for _, attrs in output.input_tags
                   if attrs.get('name', '').startswith('__cloned_eid')]
--- a/web/test/unittest_views_baseviews.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_views_baseviews.py	Fri Apr 24 19:46:47 2009 +0200
@@ -39,7 +39,7 @@
         
     def test_more_than_one_entity(self):
         req = self.request()
-        rset = self.execute('Any X WHERE X is EUser')
+        rset = self.execute('Any X WHERE X is CWUser')
         self.assertEquals(vid_from_rset(req, rset, self.schema), 'list')
         rset = self.execute('Any X, L WHERE X login L')
         self.assertEquals(vid_from_rset(req, rset, self.schema), 'list')
@@ -58,16 +58,16 @@
         req = self.request()
         rset = self.execute('Any X, COUNT(T) GROUPBY X WHERE X is T')
         self.assertEquals(vid_from_rset(req, rset, self.schema), 'table')
-        rset = self.execute('Any MAX(X) WHERE X is EUser')
+        rset = self.execute('Any MAX(X) WHERE X is CWUser')
         self.assertEquals(vid_from_rset(req, rset, self.schema), 'table')
 
     def test_subquery(self):
         rset = self.execute(
 'DISTINCT Any X,N ORDERBY N '
 'WITH X,N BEING ('
-'     (DISTINCT Any P,N WHERE P is EUser, P login N)'
+'     (DISTINCT Any P,N WHERE P is CWUser, P login N)'
 '       UNION'
-'     (DISTINCT Any W,N WHERE W is EGroup, W name N))')
+'     (DISTINCT Any W,N WHERE W is CWGroup, W name N))')
         req = self.request()
         self.assertEquals(vid_from_rset(req, rset, self.schema), 'table')
 
--- a/web/test/unittest_views_editforms.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_views_editforms.py	Fri Apr 24 19:46:47 2009 +0200
@@ -9,19 +9,19 @@
 class AutomaticEntityFormTC(EnvBasedTC):
 
     def test_custom_widget(self):
-        AEF.rwidgets.set_rtag(AutoCompletionWidget, 'login', 'subject', 'EUser')
+        AEF.rwidgets.set_rtag(AutoCompletionWidget, 'login', 'subject', 'CWUser')
         form = self.vreg.select_object('forms', 'edition', self.request(), None,
                                        entity=self.user())
         field = form.field_by_name('login')
         self.assertIsInstance(field.widget, AutoCompletionWidget)
-        AEF.rwidgets.del_rtag('login', 'subject', 'EUser')
+        AEF.rwidgets.del_rtag('login', 'subject', 'CWUser')
         
 
     def test_euser_relations_by_category(self):
         #for (rtype, role, stype, otype), tag in AEF.rcategories._tagdefs.items():
         #    if rtype == 'tags':
         #        print rtype, role, stype, otype, ':', tag
-        e = self.etype_instance('EUser')
+        e = self.etype_instance('CWUser')
         # see custom configuration in views.euser
         self.assertEquals(rbc(e, 'primary'),
                           [('login', 'subject'),
@@ -48,7 +48,7 @@
                                ('connait', 'subject'),
                                ('checked_by', 'object'),
                                ])
-        # owned_by is defined both as subject and object relations on EUser
+        # owned_by is defined both as subject and object relations on CWUser
         self.assertListEquals(rbc(e, 'generated'),
                               [('has_text', 'subject'),
                                ('identity', 'subject'),
@@ -63,8 +63,8 @@
                                ])
 
     def test_inlined_view(self):
-        self.failUnless(AEF.rinlined.etype_rtag('EUser', 'use_email', 'subject'))
-        self.failIf(AEF.rinlined.etype_rtag('EUser', 'primary_email', 'subject'))
+        self.failUnless(AEF.rinlined.etype_rtag('CWUser', 'use_email', 'subject'))
+        self.failIf(AEF.rinlined.etype_rtag('CWUser', 'primary_email', 'subject'))
         
     def test_personne_relations_by_category(self):
         e = self.etype_instance('Personne')
@@ -105,7 +105,7 @@
                                ])
         
     def test_edition_form(self):
-        rset = self.execute('EUser X LIMIT 1')
+        rset = self.execute('CWUser X LIMIT 1')
         form = self.vreg.select_object('forms', 'edition', rset.req, rset,
                                        row=0, col=0)
         # should be also selectable by specifying entity
@@ -116,36 +116,36 @@
         
 class FormViewsTC(WebTest):
     def test_delete_conf_formview(self):
-        rset = self.execute('EGroup X')
+        rset = self.execute('CWGroup X')
         self.view('deleteconf', rset, template=None).source
         
     def test_automatic_edition_formview(self):
-        rset = self.execute('EUser X')
+        rset = self.execute('CWUser X')
         self.view('edition', rset, row=0, template=None).source
         
     def test_automatic_edition_formview(self):
-        rset = self.execute('EUser X')
+        rset = self.execute('CWUser X')
         self.view('copy', rset, row=0, template=None).source
         
     def test_automatic_creation_formview(self):
-        self.view('creation', None, etype='EUser', template=None).source
+        self.view('creation', None, etype='CWUser', template=None).source
         
     def test_automatic_muledit_formview(self):
-        rset = self.execute('EUser X')
+        rset = self.execute('CWUser X')
         self.view('muledit', rset, template=None).source
         
     def test_automatic_reledit_formview(self):
-        rset = self.execute('EUser X')
+        rset = self.execute('CWUser X')
         self.view('reledit', rset, row=0, rtype='login', template=None).source
         
     def test_automatic_inline_edit_formview(self):
-        geid = self.execute('EGroup X LIMIT 1')[0][0]
-        rset = self.execute('EUser X LIMIT 1')
+        geid = self.execute('CWGroup X LIMIT 1')[0][0]
+        rset = self.execute('CWUser X LIMIT 1')
         self.view('inline-edition', rset, row=0, rtype='in_group', peid=geid, template=None).source
                               
     def test_automatic_inline_creation_formview(self):
-        geid = self.execute('EGroup X LIMIT 1')[0][0]
-        self.view('inline-creation', None, etype='EUser', rtype='in_group', peid=geid, template=None).source
+        geid = self.execute('CWGroup X LIMIT 1')[0][0]
+        self.view('inline-creation', None, etype='CWUser', rtype='in_group', peid=geid, template=None).source
 
         
 if __name__ == '__main__':
--- a/web/test/unittest_views_navigation.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_views_navigation.py	Fri Apr 24 19:46:47 2009 +0200
@@ -53,7 +53,7 @@
         rset = self.execute('Any RDEF ORDERBY RDEF WHERE RDEF relation_type RT')
         navcomp = self.vreg.select_component('navigation', req, rset)
         html = navcomp.dispatch()
-        rset = self.execute('EFRDef RDEF ORDERBY RDEF')
+        rset = self.execute('CWAttribute RDEF ORDERBY RDEF')
         navcomp = self.vreg.select_component('navigation', req, rset)
         html = navcomp.dispatch()
         rset = self.execute('Any RDEF ORDERBY N WHERE RDEF relation_type RT, RT name N')
@@ -69,7 +69,7 @@
 
     def test_component_context(self):
         view = mock_object(is_primary=lambda x: True)
-        rset = self.execute('EUser X LIMIT 1')
+        rset = self.execute('CWUser X LIMIT 1')
         req = self.request()
         objs = self.vreg.possible_vobjects('contentnavigation', req, rset,
                                            view=view, context='navtop')
@@ -81,7 +81,7 @@
         # breadcrumbs should _NOT_ be in footers by default
         clsids = set(obj.id for obj in objs)
         self.failIf('breadcrumbs' in clsids)
-        self.execute('INSERT EProperty P: P pkey "contentnavigation.breadcrumbs.context", '
+        self.execute('INSERT CWProperty P: P pkey "contentnavigation.breadcrumbs.context", '
                      'P value "navbottom"')
         # breadcrumbs should now be in footers
         req.cnx.commit()
--- a/web/test/unittest_views_searchrestriction.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_views_searchrestriction.py	Fri Apr 24 19:46:47 2009 +0200
@@ -28,25 +28,25 @@
     def test_1(self):
         self.assertEquals(self._generate(self.select, 'in_state', 'subject', 'name'),
                           "DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name 'managers', "
-                          "B in_state A, A name C, B is EUser")
+                          "B in_state A, A name C, B is CWUser")
         
     def test_2(self):
         self.assertEquals(self._generate(self.select, 'tags', 'object', 'name'),
                           "DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name 'managers', "
-                          "A tags B, A name C, B is EUser")
+                          "A tags B, A name C, B is CWUser")
         
     def test_3(self):
         self.assertEquals(self._generate(self.select, 'created_by', 'subject', 'login'),
                           "DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name 'managers', "
-                          "B created_by A, A login C, B is EUser")
+                          "B created_by A, A login C, B is CWUser")
         
     def test_4(self):
-        self.assertEquals(self._generate(self.parse('Any X WHERE X is EUser'), 'created_by', 'subject', 'login'),
-                          "DISTINCT Any A,B ORDERBY B WHERE X is EUser, X created_by A, A login B")
+        self.assertEquals(self._generate(self.parse('Any X WHERE X is CWUser'), 'created_by', 'subject', 'login'),
+                          "DISTINCT Any A,B ORDERBY B WHERE X is CWUser, X created_by A, A login B")
         
     def test_5(self):
-        self.assertEquals(self._generate(self.parse('Any X,L WHERE X is EUser, X login L'), 'created_by', 'subject', 'login'),
-                          "DISTINCT Any A,B ORDERBY B WHERE X is EUser, X created_by A, A login B")
+        self.assertEquals(self._generate(self.parse('Any X,L WHERE X is CWUser, X login L'), 'created_by', 'subject', 'login'),
+                          "DISTINCT Any A,B ORDERBY B WHERE X is CWUser, X created_by A, A login B")
         
     def test_nonregr1(self):
         select = self.parse('Any T,V WHERE T bookmarked_by V?, '
@@ -57,14 +57,14 @@
 
     def test_nonregr2(self):
         #'DISTINCT Any X,TMP,N WHERE P name TMP, X version_of P, P is Project, X is Version, not X in_state S,S name "published", X num N ORDERBY TMP,N'
-        select = self.parse('DISTINCT Any V,TN,L ORDERBY TN,L WHERE T nom TN, V connait T, T is Personne, V is EUser,'
+        select = self.parse('DISTINCT Any V,TN,L ORDERBY TN,L WHERE T nom TN, V connait T, T is Personne, V is CWUser,'
                             'NOT V in_state VS, VS name "published", V login L')
         rschema = self.schema['connait']
         for s, o in rschema.iter_rdefs():
             rschema.set_rproperty(s, o, 'cardinality', '++')
         try:
             self.assertEquals(self._generate(select, 'in_state', 'subject', 'name'),
-                              "DISTINCT Any A,B ORDERBY B WHERE V is EUser, "
+                              "DISTINCT Any A,B ORDERBY B WHERE V is CWUser, "
                               "NOT V in_state VS, VS name 'published', "
                               "V in_state A, A name B")
         finally:
@@ -73,9 +73,9 @@
 
     def test_nonregr3(self):
         #'DISTINCT Any X,TMP,N WHERE P name TMP, X version_of P, P is Project, X is Version, not X in_state S,S name "published", X num N ORDERBY TMP,N'
-        select = self.parse('DISTINCT Any X, MAX(Y) GROUPBY X WHERE X is EUser, Y is Bookmark, X in_group A')
+        select = self.parse('DISTINCT Any X, MAX(Y) GROUPBY X WHERE X is CWUser, Y is Bookmark, X in_group A')
         self.assertEquals(self._generate(select, 'in_group', 'subject', 'name'),
-                          "DISTINCT Any B,C ORDERBY C WHERE X is EUser, X in_group B, B name C")
+                          "DISTINCT Any B,C ORDERBY C WHERE X is CWUser, X in_group B, B name C")
 
         
 if __name__ == '__main__':
--- a/web/test/unittest_viewselector.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_viewselector.py	Fri Apr 24 19:46:47 2009 +0200
@@ -80,7 +80,7 @@
                              [])
         
     def test_possible_views_one_egroup(self):
-        rset, req = self.env.get_rset_and_req('EGroup X WHERE X name "managers"')
+        rset, req = self.env.get_rset_and_req('CWGroup X WHERE X name "managers"')
         self.assertListEqual(self.pviews(req, rset),
                              [('csvexport', baseviews.CSVRsetView),
                               ('ecsvexport', baseviews.CSVEntityView),
@@ -102,7 +102,7 @@
                               ])
             
     def test_possible_views_multiple_egroups(self):
-        rset, req = self.env.get_rset_and_req('EGroup X')
+        rset, req = self.env.get_rset_and_req('CWGroup X')
         self.assertListEqual(self.pviews(req, rset),
                              [('csvexport', baseviews.CSVRsetView),
                               ('ecsvexport', baseviews.CSVEntityView),
@@ -155,7 +155,7 @@
                               ])
 
     def test_possible_views_multiple_eusers(self):
-        rset, req = self.env.get_rset_and_req('EUser X')
+        rset, req = self.env.get_rset_and_req('CWUser X')
         self.assertListEqual(self.pviews(req, rset),
                              [('csvexport', baseviews.CSVRsetView),
                               ('ecsvexport', baseviews.CSVEntityView),
@@ -165,7 +165,7 @@
                               ('list', baseviews.ListView),
                               ('oneline', baseviews.OneLineView),
                               ('owlabox', owl.OWLABOXView),
-                              ('primary', euser.EUserPrimaryView),
+                              ('primary', euser.CWUserPrimaryView),
                               ('rsetxml', baseviews.XMLRsetView),
                               ('rss', baseviews.RssView),
                               ('secondary', baseviews.SecondaryView),
@@ -173,7 +173,7 @@
                               ('table', tableview.TableView),
                               ('text', baseviews.TextView),
                               ('treeview', treeview.TreeView),
-                              ('vcard', vcard.VCardEUserView),
+                              ('vcard', vcard.VCardCWUserView),
                               ('xbel', xbel.XbelView),
                               ('xml', baseviews.XmlView),
                               ])
@@ -193,7 +193,7 @@
                               })
         
     def test_possible_actions_same_type_entities(self):
-        rset, req = self.env.get_rset_and_req('EGroup X')
+        rset, req = self.env.get_rset_and_req('CWGroup X')
         self.assertDictEqual(self.pactions(req, rset),
                              {'useractions': USERACTIONS,
                               'siteactions': SITEACTIONS,
@@ -217,7 +217,7 @@
                               'siteactions': SITEACTIONS})
         
     def test_possible_actions_eetype_euser_entity(self):
-        rset, req = self.env.get_rset_and_req('EEType X WHERE X name "EUser"')
+        rset, req = self.env.get_rset_and_req('CWEType X WHERE X name "CWUser"')
         self.assertDictEqual(self.pactions(req, rset),
                              {'useractions': USERACTIONS,
                               'siteactions': SITEACTIONS,
@@ -233,17 +233,17 @@
         rset = None
         req = self.request()
         # creation form
-        req.form['etype'] = 'EGroup'
+        req.form['etype'] = 'CWGroup'
         self.assertIsInstance(self.vreg.select_view('creation', req, rset),
                                   baseforms.CreationForm)
         del req.form['etype']
         # custom creation form
-        class EUserCreationForm(baseforms.CreationForm):
-            __select__ = specified_etype_implements('EUser')
-        self.vreg.register_vobject_class(EUserCreationForm)
-        req.form['etype'] = 'EUser'
+        class CWUserCreationForm(baseforms.CreationForm):
+            __select__ = specified_etype_implements('CWUser')
+        self.vreg.register_vobject_class(CWUserCreationForm)
+        req.form['etype'] = 'CWUser'
         self.assertIsInstance(self.vreg.select_view('creation', req, rset),
-                              EUserCreationForm)
+                              CWUserCreationForm)
             
     def test_select_view(self):
         # no entity
@@ -267,7 +267,7 @@
         self.failUnlessRaises(NoSelectableObject,
                              self.vreg.select_view, 'table', req, rset)
         # one entity
-        rset, req = self.env.get_rset_and_req('EGroup X WHERE X name "managers"')
+        rset, req = self.env.get_rset_and_req('CWGroup X WHERE X name "managers"')
         self.assertIsInstance(self.vreg.select_view('primary', req, rset),
                              baseviews.PrimaryView)
         self.assertIsInstance(self.vreg.select_view('list', req, rset),
@@ -281,7 +281,7 @@
         self.failUnlessRaises(NoSelectableObject,
                               self.vreg.select_view, 'index', req, rset)
         # list of entities of the same type
-        rset, req = self.env.get_rset_and_req('EGroup X')
+        rset, req = self.env.get_rset_and_req('CWGroup X')
         self.assertIsInstance(self.vreg.select_view('primary', req, rset),
                              baseviews.PrimaryView)
         self.assertIsInstance(self.vreg.select_view('list', req, rset),
@@ -317,7 +317,7 @@
         self.failUnlessRaises(NoSelectableObject,
                              self.vreg.select_view, 'edition', req, rset)
         # mixed query
-        rset, req = self.env.get_rset_and_req('Any U,G WHERE U is EUser, G is EGroup')
+        rset, req = self.env.get_rset_and_req('Any U,G WHERE U is CWUser, G is CWGroup')
         self.failUnlessRaises(NoSelectableObject,
                               self.vreg.select_view, 'edition', req, rset)
         self.failUnlessRaises(NoSelectableObject,
@@ -325,9 +325,9 @@
         self.assertIsInstance(self.vreg.select_view('table', req, rset),
                               tableview.TableView)
         # euser primary view priority
-        rset, req = self.env.get_rset_and_req('EUser X WHERE X login "admin"')
+        rset, req = self.env.get_rset_and_req('CWUser X WHERE X login "admin"')
         self.assertIsInstance(self.vreg.select_view('primary', req, rset),
-                             euser.EUserPrimaryView)
+                             euser.CWUserPrimaryView)
         self.assertIsInstance(self.vreg.select_view('text', req, rset),
                              baseviews.TextView)
 
@@ -367,9 +367,9 @@
     def test_form(self):
         for vid, rql, args in (
             #('creation', 'Any X WHERE X eid 999999', {}),
-            ('edition', 'EGroup X WHERE X name "managers"', {}),
-            ('copy', 'EGroup X WHERE X name "managers"', {}),
-            ('muledit', 'EGroup X', {}),
+            ('edition', 'CWGroup X WHERE X name "managers"', {}),
+            ('copy', 'CWGroup X WHERE X name "managers"', {}),
+            ('muledit', 'CWGroup X', {}),
             #('muledit', 'Any X', {}),
             ):
             self._test_view(vid, rql, args)
@@ -405,7 +405,7 @@
             self.create_user('john')
             self.login('john')
             # it should not be possible to use SomeAction not owned objects
-            rset, req = self.env.get_rset_and_req('Any G WHERE G is EGroup, G name "managers"')
+            rset, req = self.env.get_rset_and_req('Any G WHERE G is CWGroup, G name "managers"')
             self.failIf('foo' in self.pactions(req, rset))
             # insert a new card, and check that we can use SomeAction on our object
             self.execute('INSERT Card C: C title "zoubidou"')
@@ -420,33 +420,33 @@
             del self.vreg[SomeAction.__registry__][SomeAction.id]
 
 
-class EETypeRQLAction(Action):
+class CWETypeRQLAction(Action):
     id = 'testaction'
-    __select__ = implements('EEType') & rql_condition('X name "EEType"')
+    __select__ = implements('CWEType') & rql_condition('X name "CWEType"')
     title = 'bla'
 
 class RQLActionTC(ViewSelectorTC):
             
     def setUp(self):
         super(RQLActionTC, self).setUp()
-        self.vreg.register_vobject_class(EETypeRQLAction)
+        self.vreg.register_vobject_class(CWETypeRQLAction)
         
     def tearDown(self):
         super(RQLActionTC, self).tearDown()        
         del self.vreg._registries['actions']['testaction']
         
     def test(self):
-        rset, req = self.env.get_rset_and_req('EEType X WHERE X name "EEType"')
+        rset, req = self.env.get_rset_and_req('CWEType X WHERE X name "CWEType"')
         self.assertDictEqual(self.pactions(req, rset),
                              {'useractions': USERACTIONS,
                               'siteactions': SITEACTIONS,
                               'mainactions': [('edit', actions.ModifyAction)],
                               'moreactions': [('delete', actions.DeleteAction),
                                               ('copy', actions.CopyAction),
-                                              ('testaction', EETypeRQLAction),
+                                              ('testaction', CWETypeRQLAction),
                                               ('managepermission', actions.ManagePermissionsAction)],
                               })
-        rset, req = self.env.get_rset_and_req('EEType X WHERE X name "ERType"')
+        rset, req = self.env.get_rset_and_req('CWEType X WHERE X name "CWRType"')
         self.assertDictEqual(self.pactions(req, rset),
                              {'useractions': USERACTIONS,
                               'siteactions': SITEACTIONS,
--- a/web/test/unittest_widgets.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/test/unittest_widgets.py	Fri Apr 24 19:46:47 2009 +0200
@@ -32,7 +32,7 @@
                            u'<input type="hidden" name="eid" value="X" />')
 
     def test_textarea_widget(self):
-        self.add_entity('EProperty', pkey=u'ui.fckeditor', value=u'')
+        self.add_entity('CWProperty', pkey=u'ui.fckeditor', value=u'')
         self.commit()
         w = self.get_widget('State', 'description', 'String')
         self.assertEquals(w.name, 'description')
@@ -58,7 +58,7 @@
 </select><br/><textarea onkeypress="autogrow(this)" name="description:X" accesskey="d" cols="80" id="description:X" rows="20" tabindex="1"></textarea>''' % tal_format)
 
     def test_textarea_widget_previous_value(self):
-        self.add_entity('EProperty', pkey=u'ui.fckeditor', value=u'')
+        self.add_entity('CWProperty', pkey=u'ui.fckeditor', value=u'')
         self.commit()
         w = self.get_widget('State', 'description', 'String')
         req = self.request()
@@ -284,11 +284,11 @@
 
 
     def test_password_widget(self):
-        w = self.get_widget('EUser', 'upassword', 'Password')
+        w = self.get_widget('CWUser', 'upassword', 'Password')
         self.assertEquals(w.name, 'upassword')
         self.assertEquals(w.render_example(self.request()), '')
         self.assertDictEquals(w.attrs, {'accesskey': 'u'})
-        entity = self.etype_instance('EUser')
+        entity = self.etype_instance('CWUser')
         entity.eid = 'X'
         self.assertEquals(w.required(entity), True)
         self.assertEquals(w.render(entity), '')
--- a/web/uicfg.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/uicfg.py	Fri Apr 24 19:46:47 2009 +0200
@@ -56,7 +56,7 @@
 # boxes.EditBox configuration #################################################
 
 # 'link' / 'create' relation tags, used to control the "add entity" submenu
-rmode = RelationTags() 
+rmode = RelationTags()
 rmode.set_rtag('link', 'is', 'subject')
 rmode.set_rtag('link', 'is', 'object')
 rmode.set_rtag('link', 'is_instance_of', 'subject')
@@ -67,4 +67,4 @@
 rmode.set_rtag('link', 'created_by', 'subject')
 rmode.set_rtag('link', 'require_permission', 'subject')
 rmode.set_rtag('link', 'wf_info_for', 'subject')
-rmode.set_rtag('link', 'wf_info_for', 'subject')
+rmode.set_rtag('link', 'wf_info_for', 'object')
--- a/web/views/actions.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/actions.py	Fri Apr 24 19:46:47 2009 +0200
@@ -7,7 +7,7 @@
 __docformat__ = "restructuredtext en"
 
 from cubicweb.vregistry import objectify_selector
-from cubicweb.selectors import (EntitySelector, 
+from cubicweb.selectors import (EntitySelector,
     one_line_rset, two_lines_rset, one_etype_rset, relation_possible,
     non_final_entity,
     authenticated_user, match_user_groups, match_search_state,
@@ -26,7 +26,7 @@
 
     See `EntitySelector` documentation for behaviour when row is not specified.
     """
-        
+
     def score_entity(self, entity):
         # if user has no update right but it can modify some relation,
         # display action anyway
@@ -75,11 +75,11 @@
     """
     id = 'select'
     __select__ = match_search_state('linksearch') & match_searched_etype()
-    
+
     title = _('select')
-    category = 'mainactions'    
+    category = 'mainactions'
     order = 0
-    
+
     def url(self):
         return linksearch_select_url(self.req, self.rset)
 
@@ -87,11 +87,11 @@
 class CancelSelectAction(Action):
     id = 'cancel'
     __select__ = match_search_state('linksearch')
-    
+
     title = _('cancel select')
     category = 'mainactions'
     order = 10
-    
+
     def url(self):
         target, eid, r_type, searched_type = self.req.search_state[1]
         return self.build_url(str(eid),
@@ -102,13 +102,13 @@
     id = 'view'
     __select__ = (match_search_state('normal') &
                   match_user_groups('users', 'managers') &
-                  view_is_not_default_view() & 
+                  view_is_not_default_view() &
                   non_final_entity())
-    
+
     title = _('view')
-    category = 'mainactions'    
+    category = 'mainactions'
     order = 0
-    
+
     def url(self):
         params = self.req.form.copy()
         params.pop('vid', None)
@@ -120,9 +120,9 @@
 class ModifyAction(Action):
     id = 'edit'
     __select__ = (match_search_state('normal') &
-                  one_line_rset() & 
+                  one_line_rset() &
                   (has_permission('update') | has_editable_relation('add')))
-    
+
     title = _('modify')
     category = 'mainactions'
     order = 10
@@ -130,7 +130,7 @@
     def url(self):
         entity = self.rset.get_entity(self.row or 0, self.col or 0)
         return entity.absolute_url(vid='edition')
-        
+
 
 class MultipleEditAction(Action):
     id = 'muledit' # XXX get strange conflicts if id='edit'
@@ -141,7 +141,7 @@
     title = _('modify')
     category = 'mainactions'
     order = 10
-    
+
     def url(self):
         return self.build_url('view', rql=self.rset.rql, vid='muledit')
 
@@ -162,37 +162,37 @@
         if 'require_permission' in vreg.schema:
             cls.__select__ = (one_line_rset() & non_final_entity() &
                               (match_user_groups('managers')
-                               | relation_possible('require_permission', 'subject', 'EPermission',
+                               | relation_possible('require_permission', 'subject', 'CWPermission',
                                                    action='add')))
         return super(ManagePermissionsAction, cls).registered(vreg)
-    
+
     def url(self):
-        return self.rset.get_entity(0, 0).absolute_url(vid='security')
+        return self.rset.get_entity(self.row or 0, self.col or 0).absolute_url(vid='security')
 
-    
+
 class DeleteAction(Action):
     id = 'delete'
     __select__ = has_permission('delete')
-    
+
     title = _('delete')
-    category = 'moreactions' 
+    category = 'moreactions'
     order = 20
-    
+
     def url(self):
         if len(self.rset) == 1:
-            entity = self.rset.get_entity(0, 0)
+            entity = self.rset.get_entity(self.row or 0, self.col or 0)
             return self.build_url(entity.rest_path(), vid='deleteconf')
         return self.build_url(rql=self.rset.printable_rql(), vid='deleteconf')
-    
-        
+
+
 class CopyAction(Action):
     id = 'copy'
     __select__ = one_line_rset() & has_permission('add')
-    
+
     title = _('copy')
     category = 'moreactions'
     order = 30
-    
+
     def url(self):
         entity = self.rset.get_entity(self.row or 0, self.col or 0)
         return entity.absolute_url(vid='copy')
@@ -210,7 +210,7 @@
 
     category = 'moreactions'
     order = 40
-    
+
     @property
     def rsettype(self):
         if self.rset:
@@ -230,7 +230,7 @@
 class UserPreferencesAction(Action):
     id = 'myprefs'
     __select__ = authenticated_user()
-    
+
     title = _('user preferences')
     category = 'useractions'
     order = 10
@@ -242,7 +242,7 @@
 class UserInfoAction(Action):
     id = 'myinfos'
     __select__ = authenticated_user()
-    
+
     title = _('personnal informations')
     category = 'useractions'
     order = 20
@@ -254,7 +254,7 @@
 class LogoutAction(Action):
     id = 'logout'
     __select__ = authenticated_user()
-    
+
     title = _('logout')
     category = 'useractions'
     order = 30
@@ -262,7 +262,7 @@
     def url(self):
         return self.build_url(self.id)
 
-    
+
 # site actions ################################################################
 
 class ManagersAction(Action):
@@ -274,13 +274,13 @@
     def url(self):
         return self.build_url(self.id)
 
-    
+
 class SiteConfigurationAction(ManagersAction):
     id = 'siteconfig'
     title = _('site configuration')
     order = 10
 
-    
+
 class ManageAction(ManagersAction):
     id = 'manage'
     title = _('manage')
--- a/web/views/basecontrollers.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/basecontrollers.py	Fri Apr 24 19:46:47 2009 +0200
@@ -18,7 +18,7 @@
 from cubicweb import NoSelectableObject, ValidationError, ObjectNotFound, typed_eid
 from cubicweb.utils import strptime
 from cubicweb.selectors import yes, match_user_groups
-from cubicweb.view import STRICT_DOCTYPE, CW_XHTML_EXTENSIONS
+from cubicweb.view import STRICT_DOCTYPE
 from cubicweb.common.mail import format_mail
 from cubicweb.web import ExplicitLogin, Redirect, RemoteCallFailed
 from cubicweb.web.formrenderers import FormRenderer
@@ -30,8 +30,42 @@
     HAS_SEARCH_RESTRICTION = True
 except ImportError: # gae
     HAS_SEARCH_RESTRICTION = False
-    
-    
+
+
+def xhtml_wrap(source):
+    head = u'<?xml version="1.0"?>\n' + STRICT_DOCTYPE
+    return head + u'<div xmlns="http://www.w3.org/1999/xhtml" xmlns:cubicweb="http://www.logilab.org/2008/cubicweb">%s</div>' % source.strip()
+
+def jsonize(func):
+    """decorator to sets correct content_type and calls `simplejson.dumps` on
+    results
+    """
+    def wrapper(self, *args, **kwargs):
+        self.req.set_content_type('application/json')
+        result = func(self, *args, **kwargs)
+        return simplejson.dumps(result)
+    return wrapper
+
+def xhtmlize(func):
+    """decorator to sets correct content_type and calls `xmlize` on results"""
+    def wrapper(self, *args, **kwargs):
+        self.req.set_content_type(self.req.html_content_type())
+        result = func(self, *args, **kwargs)
+        return xhtml_wrap(result)
+    return wrapper
+
+def check_pageid(func):
+    """decorator which checks the given pageid is found in the
+    user's session data
+    """
+    def wrapper(self, *args, **kwargs):
+        data = self.req.get_session_data(self.req.pageid)
+        if data is None:
+            raise RemoteCallFailed(self.req._('pageid-not-found'))
+        return func(self, *args, **kwargs)
+    return wrapper
+
+
 class LoginController(Controller):
     id = 'login'
 
@@ -44,10 +78,10 @@
             # Cookie authentication
             return self.appli.need_login_content(self.req)
 
-    
+
 class LogoutController(Controller):
     id = 'logout'
-    
+
     def publish(self, rset=None):
         """logout from the application"""
         return self.appli.session_handler.logout(self.req)
@@ -60,7 +94,7 @@
     """
     id = 'view'
     template = 'main-template'
-    
+
     def publish(self, rset=None):
         """publish a request, returning an encoded string"""
         view, rset = self._select_view_and_rset(rset)
@@ -131,7 +165,7 @@
             else:
                 rql = 'SET Y %s X WHERE X eid %%(x)s, Y eid %%(y)s' % rtype
             for teid in eids:
-                req.execute(rql, {'x': eid, 'y': typed_eid(teid)}, ('x', 'y')) 
+                req.execute(rql, {'x': eid, 'y': typed_eid(teid)}, ('x', 'y'))
 
 
 class FormValidatorController(Controller):
@@ -178,56 +212,65 @@
         except AttributeError:
             eid = err.entity
         return (False, (eid, err.errors))
-        
-def xmlize(source):
-    head = u'<?xml version="1.0"?>\n' + STRICT_DOCTYPE % CW_XHTML_EXTENSIONS
-    return head + u'<div xmlns="http://www.w3.org/1999/xhtml" xmlns:cubicweb="http://www.logilab.org/2008/cubicweb">%s</div>' % source.strip()
 
-def jsonize(func):
-    """sets correct content_type and calls `simplejson.dumps` on results
-    """
-    def wrapper(self, *args, **kwargs):
-        self.req.set_content_type('application/json')
-        result = func(self, *args, **kwargs)
-        return simplejson.dumps(result)
-    return wrapper
-
-
-def check_pageid(func):
-    """decorator which checks the given pageid is found in the
-    user's session data
-    """
-    def wrapper(self, *args, **kwargs):
-        data = self.req.get_session_data(self.req.pageid)
-        if data is None:
-            raise RemoteCallFailed(self.req._('pageid-not-found'))
-        return func(self, *args, **kwargs)
-    return wrapper
-    
 
 class JSonController(Controller):
     id = 'json'
-    template = 'main'
 
     def publish(self, rset=None):
-        mode = self.req.form.get('mode', 'html')
+        """call js_* methods. Expected form keys:
+
+        :fname: the method name without the js_ prefix
+        :args: arguments list (json)
+
+        note: it's the responsability of js_* methods to set the correct
+        response content type
+        """
         self.req.pageid = self.req.form.get('pageid')
+        fname = self.req.form['fname']
+        try:
+            func = getattr(self, 'js_%s' % fname)
+        except AttributeError:
+            raise RemoteCallFailed('no %s method' % fname)
+        # no <arg> attribute means the callback takes no argument
+        args = self.req.form.get('arg', ())
+        if not isinstance(args, (list, tuple)):
+            args = (args,)
+        args = [simplejson.loads(arg) for arg in args]
         try:
-            func = getattr(self, '%s_exec' % mode)
-        except AttributeError, ex:
-            self.error('json controller got an unknown mode %r', mode)
-            self.error('\t%s', ex)
-            result = u''
-        else:
-            try:
-                result = func(rset)
-            except RemoteCallFailed:
-                raise
-            except Exception, ex:
-                self.exception('an exception occured on json request(rset=%s): %s',
-                               rset, ex)
-                raise RemoteCallFailed(repr(ex))
-        return result.encode(self.req.encoding)
+            result = func(*args)
+        except RemoteCallFailed:
+            raise
+        except Exception, ex:
+            self.exception('an exception occured while calling js_%s(%s): %s',
+                           fname, args, ex)
+            raise RemoteCallFailed(repr(ex))
+        if result is None:
+            return ''
+        # get unicode on @htmlize methods, encoded string on @jsonize methods
+        elif isinstance(result, unicode):
+            return result.encode(self.req.encoding)
+        return result
+
+    def _rebuild_posted_form(self, names, values, action=None):
+        form = {}
+        for name, value in zip(names, values):
+            # remove possible __action_xxx inputs
+            if name.startswith('__action'):
+                continue
+            # form.setdefault(name, []).append(value)
+            if name in form:
+                curvalue = form[name]
+                if isinstance(curvalue, list):
+                    curvalue.append(value)
+                else:
+                    form[name] = [curvalue, value]
+            else:
+                form[name] = value
+        # simulate click on __action_%s button to help the controller
+        if action:
+            form['__action_%s' % action] = u'whatever'
+        return form
 
     def _exec(self, rql, args=None, eidkey=None, rocheck=True):
         """json mode: execute RQL and return resultset as json"""
@@ -240,31 +283,15 @@
             return None
         return None
 
-    @jsonize
-    def json_exec(self, rset=None):
-        """json mode: execute RQL and return resultset as json"""
-        rql = self.req.form.get('rql')
-        if rset is None and rql:
-            rset = self._exec(rql)
-        return rset and rset.rows or []
-
-    def _set_content_type(self, vobj, data):
-        """sets req's content type according to vobj's content type
-        (and xmlize data if needed)
-        """
-        content_type = vobj.content_type
-        if content_type == 'application/xhtml+xml':
-            self.req.set_content_type(content_type)
-            return xmlize(data)
-        return data
-    
-    def html_exec(self, rset=None):
+    @xhtmlize
+    def js_view(self):
         # XXX try to use the page-content template
         req = self.req
         rql = req.form.get('rql')
-        if rset is None and rql:
+        if rql:
             rset = self._exec(rql)
-        
+        else:
+            rset = None
         vid = req.form.get('vid') or vid_from_rset(req, rset, self.schema)
         try:
             view = self.vreg.select_view(vid, req, rset)
@@ -292,46 +319,46 @@
             stream.write(u'</div>\n')
         if req.form.get('paginate') and divid == 'pageContent':
             stream.write(u'</div></div>')
-        source = stream.getvalue()
-        return self._set_content_type(view, source)
+        return stream.getvalue()
 
-    def rawremote_exec(self, rset=None):
-        """like remote_exec but doesn't change content type"""
-        # no <arg> attribute means the callback takes no argument
-        args = self.req.form.get('arg', ())
-        if not isinstance(args, (list, tuple)):
-            args = (args,)
-        fname = self.req.form['fname']
-        args = [simplejson.loads(arg) for arg in args]
-        try:
-            func = getattr(self, 'js_%s' % fname)
-        except AttributeError:
-            self.exception('rawremote_exec fname=%s', fname)
-            return u""
-        return func(*args)
+    @xhtmlize
+    def js_prop_widget(self, propkey, varname, tabindex=None):
+        """specific method for CWProperty handling"""
+        entity = self.vreg.etype_class('CWProperty')(self.req, None, None)
+        entity.eid = varname
+        entity['pkey'] = propkey
+        form = self.vreg.select_object('forms', 'edition', self.req, None,
+                                       entity=entity)
+        form.form_build_context()
+        vfield = form.field_by_name('value')
+        renderer = FormRenderer()
+        return vfield.render(form, renderer, tabindex=tabindex) \
+               + renderer.render_help(form, vfield)
 
-    remote_exec = jsonize(rawremote_exec)
-        
-    def _rebuild_posted_form(self, names, values, action=None):
-        form = {}
-        for name, value in zip(names, values):
-            # remove possible __action_xxx inputs
-            if name.startswith('__action'):
-                continue
-            # form.setdefault(name, []).append(value)
-            if name in form:
-                curvalue = form[name]
-                if isinstance(curvalue, list):
-                    curvalue.append(value)
-                else:
-                    form[name] = [curvalue, value]
-            else:
-                form[name] = value
-        # simulate click on __action_%s button to help the controller
-        if action:
-            form['__action_%s' % action] = u'whatever'
-        return form
-    
+    @xhtmlize
+    def js_component(self, compid, rql, registry='components', extraargs=None):
+        if rql:
+            rset = self._exec(rql)
+        else:
+            rset = None
+        comp = self.vreg.select_object(registry, compid, self.req, rset)
+        if extraargs is None:
+            extraargs = {}
+        else: # we receive unicode keys which is not supported by the **syntax
+            extraargs = dict((str(key), value)
+                             for key, value in extraargs.items())
+        extraargs = extraargs or {}
+        return comp.dispatch(**extraargs)
+
+    @check_pageid
+    @xhtmlize
+    def js_inline_creation_form(self, peid, ttype, rtype, role):
+        view = self.vreg.select_view('inline-creation', self.req, None,
+                                     etype=ttype, peid=peid, rtype=rtype,
+                                     role=role)
+        return view.dispatch(etype=ttype, peid=peid, rtype=rtype, role=role)
+
+    @jsonize
     def js_validate_form(self, action, names, values):
         # XXX this method (and correspoding js calls) should use the new
         #     `RemoteCallFailed` mechansim
@@ -359,6 +386,7 @@
             return (False, self.req._(str(err)))
         return (False, '???')
 
+    @jsonize
     def js_edit_field(self, action, names, values, rtype, eid):
         success, args = self.js_validate_form(action, names, values)
         if success:
@@ -368,52 +396,29 @@
             return (success, args, entity.printable_value(rtype))
         else:
             return (success, args, None)
-            
-    def js_rql(self, rql):
-        rset = self._exec(rql)
-        return rset and rset.rows or []
-    
+
+#     def js_rql(self, rql):
+#         rset = self._exec(rql)
+#         return rset and rset.rows or []
+
+    @jsonize
     def js_i18n(self, msgids):
         """returns the translation of `msgid`"""
         return [self.req._(msgid) for msgid in msgids]
 
+    @jsonize
     def js_format_date(self, strdate):
         """returns the formatted date for `msgid`"""
         date = strptime(strdate, '%Y-%m-%d %H:%M:%S')
         return self.format_date(date)
 
+    @jsonize
     def js_external_resource(self, resource):
         """returns the URL of the external resource named `resource`"""
         return self.req.external_resource(resource)
 
-    def js_prop_widget(self, propkey, varname, tabindex=None):
-        """specific method for EProperty handling"""
-        entity = self.vreg.etype_class('EProperty')(self.req, None, None)
-        entity.eid = varname
-        entity['pkey'] = propkey
-        form = self.vreg.select_object('forms', 'edition', self.req, None,
-                                       entity=entity)
-        form.form_build_context()
-        vfield = form.field_by_name('value')
-        renderer = FormRenderer()
-        return vfield.render(form, renderer, tabindex=tabindex) \
-                   + renderer.render_help(form, vfield)
-
-    def js_component(self, compid, rql, registry='components', extraargs=None):
-        if rql:
-            rset = self._exec(rql)
-        else:
-            rset = None
-        comp = self.vreg.select_object(registry, compid, self.req, rset)
-        if extraargs is None:
-            extraargs = {}
-        else: # we receive unicode keys which is not supported by the **syntax
-            extraargs = dict((str(key), value)
-                             for key, value in extraargs.items())
-        extraargs = extraargs or {}
-        return self._set_content_type(comp, comp.dispatch(**extraargs))
-
     @check_pageid
+    @jsonize
     def js_user_callback(self, cbname):
         page_data = self.req.get_session_data(self.req.pageid, {})
         try:
@@ -421,53 +426,16 @@
         except KeyError:
             return None
         return cb(self.req)
-    
-    def js_unregister_user_callback(self, cbname):
-        self.req.unregister_callback(self.req.pageid, cbname)
-
-    def js_unload_page_data(self):
-        self.req.del_session_data(self.req.pageid)
-        
-    def js_cancel_edition(self, errorurl):
-        """cancelling edition from javascript
-
-        We need to clear associated req's data :
-          - errorurl
-          - pending insertions / deletions
-        """
-        self.req.cancel_edition(errorurl)
-    
-    @check_pageid
-    def js_inline_creation_form(self, peid, ttype, rtype, role):
-        view = self.vreg.select_view('inline-creation', self.req, None,
-                                     etype=ttype, peid=peid, rtype=rtype,
-                                     role=role)
-        source = view.dispatch(etype=ttype, peid=peid, rtype=rtype, role=role)
-        return self._set_content_type(view, source)
-
-    def js_remove_pending_insert(self, (eidfrom, rel, eidto)):
-        self._remove_pending(eidfrom, rel, eidto, 'insert')
-        
-    def js_add_pending_insert(self, (eidfrom, rel, eidto)):
-        self._add_pending(eidfrom, rel, eidto, 'insert')
-        
-    def js_add_pending_inserts(self, tripletlist):
-        for eidfrom, rel, eidto in tripletlist:
-            self._add_pending(eidfrom, rel, eidto, 'insert')
-        
-    def js_remove_pending_delete(self, (eidfrom, rel, eidto)):
-        self._remove_pending(eidfrom, rel, eidto, 'delete')
-    
-    def js_add_pending_delete(self, (eidfrom, rel, eidto)):
-        self._add_pending(eidfrom, rel, eidto, 'delete')
 
     if HAS_SEARCH_RESTRICTION:
+        @jsonize
         def js_filter_build_rql(self, names, values):
             form = self._rebuild_posted_form(names, values)
             self.req.form = form
             builder = FilterRQLBuilder(self.req)
             return builder.build_rql()
 
+        @jsonize
         def js_filter_select_content(self, facetids, rql):
             rqlst = self.vreg.parse(self.req, rql) # XXX Union unsupported yet
             mainvar = prepare_facets_rqlst(rqlst)[0]
@@ -477,13 +445,33 @@
                 update_map[facetid] = facet.possible_values()
             return update_map
 
+    def js_unregister_user_callback(self, cbname):
+        self.req.unregister_callback(self.req.pageid, cbname)
+
+    def js_unload_page_data(self):
+        self.req.del_session_data(self.req.pageid)
+
+    def js_cancel_edition(self, errorurl):
+        """cancelling edition from javascript
+
+        We need to clear associated req's data :
+          - errorurl
+          - pending insertions / deletions
+        """
+        self.req.cancel_edition(errorurl)
+
     def js_delete_bookmark(self, beid):
-        try:
-            rql = 'DELETE B bookmarked_by U WHERE B eid %(b)s, U eid %(u)s'
-            self.req.execute(rql, {'b': typed_eid(beid), 'u' : self.req.user.eid})
-        except Exception, ex:
-            self.exception(unicode(ex))
-            return self.req._('Problem occured')
+        rql = 'DELETE B bookmarked_by U WHERE B eid %(b)s, U eid %(u)s'
+        self.req.execute(rql, {'b': typed_eid(beid), 'u' : self.req.user.eid})
+
+    def js_set_cookie(self, cookiename, cookievalue):
+        # XXX we should consider jQuery.Cookie
+        cookiename, cookievalue = str(cookiename), str(cookievalue)
+        cookies = self.req.get_cookie()
+        cookies[cookiename] = cookievalue
+        self.req.set_cookie(cookies, cookiename)
+
+    # relations edition stuff ##################################################
 
     def _add_pending(self, eidfrom, rel, eidto, kind):
         key = 'pending_%s' % kind
@@ -492,7 +480,7 @@
         self.req.set_session_data(key, pendings)
 
     def _remove_pending(self, eidfrom, rel, eidto, kind):
-        key = 'pending_%s' % kind        
+        key = 'pending_%s' % kind
         try:
             pendings = self.req.get_session_data(key)
             pendings.remove( (typed_eid(eidfrom), rel, typed_eid(eidto)) )
@@ -501,6 +489,21 @@
         else:
             self.req.set_session_data(key, pendings)
 
+    def js_remove_pending_insert(self, (eidfrom, rel, eidto)):
+        self._remove_pending(eidfrom, rel, eidto, 'insert')
+
+    def js_add_pending_inserts(self, tripletlist):
+        for eidfrom, rel, eidto in tripletlist:
+            self._add_pending(eidfrom, rel, eidto, 'insert')
+
+    def js_remove_pending_delete(self, (eidfrom, rel, eidto)):
+        self._remove_pending(eidfrom, rel, eidto, 'delete')
+
+    def js_add_pending_delete(self, (eidfrom, rel, eidto)):
+        self._add_pending(eidfrom, rel, eidto, 'delete')
+
+    # XXX specific code. Kill me and my AddComboBox friend
+    @jsonize
     def js_add_and_link_new_entity(self, etype_to, rel, eid_to, etype_from, value_from):
         # create a new entity
         eid_from = self.req.execute('INSERT %s T : T name "%s"' % ( etype_from, value_from ))[0][0]
@@ -508,12 +511,6 @@
         rql = 'SET F %(rel)s T WHERE F eid %(eid_to)s, T eid %(eid_from)s' % {'rel' : rel, 'eid_to' : eid_to, 'eid_from' : eid_from}
         return eid_from
 
-    def js_set_cookie(self, cookiename, cookievalue):
-        # XXX we should consider jQuery.Cookie
-        cookiename, cookievalue = str(cookiename), str(cookievalue)
-        cookies = self.req.get_cookie()
-        cookies[cookiename] = cookievalue
-        self.req.set_cookie(cookies, cookiename)
 
 class SendMailController(Controller):
     id = 'sendmail'
@@ -549,12 +546,12 @@
         msg = format_mail({'email' : self.req.user.get_email(),
                            'name' : self.req.user.dc_title(),},
                           [recipient], body, subject)
-        self.smtp.sendmail(helo_addr, [recipient], msg.as_string())    
+        self.smtp.sendmail(helo_addr, [recipient], msg.as_string())
 
     def publish(self, rset=None):
         # XXX this allow anybody with access to an cubicweb application to use it as a mail relay
         body = self.req.form['mailbody']
-        subject = self.req.form['mailsubject']
+        subject = self.req.form['subject']
         for recipient in self.recipients():
             text = body % recipient.as_email_context()
             self.sendmail(recipient.get_email(), subject, text)
@@ -572,4 +569,4 @@
         self.sendmail(self.config['submit-mail'], _('%s error report') % self.config.appid, body)
         url = self.build_url(__message=self.req._('bug report sent'))
         raise Redirect(url)
-    
+
--- a/web/views/basetemplates.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/basetemplates.py	Fri Apr 24 19:46:47 2009 +0200
@@ -12,7 +12,7 @@
 
 from cubicweb.vregistry import objectify_selector
 from cubicweb.selectors import match_kwargs
-from cubicweb.view import View, MainTemplate,  NOINDEX, NOFOLLOW
+from cubicweb.view import View, MainTemplate,  NOINDEX, NOFOLLOW, STRICT_DOCTYPE
 from cubicweb.utils import make_uid, UStringIO
 
 # main templates ##############################################################
@@ -78,14 +78,20 @@
 class NonTemplatableViewTemplate(MainTemplate):
     """main template for any non templatable views (xml, binaries, etc.)"""
     id = 'main-template'
-    __select__ = ~ templatable_view()
-    
+    __select__ = ~templatable_view()
+
     def call(self, view):
         view.set_request_content_type()
-        self.set_stream(templatable=False)
+        view.set_stream()
+        xhtml_wrap = (self.req.form.has_key('__notemplate') and view.templatable
+                      and view.content_type == self.req.html_content_type())
+        if xhtml_wrap:
+            view.w(u'<?xml version="1.0"?>\n' + STRICT_DOCTYPE)
+            view.w(u'<div xmlns="http://www.w3.org/1999/xhtml" xmlns:cubicweb="http://www.logilab.org/2008/cubicweb">')
         # have to replace our unicode stream using view's binary stream
         view.dispatch()
-        assert self._stream, 'duh, template used as a sub-view ?? (%s)' % self._stream
+        if xhtml_wrap:
+            view.w(u'</div>')
         self._stream = view._stream
 
 
@@ -96,7 +102,7 @@
     """
     id = 'main-template'
     __select__ = templatable_view()
-    
+
     def call(self, view):
         self.set_request_content_type()
         self.template_header(self.content_type, view)
@@ -417,9 +423,9 @@
 class LogFormTemplate(View):
     id = 'logform'
     __select__ = match_kwargs('id', 'klass')
-    
+
     title = 'log in'
-    
+
     def call(self, id, klass, title=True, message=True):
         self.req.add_css('cubicweb.login.css')
         self.w(u'<div id="%s" class="%s">' % (id, klass))
--- a/web/views/baseviews.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/baseviews.py	Fri Apr 24 19:46:47 2009 +0200
@@ -40,7 +40,7 @@
     """default view when no result has been found"""
     __select__ = empty_rset()
     id = 'noresult'
-    
+
     def call(self, **kwargs):
         self.w(u'<div class="searchMessage"><strong>%s</strong></div>\n'
                % self.req._('No result matching query'))
@@ -48,7 +48,7 @@
 
 class FinalView(AnyRsetView):
     """display values without any transformation (i.e. get a number for
-    entities) 
+    entities)
     """
     id = 'final'
     # record generated i18n catalog messages
@@ -66,7 +66,7 @@
     _('%d hours')
     _('%d minutes')
     _('%d seconds')
-            
+
     def cell_call(self, row, col, props=None, displaytime=False, format='text/html'):
         etype = self.rset.description[row][col]
         value = self.rset.rows[row][col]
@@ -77,7 +77,7 @@
                 self.w(entity.printable_value(rtype, value, format=format))
                 return
         if etype in ('Time', 'Interval'):
-            # value is DateTimeDelta but we have no idea about what is the 
+            # value is DateTimeDelta but we have no idea about what is the
             # reference date here, so we can only approximate years and months
             if format == 'text/html':
                 space = '&nbsp;'
@@ -100,9 +100,9 @@
             return
         self.wdata(printable_value(self.req, etype, value, props, displaytime=displaytime))
 
-        
+
 PRIMARY_SKIP_RELS = set(['is', 'is_instance_of', 'identity',
-                         'owned_by', 'created_by', 
+                         'owned_by', 'created_by',
                          'in_state', 'wf_info_for', 'require_permission',
                          'from_entity', 'to_entity',
                          'see_also'])
@@ -125,12 +125,12 @@
         by default primary views are indexed
         """
         return []
-    
-    def cell_call(self, row, col):        
+
+    def cell_call(self, row, col):
         self.row = row
         # XXX move render_entity implementation here
         self.render_entity(self.complete_entity(row, col))
-    
+
     def render_entity(self, entity):
         """return html to display the given entity"""
         siderelations = []
@@ -138,6 +138,9 @@
         self.render_entity_metadata(entity)
         # entity's attributes and relations, excluding meta data
         # if the entity isn't meta itself
+        boxes = self._preinit_side_related(entity, siderelations)
+        if boxes:
+            self.w(u'<table width="100%"><tr><td width="75%">')
         self.w(u'<div>')
         self.w(u'<div class="mainInfo">')
         self.render_entity_attributes(entity, siderelations)
@@ -146,13 +149,16 @@
         if self.main_related_section:
             self.render_entity_relations(entity, siderelations)
         self.w(u'</div>')
-        # side boxes
-        self.w(u'<div class="primaryRight">')
-        self.render_side_related(entity, siderelations)
-        self.w(u'</div>')
-        self.w(u'<div class="clear"></div>')          
+        if boxes:
+            self.w(u'</td><td>')
+            # side boxes
+            self.w(u'<div class="primaryRight">')
+            self.render_side_related(entity, siderelations)
+            self.w(u'</div>')
+            self.w(u'</td></tr></table>')
         self.content_navigation_components('navcontentbottom')
 
+
     def content_navigation_components(self, context):
         self.w(u'<div class="%s">' % context)
         for comp in self.vreg.possible_vobjects('contentnavigation',
@@ -165,13 +171,13 @@
                      % comp.__class__, DeprecationWarning)
                 comp.dispatch(w=self.w, view=self)
         self.w(u'</div>')
-        
+
     def iter_attributes(self, entity):
         for rschema, targetschema in entity.e_schema.attribute_definitions():
             if rschema.type in self.skip_attrs:
                 continue
             yield rschema, targetschema
-            
+
     def iter_relations(self, entity):
         skip = set(self.skip_rels)
         skip.update(PRIMARY_SKIP_RELS)
@@ -185,21 +191,21 @@
         if title:
             self.w(u'<h1><span class="etype">%s</span> %s</h1>'
                    % (entity.dc_type().capitalize(), title))
-    
+
     def content_title(self, entity):
         """default implementation return an empty string"""
         return u''
-            
+
     def render_entity_metadata(self, entity):
         entity.view('metadata', w=self.w)
         summary = self.summary(entity) # deprecate summary?
         if summary:
             self.w(u'<div class="summary">%s</div>' % summary)
-    
+
     def summary(self, entity):
         """default implementation return an empty string"""
-        return u''    
-               
+        return u''
+
     def render_entity_attributes(self, entity, siderelations):
         for rschema, targetschema in self.iter_attributes(entity):
             attr = rschema.type
@@ -217,35 +223,46 @@
                 continue
             self._render_related_entities(entity, rschema, value)
 
-    def render_entity_relations(self, entity, siderelations):
+    def _preinit_side_related(self, entity, siderelations):
+        self._sideboxes = None
+        self._related_entities = []
         if hasattr(self, 'get_side_boxes_defs'):
-            return
-        eschema = entity.e_schema
-        maxrelated = self.req.property_value('navigation.related-limit')
-        for rschema, targetschemas, x in self.iter_relations(entity):
-            try:
-                related = entity.related(rschema.type, x, limit=maxrelated+1)
-            except Unauthorized:
-                continue
-            if not related:
-                continue
-            if self.is_side_related(rschema, eschema):
-                siderelations.append((rschema, related, x))
-                continue
-            self._render_related_entities(entity, rschema, related, x)
+            self._sideboxes = [(label, rset) for label, rset in self.get_side_boxes_defs(entity)
+                               if rset]
+        else:
+            eschema = entity.e_schema
+            maxrelated = self.req.property_value('navigation.related-limit')
+            for rschema, targetschemas, x in self.iter_relations(entity):
+                try:
+                    related = entity.related(rschema.type, x, limit=maxrelated+1)
+                except Unauthorized:
+                    continue
+                if not related:
+                    continue
+                if self.is_side_related(rschema, eschema):
+                    siderelations.append((rschema, related, x))
+                    continue
+                self._related_entities.append((rschema, related, x))
+        self._boxes_in_context = list(self.vreg.possible_vobjects('boxes', self.req, self.rset,
+                                                 row=self.row, view=self,
+                                                 context='incontext'))
+        return self._sideboxes or self._boxes_in_context or self._related_entities or siderelations
+
+    def render_entity_relations(self, entity, siderelations):
+        if self._related_entities:
+            for rschema, related, x in self._related_entities:
+                self._render_related_entities(entity, rschema, related, x)
+
 
     def render_side_related(self, entity, siderelations):
         """display side related relations:
         non-meta in a first step, meta in a second step
         """
-        if hasattr(self, 'get_side_boxes_defs'):
-            sideboxes = [(label, rset) for label, rset in self.get_side_boxes_defs(entity)
-                         if rset]
-            if sideboxes:
-                for label, rset in sideboxes:
-                    self.w(u'<div class="sideRelated">')
-                    self.wview('sidebox', rset, title=label)
-                    self.w(u'</div>')
+        if self._sideboxes:
+            for label, rset in self._sideboxes:
+                self.w(u'<div class="sideRelated">')
+                self.wview('sidebox', rset, title=label)
+                self.w(u'</div>')
         elif siderelations:
             self.w(u'<div class="sideRelated">')
             for relatedinfos in siderelations:
@@ -253,18 +270,16 @@
                 #    continue
                 self._render_related_entities(entity, *relatedinfos)
             self.w(u'</div>')
-        boxes = list(self.vreg.possible_vobjects('boxes', self.req, self.rset,
-                                                 row=self.row, view=self,
-                                                 context='incontext'))
-        if boxes:
-            for box in boxes:
+
+        if self._boxes_in_context:
+            for box in self._boxes_in_context:
                 try:
                     box.dispatch(w=self.w, row=self.row)
                 except NotImplementedError:
                     # much probably a context insensitive box, which only implements
                     # .call() and not cell_call()
-                    box.dispatch(w=self.w)               
-                
+                    box.dispatch(w=self.w)
+
     def is_side_related(self, rschema, eschema):
         return rschema.meta and \
                not rschema.schema_relation() == eschema.schema_entity()
@@ -296,13 +311,13 @@
                                                     self.req._('see them all'))
                 value +=  '</div>'
         label = display_name(self.req, rschema.type, role)
-        self.field(label, value, show_label=show_label, w=self.w, tr=False)
+        self.field(label, value, show_label=show_label, tr=False)
 
- 
+
 class SecondaryView(EntityView):
     id = 'secondary'
     title = _('secondary')
-    
+
     def cell_call(self, row, col):
         """the secondary view for an entity
         secondary = icon + view(oneline)
@@ -314,7 +329,7 @@
 
 class OneLineView(EntityView):
     id = 'oneline'
-    title = _('oneline') 
+    title = _('oneline')
 
     def cell_call(self, row, col):
         """the one line view for an entity: linked text view
@@ -345,7 +360,7 @@
             self.wview(self.id, rset, row=i, **kwargs)
             if len(rset) > 1:
                 self.w(u"\n")
-    
+
     def cell_call(self, row, col=0, **kwargs):
         entity = self.entity(row, col)
         self.w(cut(entity.dc_title(),
@@ -356,7 +371,7 @@
     """paragraph view of some metadata"""
     id = 'metadata'
     show_eid = True
-    
+
     def cell_call(self, row, col):
         _ = self.req._
         entity = self.entity(row, col)
@@ -365,15 +380,15 @@
             self.w(u'#%s - ' % entity.eid)
         if entity.modification_date != entity.creation_date:
             self.w(u'<span>%s</span> ' % _('latest update on'))
-            self.w(u'<span class="value">%s</span>,&nbsp;'
+            self.w(u'<span class="value">%s</span>, ;'
                    % self.format_date(entity.modification_date))
         # entities from external source may not have a creation date (eg ldap)
-        if entity.creation_date: 
+        if entity.creation_date:
             self.w(u'<span>%s</span> ' % _('created on'))
             self.w(u'<span class="value">%s</span>'
                    % self.format_date(entity.creation_date))
         if entity.creator:
-            self.w(u'&nbsp;<span>%s</span> ' % _('by'))
+            self.w(u' <span>%s</span> ' % _('by'))
             self.w(u'<span class="value">%s</span>' % entity.creator.name())
         self.w(u'</div>')
 
@@ -408,7 +423,7 @@
         self.w(html_escape(self.view('textincontext', self.rset, row=row, col=col)))
         self.w(u'</a>')
 
-        
+
 class OutOfContextView(EntityView):
     id = 'outofcontext'
 
@@ -417,17 +432,17 @@
         self.w(html_escape(self.view('textoutofcontext', self.rset, row=row, col=col)))
         self.w(u'</a>')
 
-            
+
 # list views ##################################################################
-    
+
 class ListView(EntityView):
     id = 'list'
     title = _('list')
     item_vid = 'listitem'
-        
+
     def call(self, klass=None, title=None, subvid=None, listid=None, **kwargs):
         """display a list of entities by calling their <item_vid> view
-        
+
         :param listid: the DOM id to use for the root element
         """
         if subvid is None and 'subvid' in self.req.form:
@@ -474,16 +489,16 @@
             return self.build_url(entity.rest_path(), vid=self.id)
         return self.build_url(rql=self.rset.printable_rql(), vid=self.id)
 
- 
+
 class ListItemView(EntityView):
     id = 'listitem'
-    
+
     @property
     def redirect_vid(self):
         if self.req.search_state[0] == 'normal':
             return 'outofcontext'
         return 'outofcontext-search'
-        
+
     def cell_call(self, row, col, vid=None, **kwargs):
         if not vid:
             vid = self.redirect_vid
@@ -504,7 +519,7 @@
 class CSVView(SimpleListView):
     id = 'csv'
     redirect_vid = 'incontext'
-        
+
     def call(self, **kwargs):
         rset = self.rset
         for i in xrange(len(rset)):
@@ -515,11 +530,10 @@
 
 class TreeItemView(ListItemView):
     id = 'treeitem'
-    
+
     def cell_call(self, row, col):
         self.wview('incontext', self.rset, row=row, col=col)
 
-
 class TextSearchResultView(EntityView):
     """this view is used to display full-text search
 
@@ -552,7 +566,7 @@
                     else:
                         contexts.append(ctx)
                 value = u'\n' + highlighted.join(contexts)
-                self.w(value.replace('\n', '<br/>'))            
+                self.w(value.replace('\n', '<br/>'))
 
 
 class TooltipView(EntityView):
@@ -579,4 +593,4 @@
 XmlRsetView = class_moved(xmlrss.XmlRsetView)
 RssView = class_moved(xmlrss.RssView)
 RssItemView = class_moved(xmlrss.RssItemView)
-            
+
--- a/web/views/boxes.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/boxes.py	Fri Apr 24 19:46:47 2009 +0200
@@ -24,7 +24,7 @@
 from cubicweb.web.box import BoxTemplate
 
 _ = unicode
-    
+
 class EditBox(BoxTemplate):
     """
     box with all actions impacting the entity displayed: edit, copy, delete
@@ -38,7 +38,7 @@
     # class attributes below are actually stored in the uicfg module since we
     # don't want them to be reloaded
     rmode = uicfg.rmode
-        
+
     @classmethod
     def vreg_initialization_completed(cls):
         """set default category tags for relations where it's not yet defined in
@@ -71,7 +71,9 @@
         """return a string telling if the given relation is usually created
         to a new entity ('create' mode) or to an existant entity ('link' mode)
         """
-        return cls.rmode.rtag(rtype, role, etype, targettype)
+        if role == 'subject':
+            return cls.rmode.rtag(rtype, role, etype, targettype)
+        return cls.rmode.rtag(rtype, role, targettype, etype)
 
 
     def call(self, view=None, **kwargs):
@@ -117,7 +119,7 @@
         self.add_submenu(box, other_menu)
         if not box.is_empty():
             box.render(self.w)
-            
+
     def add_submenu(self, box, submenu, label_prefix=None):
         if len(submenu.items) == 1:
             boxlink = submenu.items[0]
@@ -126,7 +128,7 @@
             box.append(boxlink)
         elif submenu.items:
             box.append(submenu)
-        
+
     def schema_actions(self, entity):
         user = self.req.user
         actions = []
@@ -225,7 +227,7 @@
         title = u"""<span onclick="javascript: toggleVisibility('rqlinput')">%s</span>""" % req._(self.title)
         box = BoxWidget(title, self.id, _class="searchBoxFrame", islist=False, escape=False)
         box.append(BoxHtml(form))
-        box.render(self.w)            
+        box.render(self.w)
 
 
 # boxes disabled by default ###################################################
@@ -234,7 +236,7 @@
     """display a box containing links to all possible views"""
     id = 'possible_views_box'
     __select__ = BoxTemplate.__select__ & match_user_groups('users', 'managers')
-    
+
     visible = False
     title = _('possible views')
     order = 10
@@ -264,7 +266,7 @@
         for view in self.vreg.possible_views(self.req, None):
             if view.category == 'startupview':
                 box.append(self.box_action(view))
-        
+
         if not box.is_empty():
             box.render(self.w)
 
@@ -274,7 +276,7 @@
 class SideBoxView(EntityView):
     """helper view class to display some entities in a sidebox"""
     id = 'sidebox'
-    
+
     def call(self, boxclass='sideBox', title=u''):
         """display a list of entities by calling their <item_vid> view"""
         if title:
--- a/web/views/calendar.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/calendar.py	Fri Apr 24 19:46:47 2009 +0200
@@ -155,7 +155,7 @@
         task_max = 0
         for row in xrange(self.rset.rowcount):
             task = self.rset.get_entity(row, 0)
-            if len(self.rset[row]) > 1 and self.rset.description[row][1] == 'EUser':
+            if len(self.rset[row]) > 1 and self.rset.description[row][1] == 'CWUser':
                 user = self.rset.get_entity(row, 1)
             else:
                 user = None
--- a/web/views/card.py	Wed Apr 22 09:45:54 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-"""Specific views for cards
-
-:organization: Logilab
-:copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-"""
-__docformat__ = "restructuredtext en"
-
-from cubicweb.selectors import implements
-from cubicweb.web.views import baseviews
-from logilab.mtconverter import html_escape
-
-_ = unicode
-
-class CardPrimaryView(baseviews.PrimaryView):
-    __select__ = implements('Card')
-    skip_attrs = baseviews.PrimaryView.skip_attrs + ('title', 'synopsis', 'wikiid')
-    show_attr_label = False
-
-    def content_title(self, entity):
-        return html_escape(entity.dc_title())
-    
-    def summary(self, entity):
-        return html_escape(entity.dc_description())
-
-
-class CardInlinedView(CardPrimaryView):
-    """hide card title and summary"""
-    id = 'inlined'
-    title = _('inlined view')
-    main_related_section = False
-    
-    def render_entity_title(self, entity):
-        pass
-    
-    def render_entity_metadata(self, entity):
-        pass
--- a/web/views/csvexport.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/csvexport.py	Fri Apr 24 19:46:47 2009 +0200
@@ -12,28 +12,28 @@
 class CSVMixIn(object):
     """mixin class for CSV views"""
     templatable = False
-    content_type = "text/comma-separated-values"    
+    content_type = "text/comma-separated-values"
     binary = True # avoid unicode assertion
     csv_params = {'dialect': 'excel',
                   'quotechar': '"',
                   'delimiter': ';',
                   'lineterminator': '\n'}
-    
+
     def set_request_content_type(self):
         """overriden to set a .csv filename"""
         self.req.set_content_type(self.content_type, filename='cubicwebexport.csv')
-            
+
     def csvwriter(self, **kwargs):
         params = self.csv_params.copy()
         params.update(kwargs)
         return UnicodeCSVWriter(self.w, self.req.encoding, **params)
 
-    
+
 class CSVRsetView(CSVMixIn, AnyRsetView):
     """dumps raw result set in CSV"""
     id = 'csvexport'
     title = _('csv export')
-        
+
     def call(self):
         writer = self.csvwriter()
         writer.writerow(self.columns_labels())
@@ -45,16 +45,16 @@
                 etype = descr[rowindex][colindex]
                 if val is not None and not eschema(etype).is_final():
                     # csvrow.append(val) # val is eid in that case
-                    content = self.view('textincontext', rset, 
+                    content = self.view('textincontext', rset,
                                         row=rowindex, col=colindex)
                 else:
                     content = self.view('final', rset,
                                         displaytime=True, format='text/plain',
                                         row=rowindex, col=colindex)
-                csvrow.append(content)                    
+                csvrow.append(content)
             writer.writerow(csvrow)
-    
-    
+
+
 class CSVEntityView(CSVMixIn, EntityView):
     """dumps rset's entities (with full set of attributes) in CSV
 
@@ -83,5 +83,5 @@
         for rows in rows_by_type.itervalues():
             writer.writerows(rows)
             # use two empty lines as separator
-            writer.writerows([[], []])        
-    
+            writer.writerows([[], []])
+
--- a/web/views/editforms.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/editforms.py	Fri Apr 24 19:46:47 2009 +0200
@@ -35,7 +35,7 @@
     if role == 'subject':
         return u'%s:%s:%s' % (eid, rtype, reid)
     return u'%s:%s:%s' % (reid, rtype, eid)
-        
+
 def toggable_relation_link(eid, nodeid, label='x'):
     """return javascript snippet to delete/undelete a relation between two
     entities
@@ -53,7 +53,7 @@
     # don't use navigation, all entities asked to be deleted should be displayed
     # else we will only delete the displayed page
     need_navigation = False
-    
+
     def call(self):
         """ask for confirmation before real deletion"""
         req, w = self.req, self.w
@@ -83,18 +83,18 @@
 
 class ClickAndEditFormView(FormViewMixIn, EntityView):
     """form used to permit ajax edition of an attribute of an entity in a view
-    
+
     (double-click on the field to see an appropriate edition widget)
     """
     id = 'reledit'
     __select__ = non_final_entity() & match_kwargs('rtype')
-    
+
     # FIXME editableField class could be toggleable from userprefs
-    
+
     onsubmit = ("return inlineValidateForm('%(divid)s-form', '%(rtype)s', "
                 "'%(eid)s', '%(divid)s', %(reload)s);")
     ondblclick = "showInlineEditionForm(%(eid)s, '%(rtype)s', '%(divid)s')"
-    
+
     def cell_call(self, row, col, rtype=None, role='subject', reload=False):
         """display field to edit entity's `rtype` relation on double-click"""
         entity = self.entity(row, col)
@@ -142,7 +142,7 @@
     copy_nav_params = True
     form_buttons = [SubmitButton(stdmsgs.BUTTON_OK),
                     Button(stdmsgs.BUTTON_APPLY, cwaction='apply'),
-                    Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')]    
+                    Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')]
     attrcategories = ('primary', 'secondary')
     # class attributes below are actually stored in the uicfg module since we
     # don't want them to be reloaded
@@ -151,7 +151,7 @@
     rwidgets = uicfg.rwidgets
     rinlined = uicfg.rinlined
     rpermissions_overrides = uicfg.rpermissions_overrides
-        
+
     @classmethod
     def vreg_initialization_completed(cls):
         """set default category tags for relations where it's not yet defined in
@@ -176,7 +176,7 @@
                                 category = 'primary'
                         elif rschema.is_final():
                             category = 'secondary'
-                        else: 
+                        else:
                             category = 'generic'
                         cls.rcategories.set_rtag(category, rschema, role, X, Y)
 
@@ -241,13 +241,13 @@
                                                  fromeid=entity.related(rschema.type, role)[0][0])):
                         continue
             yield (rschema, targetschemas, role)
-    
+
     @classmethod
     def esrelations_by_category(cls, entity, categories=None, permission=None):
         """filter out result of relations_by_category(categories, permission) by
         removing final relations
 
-        return a sorted list of (relation's label, relation'schema, role) 
+        return a sorted list of (relation's label, relation'schema, role)
         """
         result = []
         for rschema, ttypes, role in cls.erelations_by_category(
@@ -256,9 +256,9 @@
                 continue
             result.append((rschema.display_name(entity.req, role), rschema, role))
         return sorted(result)
-    
+
     @iclassmethod
-    def field_by_name(cls_or_self, name, role='subject', eclass=None):
+    def field_by_name(cls_or_self, name, role='subject', eschema=None):
         """return field with the given name and role. If field is not explicitly
         defined for the form but `eclass` is specified, guess_field will be
         called.
@@ -266,56 +266,56 @@
         try:
             return super(AutomaticEntityForm, cls_or_self).field_by_name(name, role)
         except FieldNotFound: # XXX should raise more explicit exception
-            if eclass is None:
+            if eschema is None or not name in cls_or_self.schema:
                 raise
-            field = guess_field(eclass, cls_or_self.schema.rschema(name), role,
-                                eidparam=True)
+            rschema = cls_or_self.schema.rschema(name)
+            fieldcls = cls_or_self.rfields.etype_rtag(eschema, rschema, role)
+            if fieldcls:
+                return fieldcls(name=name, role=role, eidparam=True)
+            widget = cls_or_self.rwidgets.etype_rtag(eschema, rschema, role)
+            if widget:
+                field = guess_field(eschema, rschema, role,
+                                    eidparam=True, widget=widget)
+            else:
+                field = guess_field(eschema, rschema, role, eidparam=True)
             if field is None:
                 raise
             return field
-    
+
     def __init__(self, *args, **kwargs):
         super(AutomaticEntityForm, self).__init__(*args, **kwargs)
-        if self.edited_entity.has_eid():
-            self.edited_entity.complete()
+        entity = self.edited_entity
+        if entity.has_eid():
+            entity.complete()
         for rschema, role in self.editable_attributes():
             try:
                 self.field_by_name(rschema.type, role)
                 continue # explicitly specified
             except FieldNotFound:
-                pass # has to be guessed
-            fieldcls = self.rfields.etype_rtag(self.edited_entity.id, rschema,
-                                               role)
-            if fieldcls:
-                field = fieldcls(name=rschema.type, role=role, eidparam=True)
-                self.fields.append(field)
-                continue
-            widget = self.rwidgets.etype_rtag(self.edited_entity.id, rschema,
-                                              role)
-            if widget:
-                field = guess_field(self.edited_entity.__class__, rschema, role,
-                                    eidparam=True, widget=widget)
-            else:
-                field = guess_field(self.edited_entity.__class__, rschema, role,
-                                    eidparam=True)
-            if field is not None:
-                self.fields.append(field)
+                # has to be guessed
+                try:
+                    field = self.field_by_name(rschema.type, role,
+                                               eschema=entity.e_schema)
+                    self.fields.append(field)
+                except FieldNotFound:
+                    # meta attribute such as <attr>_format
+                    continue
         self.maxrelitems = self.req.property_value('navigation.related-limit')
         self.force_display = bool(self.req.form.get('__force_display'))
-        
+
     @property
     def related_limit(self):
         if self.force_display:
             return None
         return self.maxrelitems + 1
-    
+
     def relations_by_category(self, categories=None, permission=None):
         """return a list of (relation schema, target schemas, role) matching
         given category(ies) and permission
         """
         return self.erelations_by_category(self.edited_entity, categories,
                                            permission)
-    
+
     def inlined_relations(self):
         """return a list of (relation schema, target schemas, role) matching
         given category(ies) and permission
@@ -323,16 +323,16 @@
         # we'll need an initialized varmaker if there are some inlined relation
         self.initialize_varmaker()
         return self.erelations_by_category(self.edited_entity, True, 'add', self.rinlined)
-    
+
     def srelations_by_category(self, categories=None, permission=None):
         """filter out result of relations_by_category(categories, permission) by
         removing final relations
 
-        return a sorted list of (relation's label, relation'schema, role) 
+        return a sorted list of (relation's label, relation'schema, role)
         """
         return self.esrelations_by_category(self.edited_entity, categories,
                                            permission)
-        
+
     def action(self):
         """return the form's action attribute. Default to validateform if not
         explicitly overriden.
@@ -341,18 +341,18 @@
             return self._action
         except AttributeError:
             return self.build_url('validateform')
-        
+
     def set_action(self, value):
         """override default action"""
         self._action = value
-        
+
     action = property(action, set_action)
-    
+
     def editable_attributes(self):
         """return a list of (relation schema, role) to edit for the entity"""
         return [(rschema, x) for rschema, _, x in self.relations_by_category(
             self.attrcategories, 'add') if rschema != 'eid']
-        
+
     def relations_table(self):
         """yiels 3-tuples (rtype, target, related_list)
         where <related_list> itself a list of :
@@ -362,7 +362,7 @@
           - oneline view of related entity
         """
         entity = self.edited_entity
-        pending_deletes = self.req.get_pending_deletes(entity.eid)        
+        pending_deletes = self.req.get_pending_deletes(entity.eid)
         for label, rschema, role in self.srelations_by_category('generic', 'add'):
             relatedrset = entity.related(rschema, role, limit=self.related_limit)
             if rschema.has_perm(self.req, 'delete'):
@@ -383,7 +383,7 @@
                 eview = self.view('oneline', relatedrset, row=row)
                 related.append((nodeid, dellink, status, eview))
             yield (rschema, role, related)
-            
+
     def restore_pending_inserts(self, cell=False):
         """used to restore edition page as it was before clicking on
         'search for <some entity type>'
@@ -407,9 +407,9 @@
             if rset.description[0][0] == 'Basket':
                 eview = '%s (%s)' % (eview, display_name(self.req, 'Basket'))
             yield rtype, pendingid, jscall, label, reid, eview
-            
+
     # should_* method extracted to allow overriding
-    
+
     def should_inline_relation_form(self, rschema, targettype, role):
         """return true if the given relation with entity has role and a
         targettype target should be inlined
@@ -432,9 +432,12 @@
         """
         return not existant or card in '+*'
 
-    
+def etype_relation_field(etype, rtype, role='subject'):
+    eschema = AutomaticEntityForm.schema.eschema(etype)
+    return AutomaticEntityForm.field_by_name(rtype, role, eschema)
+
 class EditionFormView(FormViewMixIn, EntityView):
-    """display primary entity edition form"""    
+    """display primary entity edition form"""
     id = 'edition'
     # add yes() so it takes precedence over deprecated views in baseforms,
     # though not baseforms based customized view
@@ -442,11 +445,11 @@
 
     title = _('edition')
     renderer = EntityFormRenderer()
-    
+
     def cell_call(self, row, col, **kwargs):
         entity = self.complete_entity(row, col)
         self.render_form(entity)
-        
+
     def render_form(self, entity):
         """fetch and render the form"""
         self.form_title(entity)
@@ -459,37 +462,37 @@
     def init_form(self, form, entity):
         """customize your form before rendering here"""
         form.form_add_hidden(u'__maineid', entity.eid)
-        
+
     def form_title(self, entity):
         """the form view title"""
         ptitle = self.req._(self.title)
         self.w(u'<div class="formTitle"><span>%s %s</span></div>' % (
             entity.dc_type(), ptitle and '(%s)' % ptitle))
-    
+
     def submited_message(self):
         """return the message that will be displayed on successful edition"""
         return self.req._('entity edited')
 
-        
+
 class CreationFormView(EditionFormView):
-    """display primary entity creation form"""    
+    """display primary entity creation form"""
     id = 'creation'
     __select__ = specified_etype_implements('Any') & yes()
-    
+
     title = _('creation')
-    
+
     def call(self, **kwargs):
         """creation view for an entity"""
         etype = kwargs.pop('etype', self.req.form.get('etype'))
         try:
-            entity = self.vreg.etype_class(etype)(self.req, None, None)
+            entity = self.vreg.etype_class(etype)(self.req)
         except:
             self.w(self.req._('no such entity type %s') % etype)
         else:
             self.initialize_varmaker()
             entity.eid = self.varmaker.next()
             self.render_form(entity)
-    
+
     def form_title(self, entity):
         """the form view title"""
         if '__linkto' in self.req.form:
@@ -511,11 +514,11 @@
             self.w(u'<div class="formTitle notransform"><span>%s</span></div>' % msg)
         else:
             super(CreationFormView, self).form_title(entity)
-    
+
     def url(self):
         """return the url associated with this view"""
         return self.create_url(self.req.form.get('etype'))
-    
+
     def submited_message(self):
         """return the message that will be displayed on successful edition"""
         return self.req._('entity created')
@@ -524,12 +527,12 @@
 class CopyFormView(EditionFormView):
     """display primary entity creation form initialized with values from another
     entity
-    """    
+    """
     id = 'copy'
     def render_form(self, entity):
         """fetch and render the form"""
         # make a copy of entity to avoid altering the entity in the
-        # request's cache. 
+        # request's cache.
         self.newentity = copy(entity)
         self.copying = self.newentity.eid
         self.newentity.eid = None
@@ -537,24 +540,24 @@
                % self.req._('Please note that this is only a shallow copy'))
         super(CopyFormView, self).render_form(entity)
         del self.newentity
-    
+
     def init_form(self, form, entity):
         """customize your form before rendering here"""
         super(CopyFormView, self).init_form(form, entity)
         if entity.eid == self.newentity.eid:
             form.form_add_hidden('__cloned_eid', self.copying, eidparam=True)
-    
+
     def submited_message(self):
         """return the message that will be displayed on successful edition"""
         return self.req._('entity copied')
 
-    
+
 class TableEditForm(CompositeForm):
     id = 'muledit'
     onsubmit = "return validateForm('entityForm', null);"
     form_buttons = [SubmitButton(_('validate modifications on selected items')),
                     ResetButton(_('revert changes'))]
-    
+
     def __init__(self, *args, **kwargs):
         super(TableEditForm, self).__init__(*args, **kwargs)
         for row in xrange(len(self.rset)):
@@ -565,12 +568,12 @@
             form.remove_field(form.field_by_name('eid'))
             self.form_add_subform(form)
 
-        
+
 class TableEditFormView(FormViewMixIn, EntityView):
     id = 'muledit'
     __select__ = EntityView.__select__ & yes()
     title = _('multiple edit')
-    
+
     def call(self, **kwargs):
         """a view to edit multiple entities of the same type the first column
         should be the eid
@@ -584,7 +587,7 @@
     id = 'inline-edition'
     __select__ = non_final_entity() & match_kwargs('peid', 'rtype')
     removejs = "removeInlinedEntity('%s', '%s', '%s')"
-    
+
     def call(self, **kwargs):
         """redefine default call() method to avoid automatic
         insertions of <div class="section"> between each row of
@@ -604,15 +607,20 @@
         divonclick = "restoreInlinedEntity('%s', '%s', '%s')" % (peid, rtype,
                                                                  entity.eid)
         self.render_form(entity, peid, rtype, role, divonclick=divonclick)
-        
+
     def render_form(self, entity, peid, rtype, role, **kwargs):
         """fetch and render the form"""
-        rschema = self.schema.rschema(rtype)
+        form = self.vreg.select_object('forms', 'edition', self.req, None,
+                                       entity=entity, set_error_url=False)
+        self.add_hiddens(form, entity, peid, rtype, role)
         divid = '%s-%s-%s' % (peid, rtype, entity.eid)
-        title = rschema.display_name(self.req, role)
-        form = self.vreg.select_object('forms', 'edition', self.req, None,
-                                       entity=entity)
+        title = self.schema.rschema(rtype).display_name(self.req, role)
         removejs = self.removejs % (peid, rtype,entity.eid)
+        self.w(form.form_render(renderer=EntityInlinedFormRenderer(), divid=divid,
+                                title=title, removejs=removejs,**kwargs))
+
+    def add_hiddens(self, form, entity, peid, rtype, role):
+        # to ease overriding (see cubes.vcsfile.views.forms for instance)
         if self.keep_entity(entity, peid, rtype):
             if entity.has_eid():
                 rval = entity.eid
@@ -621,8 +629,6 @@
             form.form_add_hidden('edit%s-%s:%s' % (role[0], rtype, peid), rval)
         form.form_add_hidden(name='%s:%s' % (rtype, peid), value=entity.eid,
                              id='rel-%s-%s-%s'  % (peid, rtype, entity.eid))
-        self.w(form.form_render(renderer=EntityInlinedFormRenderer(), divid=divid,
-                                title=title, removejs=removejs,**kwargs))
 
     def keep_entity(self, entity, peid, rtype):
         if not entity.has_eid():
@@ -641,7 +647,8 @@
     id = 'inline-creation'
     __select__ = (match_kwargs('peid', 'rtype')
                   & specified_etype_implements('Any'))
-    
+    removejs = "removeInlineForm('%s', '%s', '%s')"
+
     def call(self, etype, peid, rtype, role='subject', **kwargs):
         """
         :param etype: the entity type being created in the inline form
--- a/web/views/editviews.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/editviews.py	Fri Apr 24 19:46:47 2009 +0200
@@ -29,7 +29,7 @@
     id = 'search-associate'
     __select__ = (one_line_rset() & match_search_state('linksearch')
                   & non_final_entity())
-    
+
     title = _('search for association')
 
     def cell_call(self, row, col):
@@ -71,7 +71,7 @@
         else:
             entity.view('outofcontext', w=self.w)
 
-        
+
 class UnrelatedDivs(EntityView):
     id = 'unrelateddivs'
     __select__ = match_form_params('relation')
@@ -121,7 +121,7 @@
         rtype = rschema.type
         form = self.vreg.select_object('forms', 'edition', self.req,
                                        entity=entity)
-        field = form.field_by_name(rschema, target, entity.__class__)
+        field = form.field_by_name(rschema, target, entity.e_schema)
         limit = self.req.property_value('navigation.combobox-limit')
         for eview, reid in form.form_field_vocabulary(field, limit):
             if reid is None:
@@ -167,7 +167,7 @@
             # edited entity
             if baskettypes & targettypes:
                 yield basketeid, basketname
-            
+
     def _get_basket_info(self, ueid):
         basketref = []
         basketrql = 'Any B,N WHERE B is Basket, B owned_by U, U eid %(x)s, B name N'
@@ -186,18 +186,18 @@
     """
     id = 'combobox'
     title = None
-    
+
     def cell_call(self, row, col):
         """the combo-box view for an entity: same as text out of context view
         by default
         """
         self.wview('textoutofcontext', self.rset, row=row, col=col)
-        
+
 
 class EditableFinalView(FinalView):
     """same as FinalView but enables inplace-edition when possible"""
     id = 'editable-final'
-                
+
     def cell_call(self, row, col, props=None, displaytime=False):
         entity, rtype = self.rset.related_entity(row, col)
         if entity is not None:
--- a/web/views/eproperties.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/eproperties.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,4 +1,4 @@
-"""Specific views for EProperty
+"""Specific views for CWProperty
 
 :organization: Logilab
 :copyright: 2007-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
@@ -45,8 +45,8 @@
     return someclass and 'class="%s"' % someclass or ''
 
 
-class EPropertyPrimaryView(baseviews.PrimaryView):
-    __select__ = implements('EProperty')
+class CWPropertyPrimaryView(baseviews.PrimaryView):
+    __select__ = implements('CWProperty')
     skip_none = False
 
 
@@ -141,7 +141,7 @@
     @property
     @cached
     def eprops_rset(self):
-        return self.req.execute('Any P,K,V WHERE P is EProperty, P pkey K, '
+        return self.req.execute('Any P,K,V WHERE P is CWProperty, P pkey K, '
                                 'P value V, NOT P for_user U')
 
     @property
@@ -156,7 +156,7 @@
         if key in values:
             entity = self.eprops_rset.get_entity(values[key], 0)
         else:
-            entity = self.vreg.etype_class('EProperty')(self.req, None, None)
+            entity = self.vreg.etype_class('CWProperty')(self.req, None, None)
             entity.eid = self.req.varmaker.next()
             entity['pkey'] = key
             entity['value'] = self.vreg.property_value(key)
@@ -216,7 +216,7 @@
     @property
     @cached
     def eprops_rset(self):
-        return self.req.execute('Any P,K,V WHERE P is EProperty, P pkey K, P value V,'
+        return self.req.execute('Any P,K,V WHERE P is CWProperty, P pkey K, P value V,'
                                 'P for_user U, U eid %(x)s', {'x': self.user.eid})
 
     def form_row(self, form, key, splitlabel):
@@ -253,7 +253,7 @@
 
 
 class PropertyKeyField(StringField):
-    """specific field for EProperty.pkey to set the value widget according to
+    """specific field for CWProperty.pkey to set the value widget according to
     the selected key
     """
     widget = Select
@@ -276,7 +276,7 @@
 
 
 class PropertyValueField(StringField):
-    """specific field for EProperty.value  which will be different according to
+    """specific field for CWProperty.value  which will be different according to
     the selected key type and vocabulary information
     """
     widget = PlaceHolderWidget
@@ -305,7 +305,7 @@
             msg = form.req._('value associated to this key is not editable '
                              'manually')
             self.widget = NotEditableWidget(entity.printable_value('value'), msg)
-        # XXX race condition when used from EPropertyForm, should not rely on
+        # XXX race condition when used from CWPropertyForm, should not rely on
         # instance attributes
         self.initial = pdef['default']
         self.help = pdef['help']
@@ -325,6 +325,6 @@
                 wdg.attrs.setdefault('size', 3)
         self.widget = wdg
 
-uicfg.rfields.set_rtag(PropertyKeyField, 'pkey', 'subject', 'EProperty')
-uicfg.rfields.set_rtag(PropertyValueField, 'value', 'subject', 'EProperty')
+uicfg.rfields.set_rtag(PropertyKeyField, 'pkey', 'subject', 'CWProperty')
+uicfg.rfields.set_rtag(PropertyValueField, 'value', 'subject', 'CWProperty')
     
--- a/web/views/euser.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/euser.py	Fri Apr 24 19:46:47 2009 +0200
@@ -14,23 +14,23 @@
 from cubicweb.web.views.baseviews import PrimaryView
 
 
-uicfg.rcategories.set_rtag('secondary', 'firstname', 'subject', 'EUser')
-uicfg.rcategories.set_rtag('secondary', 'surname', 'subject', 'EUser')
-uicfg.rcategories.set_rtag('metadata', 'last_login_time', 'subject', 'EUser')
-uicfg.rcategories.set_rtag('primary', 'in_group', 'subject', 'EUser')
-uicfg.rcategories.set_rtag('generated', 'owned_by', 'object', otype='EUser')
-uicfg.rcategories.set_rtag('generated', 'created_by', 'object', otype='EUser')
-uicfg.rcategories.set_rtag('metadata', 'bookmarked_by', 'object', otype='EUser')
-uicfg.rinlined.set_rtag(True, 'use_email', 'subject', 'EUser')
-uicfg.rmode.set_rtag('create', 'in_group', 'subject', 'EGroup')
-uicfg.rmode.set_rtag('link', 'owned_by', 'object', 'EUser')
-uicfg.rmode.set_rtag('link', 'created_by', 'object', 'EUser')
-uicfg.rmode.set_rtag('create', 'bookmarked_by', 'object', 'EUser')
+uicfg.rcategories.set_rtag('secondary', 'firstname', 'subject', 'CWUser')
+uicfg.rcategories.set_rtag('secondary', 'surname', 'subject', 'CWUser')
+uicfg.rcategories.set_rtag('metadata', 'last_login_time', 'subject', 'CWUser')
+uicfg.rcategories.set_rtag('primary', 'in_group', 'subject', 'CWUser')
+uicfg.rcategories.set_rtag('generated', 'owned_by', 'object', otype='CWUser')
+uicfg.rcategories.set_rtag('generated', 'created_by', 'object', otype='CWUser')
+uicfg.rcategories.set_rtag('metadata', 'bookmarked_by', 'object', otype='CWUser')
+uicfg.rinlined.set_rtag(True, 'use_email', 'subject', 'CWUser')
+uicfg.rmode.set_rtag('create', 'in_group', 'subject', 'CWGroup')
+uicfg.rmode.set_rtag('link', 'owned_by', 'object', 'CWUser')
+uicfg.rmode.set_rtag('link', 'created_by', 'object', 'CWUser')
+uicfg.rmode.set_rtag('create', 'bookmarked_by', 'object', 'CWUser')
     
 
 class UserPreferencesEntityAction(action.Action):
     id = 'prefs'
-    __select__ = (one_line_rset() & implements('EUser') &
+    __select__ = (one_line_rset() & implements('CWUser') &
                   match_user_groups('owners', 'managers'))
     
     title = _('preferences')
@@ -41,14 +41,14 @@
         return self.build_url('euser/%s'%login, vid='epropertiesform')
 
 
-class EUserPrimaryView(PrimaryView):
-    __select__ = implements('EUser')
+class CWUserPrimaryView(PrimaryView):
+    __select__ = implements('CWUser')
     
     skip_attrs = ('firstname', 'surname')
     
     def iter_relations(self, entity):
         # don't want to display user's entities
-        for rschema, targetschemas, x in super(EUserPrimaryView, self).iter_relations(entity):
+        for rschema, targetschemas, x in super(CWUserPrimaryView, self).iter_relations(entity):
             if x == 'object' and rschema.type in ('owned_by', 'for_user'):
                 continue
             yield rschema, targetschemas, x
@@ -63,7 +63,7 @@
                                  ]
 class FoafView(EntityView):
     id = 'foaf'
-    __select__ = implements('EUser')
+    __select__ = implements('CWUser')
     
     title = _('foaf')
     templatable = False
@@ -96,3 +96,6 @@
         if emailaddr:
             self.w(u'<foaf:mbox>%s</foaf:mbox>\n' % html_escape(emailaddr))
         self.w(u'</foaf:Person>\n')
+
+from logilab.common.deprecation import class_renamed
+EUserPrimaryView = class_renamed('EUserPrimaryView', CWUserPrimaryView)
--- a/web/views/iprogress.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/iprogress.py	Fri Apr 24 19:46:47 2009 +0200
@@ -131,7 +131,7 @@
             else:
                 formated_date = u'%s %s' % (_('expected:'), eta_date)
         return formated_date
-    
+
     def build_todo_by_cell(self, entity):
         """``todo_by`` column cell renderer"""
         return u', '.join(p.view('outofcontext') for p in entity.contractors())
--- a/web/views/magicsearch.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/magicsearch.py	Fri Apr 24 19:46:47 2009 +0200
@@ -41,7 +41,7 @@
     :param translations: the reverted l10n dict
 
     :type schema: `cubicweb.schema.Schema`
-    :param schema: the application's schema    
+    :param schema: the application's schema
     """
     # var_types is used as a map : var_name / var_type
     vartypes = {}
@@ -107,7 +107,7 @@
         if rtype is None:
             continue
         relation.r_type = rtype
-    
+
 
 
 QUOTED_SRE = re.compile(r'(.*?)(["\'])(.+?)\2')
@@ -145,7 +145,7 @@
             return req.execute(*args)
         finally:
             # rollback necessary to avoid leaving the connection in a bad state
-            req.cnx.rollback() 
+            req.cnx.rollback()
 
     def preprocess_query(self, uquery, req):
         raise NotImplementedError()
@@ -161,10 +161,10 @@
     priority = 0
     def preprocess_query(self, uquery, req):
         return uquery,
-    
+
 
 class QueryTranslator(BaseQueryProcessor):
-    """ parses through rql and translates into schema language entity names 
+    """ parses through rql and translates into schema language entity names
     and attributes
     """
     priority = 2
@@ -185,7 +185,7 @@
     preprocessing query in shortcut form to their RQL form
     """
     priority = 4
-    
+
     def preprocess_query(self, uquery, req):
         """try to get rql from an unicode query string"""
         args = None
@@ -193,7 +193,7 @@
         try:
             # Process as if there was a quoted part
             args = self._quoted_words_query(uquery)
-        ## No quoted part  
+        ## No quoted part
         except BadRQLQuery:
             words = uquery.split()
             if len(words) == 1:
@@ -205,7 +205,7 @@
             else:
                 args = self._multiple_words_query(words)
         return args
-    
+
     def _get_entity_type(self, word):
         """check if the given word is matching an entity type, return it if
         it's the case or raise BadRQLQuery if not
@@ -214,7 +214,7 @@
         try:
             return trmap(self.config, self.vreg.schema, self.req.lang)[etype]
         except KeyError:
-            raise BadRQLQuery('%s is not a valid entity name' % etype)        
+            raise BadRQLQuery('%s is not a valid entity name' % etype)
 
     def _get_attribute_name(self, word, eschema):
         """check if the given word is matching an attribute of the given entity type,
@@ -261,7 +261,7 @@
         if var is None:
             var = etype[0]
         return '%s %s %s%%(text)s' % (var, searchattr, searchop)
-        
+
     def _two_words_query(self, word1, word2):
         """Specific process for two words query (case (2) of preprocess_rql)
         """
@@ -272,7 +272,7 @@
         # else, suppose it's a shortcut like : Person Smith
         rql = '%s %s WHERE %s' % (etype, etype[0], self._complete_rql(word2, etype))
         return rql, {'text': word2}
-           
+
     def _three_words_query(self, word1, word2, word3):
         """Specific process for three words query (case (3) of preprocess_rql)
         """
@@ -336,13 +336,13 @@
             return self._three_words_query(word1, word2, quoted_part)
             # return ori_rql
         raise BadRQLQuery("unable to handle request %r" % ori_rql)
-    
+
 
- 
+
 class FullTextTranslator(BaseQueryProcessor):
     priority = 10
     name = 'text'
-    
+
     def preprocess_query(self, uquery, req):
         """suppose it's a plain text query"""
         return 'Any X WHERE X has_text %(text)s', {'text': uquery}
--- a/web/views/management.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/management.py	Fri Apr 24 19:46:47 2009 +0200
@@ -1,4 +1,4 @@
-"""management and error screens
+"""security management and error screens
 
 
 :organization: Logilab
@@ -12,27 +12,16 @@
 from cubicweb.selectors import yes, none_rset, match_user_groups
 from cubicweb.view import AnyRsetView, StartupView, EntityView
 from cubicweb.common.uilib import html_traceback, rest_traceback
-from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param, stdmsgs
-from cubicweb.web.widgets import StaticComboBoxWidget
+from cubicweb.web import formwidgets
+from cubicweb.web.form import FieldsForm, EntityFieldsForm
+from cubicweb.web.formfields import guess_field
+from cubicweb.web.formrenderers import HTableFormRenderer
 
 _ = unicode
 
 SUBMIT_MSGID = _('Submit bug report')
 MAIL_SUBMIT_MSGID = _('Submit bug report by mail')
 
-def begin_form(w, entity, redirectvid, redirectpath=None, msg=None):
-    w(u'<form method="post" action="%s">\n' % entity.req.build_url('edit'))
-    w(u'<fieldset>\n')
-    w(u'<input type="hidden" name="__redirectvid" value="%s"/>\n' % redirectvid)
-    w(u'<input type="hidden" name="__redirectpath" value="%s"/>\n' % (
-        html_escape(redirectpath or entity.rest_path())))
-    w(u'<input type="hidden" name="eid" value="%s"/>\n' % entity.eid)
-    w(u'<input type="hidden" name="%s" value="%s"/>\n' % (
-        eid_param('__type', entity.eid), entity.e_schema))
-    if msg:
-        w(u'<input type="hidden" name="__message" value="%s"/>\n'
-          % html_escape(msg))
-
 
 class SecurityManagementView(EntityView):
     """display security information for a given entity"""
@@ -89,15 +78,14 @@
 
     def owned_by_edit_form(self, entity):
         self.w('<h3>%s</h3>' % self.req._('ownership'))
-        begin_form(self.w, entity, 'security', msg= _('ownerships have been changed'))
-        self.w(u'<table border="0">\n')
-        self.w(u'<tr><td>\n')
-        wdg = entity.get_widget('owned_by')
-        self.w(wdg.edit_render(entity))
-        self.w(u'</td><td>\n')
-        self.w(self.button_ok())
-        self.w(u'</td></tr>\n</table>\n')
-        self.w(u'</fieldset></form>\n')
+        msg = self.req._('ownerships have been changed')
+        form = EntityFieldsForm(self.req, None, entity=entity, submitmsg=msg,
+                                form_buttons=[formwidgets.SubmitButton()],
+                                __redirectvid='security',
+                                __redirectpath=entity.rest_path())
+        field = guess_field(entity.e_schema, self.schema.rschema('owned_by'))
+        form.append_field(field)
+        self.w(form.form_render())
 
     def owned_by_information(self, entity):
         ownersrset = entity.related('owned_by')
@@ -144,35 +132,28 @@
     def require_permission_edit_form(self, entity):
         w = self.w
         _ = self.req._
-        newperm = self.vreg.etype_class('EPermission')(self.req, None)
+        newperm = self.vreg.etype_class('CWPermission')(self.req, None)
         newperm.eid = self.req.varmaker.next()
         w(u'<p>%s</p>' % _('add a new permission'))
-        begin_form(w, newperm, 'security', entity.rest_path())
-        w(u'<input type="hidden" name="%s" value="%s"/>'
-          % (eid_param('edito-require_permission', newperm.eid), INTERNAL_FIELD_VALUE))
-        w(u'<input type="hidden" name="%s" value="%s"/>'
-          % (eid_param('require_permission', newperm.eid), entity.eid))
-        w(u'<table border="0">\n')
-        w(u'<tr><th>%s</th><th>%s</th><th>%s</th><th>&nbsp;</th></tr>\n'
-               % (_("name"), _("label"), _('granted to groups')))
-        if getattr(entity, '__permissions__', None):
-            wdg = StaticComboBoxWidget(self.vreg, self.schema['EPermission'],
-                                       self.schema['name'], self.schema['String'],
-                                       vocabfunc=lambda x: entity.__permissions__)
+        form = EntityFieldsForm(self.req, None, entity=newperm,
+                                form_buttons=[formwidgets.SubmitButton()],
+                                __redirectvid='security',
+                                __redirectpath=entity.rest_path())
+        form.form_add_hidden('require_permission', entity.eid, role='object', eidparam=True)
+        permnames = getattr(entity, '__permissions__', None)
+        cwpermschema = newperm.e_schema
+        if permnames is not None:
+            field = guess_field(cwpermschema, self.schema.rschema('name'),
+                                widget=formwidgets.Select, choices=permnames)
         else:
-            wdg = newperm.get_widget('name')
-        w(u'<tr><td>%s</td>\n' % wdg.edit_render(newperm))
-        wdg = newperm.get_widget('label')
-        w(u'<td>%s</td>\n' % wdg.edit_render(newperm))
-        wdg = newperm.get_widget('require_group')
-        w(u'<td>%s</td>\n' % wdg.edit_render(newperm))
-        w(u'<td>%s</td></tr>\n' % self.button_ok())
-        w(u'</table>')
-        w(u'</fieldset></form>\n')
+            field = guess_field(cwpermschema, self.schema.rschema('name'))
+        form.append_field(field)
+        field = guess_field(cwpermschema, self.schema.rschema('label'))
+        form.append_field(field)
+        field = guess_field(cwpermschema, self.schema.rschema('require_group'))
+        form.append_field(field)
+        self.w(form.form_render(renderer=HTableFormRenderer()))
 
-    def button_ok(self):
-        return (u'<input class="validateButton" type="submit" name="submit" value="%s"/>'
-                % self.req._(stdmsgs.BUTTON_OK))
 
 
 class ErrorView(AnyRsetView):
@@ -233,12 +214,12 @@
             form.form_add_hidden('description', binfo)
             form.form_add_hidden('__bugreporting', '1')
             if submitmail:
-                form.form_buttons = [SubmitButton(MAIL_SUBMIT_MSGID)]
+                form.form_buttons = [formwidgets.SubmitButton(MAIL_SUBMIT_MSGID)]
                 form.action = req.build_url('reportbug')
                 w(form.form_render())
             if submiturl:
                 form.form_add_hidden('description_format', 'text/rest')
-                form.form_buttons = [SubmitButton(SUBMIT_MSGID)]
+                form.form_buttons = [formwidgets.SubmitButton(SUBMIT_MSGID)]
                 form.action = submiturl
                 w(form.form_render())
 
@@ -268,7 +249,7 @@
 class ProcessInformationView(StartupView):
     id = 'info'
     __select__ = none_rset() & match_user_groups('managers')
-    
+
     title = _('server information')
 
     def call(self, **kwargs):
--- a/web/views/massmailing.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/massmailing.py	Fri Apr 24 19:46:47 2009 +0200
@@ -34,33 +34,33 @@
         return self.build_url(self.req.relative_path(includeparams=False),
                               **params)
 
-            
+
 class MassMailingForm(FieldsForm):
     id = 'massmailing'
-    
+
     sender = StringField(widget=TextInput({'disabled': 'disabled'}), label=_('From:'))
     recipient = StringField(widget=CheckBox(), label=_('Recipients:'))
     subject = StringField(label=_('Subject:'))
     mailbody = StringField(widget=AjaxWidget(wdgtype='TemplateTextField',
-                                             inputid='mailarea'))
-    form_buttons = [ImgButton('sendbutton', "javascript: $('sendmail').submit()",
+                                             inputid='mailbody'))
+    form_buttons = [ImgButton('sendbutton', "javascript: $('#sendmail').submit()",
                               _('send email'), 'SEND_EMAIL_ICON'),
                     ImgButton('cancelbutton', "javascript: history.back()",
-                              stdmsgs.BUTTON_CANCEL, 'CANCEL_EMAIL_ICON')]                    
-                              
+                              stdmsgs.BUTTON_CANCEL, 'CANCEL_EMAIL_ICON')]
+
     def form_field_vocabulary(self, field):
         if field.name == 'recipient':
             vocab = [(entity.get_email(), entity.eid) for entity in self.rset.entities()]
             return [(label, value) for label, value in vocab if label]
         return super(MassMailingForm, self).form_field_vocabulary(field)
-    
+
     def form_field_value(self, field, values):
         if field.name == 'recipient':
             return [entity.eid for entity in self.rset.entities() if entity.get_email()]
         elif field.name == 'mailbody':
-            field.widget.attrs['cubicweb:variables'] = self.get_allowed_substitutions()
+            field.widget.attrs['cubicweb:variables'] = ','.join(self.get_allowed_substitutions())
         return super(MassMailingForm, self).form_field_value(field, values)
-    
+
     def get_allowed_substitutions(self):
         attrs = []
         for coltype in self.rset.column_types(0):
@@ -79,12 +79,13 @@
 
 class MassMailingFormRenderer(FormRenderer):
     button_bar_class = u'toolbar'
-    
-    def _render_fields(self, fields, w, form, values):
+
+    def _render_fields(self, fields, w, form):
         w(u'<table class="headersform">')
         for field in fields:
             if field.name == 'mailbody':
                 w(u'</table>')
+                self._render_toolbar(w, form)
                 w(u'<table>')
                 w(u'<tr><td><div>')
             else:
@@ -100,7 +101,17 @@
                 w(u'</td></tr>')
         w(u'</table>')
 
-    
+    def _render_toolbar(self, w, form):
+        w(u'<div id="toolbar">')
+        w(u'<ul>')
+        for button in form.form_buttons:
+            w(u'<li>%s</li>' % button.render(form))
+        w(u'</ul>')
+        w(u'</div>')
+
+    def render_buttons(self, w, form):
+        pass
+
 class MassMailingFormView(FormViewMixIn, EntityView):
     id = 'massmailing'
     __select__ = implements(IEmailable) & match_user_groups('managers', 'users')
@@ -113,6 +124,3 @@
         form = self.vreg.select_object('forms', 'massmailing', self.req, self.rset,
                                        action='sendmail', domid='sendmail')
         self.w(form.form_render(sender=from_addr, renderer=MassMailingFormRenderer()))
-
-
-    
--- a/web/views/schema.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/schema.py	Fri Apr 24 19:46:47 2009 +0200
@@ -22,19 +22,19 @@
 from cubicweb.web.views.boxes import EditBox
 
 
-AutomaticEntityForm.rcategories.set_rtag('primary', 'require_group', 'subject', 'EPermission')
+AutomaticEntityForm.rcategories.set_rtag('primary', 'require_group', 'subject', 'CWPermission')
 AutomaticEntityForm.rcategories.set_rtag('generated', 'final', 'subject', 'EEtype')
 AutomaticEntityForm.rcategories.set_rtag('generated', 'final', 'subject', 'ERtype')
-AutomaticEntityForm.rinlined.set_rtag(True, 'relation_type', 'subject', 'ENFRDef')
-AutomaticEntityForm.rinlined.set_rtag(True, 'from_entity', 'subject', 'ENFRDef')
-AutomaticEntityForm.rinlined.set_rtag(True, 'to_entity', 'subject', 'ENFRDef')
+AutomaticEntityForm.rinlined.set_rtag(True, 'relation_type', 'subject', 'CWRelation')
+AutomaticEntityForm.rinlined.set_rtag(True, 'from_entity', 'subject', 'CWRelation')
+AutomaticEntityForm.rinlined.set_rtag(True, 'to_entity', 'subject', 'CWRelation')
 AutomaticEntityForm.rwidgets.set_rtag('StringWidget', 'expression', 'subject', 'RQLExpression')
 
-EditBox.rmode.set_rtag('create', 'state_of', 'object', 'EEType')
-EditBox.rmode.set_rtag('create', 'transition_of', 'object', 'EEType')
-EditBox.rmode.set_rtag('create', 'relation_type', 'object', 'ERType')
-EditBox.rmode.set_rtag('link', 'from_entity', 'object', 'EEType')
-EditBox.rmode.set_rtag('link', 'to_entity', 'object', 'EEType')
+EditBox.rmode.set_rtag('create', 'state_of', 'object', 'CWEType')
+EditBox.rmode.set_rtag('create', 'transition_of', 'object', 'CWEType')
+EditBox.rmode.set_rtag('create', 'relation_type', 'object', 'CWRType')
+EditBox.rmode.set_rtag('link', 'from_entity', 'object', 'CWEType')
+EditBox.rmode.set_rtag('link', 'to_entity', 'object', 'CWEType')
 
 
 class ViewSchemaAction(Action):
@@ -58,35 +58,35 @@
     def content_title(self, entity):
         return html_escape(entity.dc_long_title())
     
-class EETypePrimaryView(_SchemaEntityPrimaryView):
-    __select__ = implements('EEType')
+class CWETypePrimaryView(_SchemaEntityPrimaryView):
+    __select__ = implements('CWEType')
     skip_attrs = _SchemaEntityPrimaryView.skip_attrs + ('name', 'meta', 'final')
 
-class ERTypePrimaryView(_SchemaEntityPrimaryView):
-    __select__ = implements('ERType')
+class CWRTypePrimaryView(_SchemaEntityPrimaryView):
+    __select__ = implements('CWRType')
     skip_attrs = _SchemaEntityPrimaryView.skip_attrs + ('name', 'meta', 'final',
                                                         'symetric', 'inlined')
 
 class ErdefPrimaryView(_SchemaEntityPrimaryView):
-    __select__ = implements('EFRDef', 'ENFRDef')
+    __select__ = implements('CWAttribute', 'CWRelation')
     show_attr_label = True
 
-class EETypeOneLineView(baseviews.OneLineView):
-    __select__ = implements('EEType')
+class CWETypeOneLineView(baseviews.OneLineView):
+    __select__ = implements('CWEType')
     
     def cell_call(self, row, col, **kwargs):
         entity = self.entity(row, col)
         final = entity.final
         if final:
             self.w(u'<em class="finalentity">')
-        super(EETypeOneLineView, self).cell_call(row, col, **kwargs)
+        super(CWETypeOneLineView, self).cell_call(row, col, **kwargs)
         if final:
             self.w(u'</em>')
 
 
 # in memory schema views (yams class instances) ###############################
 
-class EETypeSchemaView(EETypePrimaryView):
+class CWETypeSchemaView(CWETypePrimaryView):
     id = 'eschema'
     title = _('in memory entity schema')
     main_related_section = False
@@ -94,7 +94,7 @@
                  'has_text',)
     
     def render_entity_attributes(self, entity, siderelations):
-        super(EETypeSchemaView, self).render_entity_attributes(entity, siderelations)
+        super(CWETypeSchemaView, self).render_entity_attributes(entity, siderelations)
         eschema = self.vreg.schema.eschema(entity.name)
         viewer = SchemaViewer(self.req)
         layout = viewer.visit_entityschema(eschema, skiprels=self.skip_rels)
@@ -105,13 +105,13 @@
                 html_escape(self.req._('graphical schema for %s') % entity.name)))
 
 
-class ERTypeSchemaView(ERTypePrimaryView):
+class CWRTypeSchemaView(CWRTypePrimaryView):
     id = 'eschema'
     title = _('in memory relation schema')
     main_related_section = False
 
     def render_entity_attributes(self, entity, siderelations):
-        super(ERTypeSchemaView, self).render_entity_attributes(entity, siderelations)
+        super(CWRTypeSchemaView, self).render_entity_attributes(entity, siderelations)
         rschema = self.vreg.schema.rschema(entity.name)
         viewer = SchemaViewer(self.req)
         layout = viewer.visit_relationschema(rschema)
@@ -125,7 +125,7 @@
 # schema images ###############################################################
 
 class ImageView(EntityView):
-    __select__ = implements('EEType')
+    __select__ = implements('CWEType')
     id = 'image'
     title = _('image')
 
@@ -210,10 +210,10 @@
         s2d.schema2dot(outputfile=tmpfile, visitor=visitor,
                        prophdlr=RestrictedSchemaDotPropsHandler(self.req))
 
-class EETypeSchemaImageView(TmpFileViewMixin, EntityView):
+class CWETypeSchemaImageView(TmpFileViewMixin, EntityView):
     id = 'eschemagraph'
     content_type = 'image/png'
-    __select__ = implements('EEType')
+    __select__ = implements('CWEType')
     skip_rels = ('owned_by', 'created_by', 'identity', 'is', 'is_instance_of')
     
     def _generate(self, tmpfile):
@@ -224,8 +224,8 @@
         s2d.schema2dot(outputfile=tmpfile, visitor=visitor,
                        prophdlr=RestrictedSchemaDotPropsHandler(self.req))
 
-class ERTypeSchemaImageView(EETypeSchemaImageView):
-    __select__ = implements('ERType')
+class CWRTypeSchemaImageView(CWETypeSchemaImageView):
+    __select__ = implements('CWRType')
     
     def _generate(self, tmpfile):
         """display schema information for an entity"""
--- a/web/views/startup.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/startup.py	Fri Apr 24 19:46:47 2009 +0200
@@ -92,7 +92,7 @@
             self.w(u'<tr><th colspan="4">%s</th></tr>\n' % self.req._('system entities'))
             self.entity_types_table(eschema for eschema in schema.entities()
                                     if eschema.meta and not eschema.schema_entity())
-            if 'EFRDef' in schema: # check schema support
+            if 'CWAttribute' in schema: # check schema support
                 self.w(u'<tr><th colspan="4">%s</th></tr>\n' % self.req._('schema entities'))
                 self.entity_types_table(schema.eschema(etype)
                                         for etype in schema.schema_entity_types())
--- a/web/views/tabs.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/tabs.py	Fri Apr 24 19:46:47 2009 +0200
@@ -92,19 +92,25 @@
         return selected_tabs
 
     def render_tabs(self, tabs, default, entity):
+        # tabbed views do no support concatenation
+        # hence we delegate to the default tab if there is more than on entity
+        # in the result set
+        if len(self.rset) > 1:
+            entity.view(default, w=self.w)
+            return
+        # XXX (syt) fix below add been introduced at some point to fix something
+        # (http://intranet.logilab.fr/jpl/ticket/32174 ?) but this is not a clean
+        # way. We must not consider form['rql'] here since it introduces some
+        # other failures on non rql queries (plain text, shortcuts,... handled by
+        # magicsearch) which has a single result whose primary view is using tabs
+        # (https://www.logilab.net/cwo/ticket/342789)
+        #rql = self.req.form.get('rql')
+        #if rql:
+        #    self.req.execute(rql).get_entity(0,0).view(default, w=self.w)
+        #    return
         self.req.add_css('ui.tabs.css')
         self.req.add_js(('ui.core.js', 'ui.tabs.js',
                          'cubicweb.ajax.js', 'cubicweb.tabs.js', 'cubicweb.lazy.js'))
-        # tabbed views do no support concatenation
-        # hence we delegate to the default tab
-        form = self.req.form
-        if form.get('vid') == 'primary':
-            entity.view(default, w=self.w)
-            return
-        rql = form.get('rql')
-        if rql:
-            self.req.execute(rql).get_entity(0,0).view(default, w=self.w)
-            return
         # prune tabs : not all are to be shown
         tabs = self.prune_tabs(tabs)
         # select a tab
--- a/web/views/urlrewrite.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/urlrewrite.py	Fri Apr 24 19:46:47 2009 +0200
@@ -7,7 +7,6 @@
 import re
 
 from cubicweb.appobject import AppObject
-from cubicweb.common.registerers import accepts_registerer
 
 
 def rgx(pattern, flags=0):
@@ -53,7 +52,6 @@
     """
     __metaclass__ = metarewriter
     __registry__ = 'urlrewriting'
-    __registerer__ = accepts_registerer
     __abstract__ = True
 
     id = 'urlrewriting'
@@ -80,14 +78,14 @@
         ('/manage', dict(vid='manage')),
         ('/notfound', dict(vid='404')),
         ('/error', dict(vid='error')),
-        (rgx('/schema/([^/]+?)/?'),  dict(vid='eschema', rql=r'Any X WHERE X is EEType, X name "\1"')),
+        (rgx('/schema/([^/]+?)/?'),  dict(vid='eschema', rql=r'Any X WHERE X is CWEType, X name "\1"')),
         (rgx('/add/([^/]+?)/?'), dict(vid='creation', etype=r'\1')),
         (rgx('/doc/images/(.+?)/?'), dict(vid='wdocimages', fid=r'\1')),
         (rgx('/doc/?'), dict(vid='wdoc', fid=r'main')),
         (rgx('/doc/(.+?)/?'), dict(vid='wdoc', fid=r'\1')),
         (rgx('/changelog/?'), dict(vid='changelog')),
         ]
-    
+
     def rewrite(self, req, uri):
         """for each `input`, `output `in rules, if `uri` matches `input`,
         req's form is updated with `output`
@@ -181,7 +179,7 @@
     rules = [
         # rgxp : callback
         (rgx('/search/(.+)'), build_rset(rql=r'Any X WHERE X has_text %(text)s',
-                                         rgxgroups=[('text', 1)])), 
+                                         rgxgroups=[('text', 1)])),
         ]
 
     def rewrite(self, req, uri):
--- a/web/views/vcard.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/vcard.py	Fri Apr 24 19:46:47 2009 +0200
@@ -13,13 +13,13 @@
 
 VCARD_PHONE_TYPES = {'home': 'HOME', 'office': 'WORK', 'mobile': 'CELL', 'fax': 'FAX'}
 
-class VCardEUserView(EntityView):
+class VCardCWUserView(EntityView):
     """export a person information as a vcard"""
     id = 'vcard'
     title = _('vcard')
     templatable = False
     content_type = 'text/x-vcard'
-    __select__ = implements('EUser')        
+    __select__ = implements('CWUser')        
 
     def set_request_content_type(self):
         """overriden to set a .vcf filename"""
@@ -49,4 +49,4 @@
             w(u'EMAIL;TYPE=INTERNET:%s\n' % email.address)
 
 from logilab.common.deprecation import class_renamed
-VCardEuserView = class_renamed('VCardEuserView', VCardEUserView)
+VCardEuserView = VCardEUserView = class_renamed('VCardEuserView', VCardCWUserView)
--- a/web/views/workflow.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/workflow.py	Fri Apr 24 19:46:47 2009 +0200
@@ -86,12 +86,12 @@
         rql = ' ORDERBY D DESC WHERE WF wf_info_for X,'\
               'WF from_state FS, WF to_state TS, WF comment C,'\
               'WF creation_date D'
-        if self.vreg.schema.eschema('EUser').has_perm(self.req, 'read'):
+        if self.vreg.schema.eschema('CWUser').has_perm(self.req, 'read'):
             sel += ',U,C'
             rql += ', WF owned_by U?'
             displaycols = range(5)
             headers = (_('from_state'), _('to_state'), _('comment'), _('date'),
-                       _('EUser'))            
+                       _('CWUser'))            
         else:
             sel += ',C'
             displaycols = range(4)
@@ -130,7 +130,7 @@
         
 class ViewWorkflowAction(action.Action):
     id = 'workflow'
-    __select__ = implements('EEType') & has_related_entities('state_of', 'object')
+    __select__ = implements('CWEType') & has_related_entities('state_of', 'object')
     
     category = 'mainactions'
     title = _('view workflow')
@@ -139,9 +139,9 @@
         return entity.absolute_url(vid='workflow')
 
         
-class EETypeWorkflowView(view.EntityView):
+class CWETypeWorkflowView(view.EntityView):
     id = 'workflow'
-    __select__ = implements('EEType')
+    __select__ = implements('CWEType')
     cache_max_age = 60*60*2 # stay in http cache for 2 hours by default 
     
     def cell_call(self, row, col, **kwargs):
@@ -205,10 +205,10 @@
             yield transition.eid, transition.destination().eid, transition
 
 
-class EETypeWorkflowImageView(TmpFileViewMixin, view.EntityView):
+class CWETypeWorkflowImageView(TmpFileViewMixin, view.EntityView):
     id = 'ewfgraph'
     content_type = 'image/png'
-    __select__ = implements('EEType')
+    __select__ = implements('CWEType')
     
     def _generate(self, tmpfile):
         """display schema information for an entity"""
--- a/web/views/xmlrss.py	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/views/xmlrss.py	Fri Apr 24 19:46:47 2009 +0200
@@ -30,10 +30,10 @@
     content_type = 'text/xml'
     xml_root = 'rset'
     item_vid = 'xmlitem'
-    
+
     def cell_call(self, row, col):
         self.wview(self.item_vid, self.rset, row=row, col=col)
-        
+
     def call(self):
         """display a list of entities by calling their <item_vid> view"""
         self.w(u'<?xml version="1.0" encoding="%s"?>\n' % self.req.encoding)
@@ -66,7 +66,7 @@
                 self.w(u'  <%s>%s</%s>\n' % (attr, value, attr))
         self.w(u'</%s>\n' % (entity.e_schema))
 
-    
+
 class XmlRsetView(AnyRsetView):
     """dumps raw rset as xml"""
     id = 'rsetxml'
@@ -74,7 +74,7 @@
     templatable = False
     content_type = 'text/xml'
     xml_root = 'rset'
-        
+
     def call(self):
         w = self.w
         rset, descr = self.rset, self.rset.description
@@ -103,13 +103,13 @@
             w(u' </row>\n')
         w(u'</%s>\n' % self.xml_root)
 
-    
+
 # RSS stuff ###################################################################
 
 class RSSFeedURL(Component):
     id = 'rss_feed_url'
     __select__ = non_final_entity()
-    
+
     def feed_url(self):
         return self.build_url(rql=self.limited_rql(), vid='rss')
 
@@ -117,20 +117,20 @@
 class RSSEntityFeedURL(Component):
     id = 'rss_feed_url'
     __select__ = non_final_entity() & one_line_rset()
-    
+
     def feed_url(self):
         return self.entity(0, 0).rss_feed_url()
 
-        
+
 class RSSIconBox(BoxTemplate):
     """just display the RSS icon on uniform result set"""
     id = 'rss'
     __select__ = (BoxTemplate.__select__
                   & appobject_selectable('components', 'rss_feed_url'))
-    
+
     visible = False
     order = 999
-    
+
     def call(self, **kwargs):
         try:
             rss = self.req.external_resource('RSS_LOGO')
@@ -148,58 +148,57 @@
     templatable = False
     content_type = 'text/xml'
     http_cache_manager = MaxAgeHTTPCacheManager
-    cache_max_age = 60*60*2 # stay in http cache for 2 hours by default 
-    
-    def cell_call(self, row, col):
-        self.wview('rssitem', self.rset, row=row, col=col)
-        
-    def call(self):
-        """display a list of entities by calling their <item_vid> view"""
+    cache_max_age = 60*60*2 # stay in http cache for 2 hours by default
+
+    def _open(self):
         req = self.req
         self.w(u'<?xml version="1.0" encoding="%s"?>\n' % req.encoding)
-        self.w(u'''<rdf:RDF
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns="http://purl.org/rss/1.0/"
->''')
-        self.w(u'  <channel rdf:about="%s">\n' % xml_escape(req.url()))
-        self.w(u'    <title>%s RSS Feed</title>\n' % xml_escape(self.page_title()))
-        self.w(u'    <description>%s</description>\n' % xml_escape(req.form.get('vtitle', '')))
+        self.w(u'<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">\n')
+        self.w(u'  <channel>\n')
+        self.w(u'    <title>%s RSS Feed</title>\n' % html_escape(self.page_title()))
+        self.w(u'    <description>%s</description>\n' % html_escape(req.form.get('vtitle', '')))
         params = req.form.copy()
         params.pop('vid', None)
-        self.w(u'    <link>%s</link>\n' % xml_escape(self.build_url(**params)))
-        self.w(u'    <items>\n')
-        self.w(u'      <rdf:Seq>\n')
-        for entity in self.rset.entities():
-            self.w(u'      <rdf:li resource="%s" />\n' % xml_escape(entity.absolute_url()))
-        self.w(u'      </rdf:Seq>\n')
-        self.w(u'    </items>\n')
+        self.w(u'    <link>%s</link>\n' % html_escape(self.build_url(**params)))
+
+    def _close(self):
         self.w(u'  </channel>\n')
+        self.w(u'</rss>')
+
+    def call(self):
+        """display a list of entities by calling their <item_vid> view"""
+        self._open()
         for i in xrange(self.rset.rowcount):
             self.cell_call(i, 0)
-        self.w(u'</rdf:RDF>')
+        self._close()
 
+    def cell_call(self, row, col):
+        self.wview('rssitem', self.rset, row=row, col=col)
 
 class RssItemView(EntityView):
     id = 'rssitem'
     date_format = '%%Y-%%m-%%dT%%H:%%M%+03i:00' % (timezone / 3600)
+    add_div_section = False
 
     def cell_call(self, row, col):
         entity = self.complete_entity(row, col)
-        self.w(u'<item rdf:about="%s">\n' % xml_escape(entity.absolute_url()))
+        self.w(u'<item>\n')
+        self.w(u'<guid isPermaLink="true">%s</guid>\n' % html_escape(entity.absolute_url()))
+        self.render_title_link(entity)
+        self._marker('description', html_escape(entity.dc_description()))
+        self._marker('dc:date', entity.dc_date(self.date_format))
+        self.render_entity_creator(entity)
+        self.w(u'</item>\n')
+
+    def render_title_link(self, entity):
         self._marker('title', entity.dc_long_title())
         self._marker('link', entity.absolute_url())
-        self._marker('description', entity.dc_description())
-        self._marker('dc:date', entity.dc_date(self.date_format))
+
+    def render_entity_creator(self, entity):
         if entity.creator:
-            self.w(u'<author>')
-            self._marker('name', entity.creator.name())
-            email = entity.creator.get_email()
-            if email:
-                self._marker('email', email)
-            self.w(u'</author>')
-        self.w(u'</item>\n')
-        
+            self._marker('dc:creator', entity.dc_creator())
+
+
     def _marker(self, marker, value):
         if value:
-            self.w(u'  <%s>%s</%s>\n' % (marker, xml_escape(value), marker))
+            self.w(u'  <%s>%s</%s>\n' % (marker, html_escape(value), marker))
--- a/web/wdoc/tut_rql_en.rst	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/wdoc/tut_rql_en.rst	Fri Apr 24 19:46:47 2009 +0200
@@ -127,16 +127,16 @@
 * `creation_date (Datetime)`, date on which the entity has been created
 * `modification_date (Datetime)`, lastest date on which the entity has been modified
 
-* `created_by (EUser)`, relation to the user which has created this entity
+* `created_by (CWUser)`, relation to the user which has created this entity
 
-* `owned_by (EUser)`, relation to the user()s considered as owner of this
+* `owned_by (CWUser)`, relation to the user()s considered as owner of this
   entity, the entity's creator by default
 
 * `is (Eetype)`, special relation to specify a variable type.
 
 A user's entity has the following schema:
 
-:EUser:
+:CWUser:
   ::
 
 	login  	  (String) not null
--- a/web/wdoc/tut_rql_fr.rst	Wed Apr 22 09:45:54 2009 +0200
+++ b/web/wdoc/tut_rql_fr.rst	Fri Apr 24 19:46:47 2009 +0200
@@ -134,9 +134,9 @@
 * `creation_date (Datetime)`, date de création de l'entité
 * `modification_date (Datetime)`, date de dernière modification de l'entité
 
-* `created_by (EUser)`, relation vers l'utilisateur ayant créé l'entité
+* `created_by (CWUser)`, relation vers l'utilisateur ayant créé l'entité
 
-* `owned_by (EUser)`, relation vers le où les utilisateurs considérés comme 
+* `owned_by (CWUser)`, relation vers le où les utilisateurs considérés comme 
   propriétaire de l'entité, par défaut le créateur de l'entité
 
 * `is (Eetype)`, relation spéciale permettant de spécifier le
@@ -144,7 +144,7 @@
 
 Enfin, le schéma standard d'un utilisateur est le suivant :
 
-:EUser:
+:CWUser:
   ::
 
 	login  	  (String, obligatoire)