diff --git a/product/ERP5Form/Form.py b/product/ERP5Form/Form.py
index f8423ea16d53b874e0de63b86012e7a9ee6c3c51..e5efb1e2b5e612e26221aaa0a7282c674fed81ec 100755
--- a/product/ERP5Form/Form.py
+++ b/product/ERP5Form/Form.py
@@ -49,127 +49,116 @@ from Products.Formulator.Field import Field
 
 from zLOG import LOG
 
-class ERP5Field(Field):
-    """
-      The ERP5Field provides here, request,
-      container etc. names to TALES expressions. It is used to dynamically
-      patch the standard Formulator
-    """
-    security = ClassSecurityInfo()
-
-    # this is a field
-    is_field = 1
-
-    security.declareProtected('Access contents information', 'get_value')
-    def get_value(self, id, **kw):
-        """Get value for id."""
-        # FIXME: backwards compat hack to make sure tales dict exists
-        if not hasattr(self, 'tales'):
-            self.tales = {}
-
-        tales_expr = self.tales.get(id, "")
-        if tales_expr:
-            form = self.aq_parent
-            object = getattr(form, 'aq_parent', None)
-            if object:
-                # NEEDS TO BE CHECKED
-                # container = object.aq_inner.aq_parent ORIGINAL VERSION - not so good ?
-                container = object.aq_parent
-                #container = object.getParentNode()
-            else:
-                container = None
-            kw['field'] = self
-            kw['form'] = form
-            kw['here'] = object
-            kw['container'] = container
-            # This allows to pass some pointer to the local object
-            # through the REQUEST parameter. Not very clean.
-            # Used by ListBox to render different items in a list
-            if kw.has_key('REQUEST') and not kw.get('cell'): kw['cell'] = kw['REQUEST']
-            try:
-              value = tales_expr.__of__(self)(**kw)
-            except:
-              # We add this safety exception to make sure we always get
-              # something reasonable rather than generate plenty of errors
-              LOG('ERP5Form.get_value ( %s/%s [%s]), exception on tales_expr: '%(
-		  self.aq_parent.getId(), self.getId(), id) ,0,'', error=sys.exc_info())
-              value = self.get_orig_value(id)
+def get_value(self, id, **kw):
+    """Get value for id."""
+    # FIXME: backwards compat hack to make sure tales dict exists
+    if not hasattr(self, 'tales'):
+        self.tales = {}
+        
+    tales_expr = self.tales.get(id, "")
+    if tales_expr:
+        form = self.aq_parent
+        object = getattr(form, 'aq_parent', None)
+        if object:
+            # NEEDS TO BE CHECKED
+            # container = object.aq_inner.aq_parent ORIGINAL VERSION - not so good ?
+            container = object.aq_parent
+            #container = object.getParentNode()
         else:
-            # FIXME: backwards compat hack to make sure overrides dict exists
-            if not hasattr(self, 'overrides'):
-                self.overrides = {}
-
-            override = self.overrides.get(id, "")
-            if override:
-                # call wrapped method to get answer
-                value = override.__of__(self)()
-            else:
-                # get normal value
-                value = self.get_orig_value(id)
-                # Only for the default value
-                if id == 'default':
-                  if (value is None or value == '' or value == [] or value == ()) \
-                                                and self.meta_type != 'MethodField' :
-                    # If nothing was provided then try to
-                    # find a default method to get the value
-                    # for that field
-                    # NEEDS TO BE CLEANED UP
-                    try:
-                      form = self.aq_parent
-                      object = getattr(form, 'aq_parent', None)
-                      key = self.id
-                      key = key[3:]
-                      value = object.getProperty(key, d=value)
-                    except:
-                      value = None
-
-        # if normal value is a callable itself, wrap it
-        if callable(value):
-            value = value.__of__(self)            
-            #value=value() # Mising call ??? XXX Make sure compatible with listbox methods
-
-        if id == 'default':
-          if self.meta_type != 'DateTimeField':
-            # We make sure we convert values to empty strings
-            # for most fields (so that we do not get a 'value'
-            # message on screeen)
-            # This can be overriden by useing TALES in the field
-            if value is None: value = ''
-
-        return value
-
-    def om_icons(self):
-        """Return a list of icon URLs to be displayed by an ObjectManager"""
-        icons = ({'path': self.icon,
-                  'alt': self.meta_type, 'title': self.meta_type},)
-        return icons
-
-    psyco.bind(get_value)
-
-    def _get_default(self, key, value, REQUEST):
-        if value is not None:
-            return value
+            container = None
+        kw['field'] = self
+        kw['form'] = form
+        kw['here'] = object
+        kw['container'] = container
+        # This allows to pass some pointer to the local object
+        # through the REQUEST parameter. Not very clean.
+        # Used by ListBox to render different items in a list
+        if kw.has_key('REQUEST') and not kw.get('cell'): kw['cell'] = kw['REQUEST']
         try:
-            value = REQUEST.form[key]
-        except (KeyError, AttributeError):
-            # fall back on default
-            return self.get_value('default',REQUEST=REQUEST) # It was missing on Formulator
-
-        # if we enter a string value while the field expects unicode,
-        # convert to unicode first
-        # this solves a problem when re-rendering a sticky form with
-        # values from request
-        if (self.has_value('unicode') and self.get_value('unicode') and
-            type(value) == type('')):
-            return unicode(value, self.get_form_encoding())
+            value = tales_expr.__of__(self)(**kw)
+        except:
+            # We add this safety exception to make sure we always get
+            # something reasonable rather than generate plenty of errors
+            LOG('ERP5Form.get_value ( %s/%s [%s]), exception on tales_expr: '%(
+                self.aq_parent.getId(), self.getId(), id) ,0,'', error=sys.exc_info())
+            value = self.get_orig_value(id)
+    else:
+        # FIXME: backwards compat hack to make sure overrides dict exists
+        if not hasattr(self, 'overrides'):
+            self.overrides = {}
+            
+        override = self.overrides.get(id, "")
+        if override:
+            # call wrapped method to get answer
+            value = override.__of__(self)()
         else:
-            return value
+            # get normal value
+            value = self.get_orig_value(id)
+            # Only for the default value
+            if id == 'default':
+                if (value is None or value == '' or value == [] or value == ()) \
+                       and self.meta_type != 'MethodField' :
+                  # If nothing was provided then try to
+                  # find a default method to get the value
+                  # for that field
+                  # NEEDS TO BE CLEANED UP
+                  try:
+                    form = self.aq_parent
+                    object = getattr(form, 'aq_parent', None)
+                    key = self.id
+                    key = key[3:]
+                    value = object.getProperty(key, d=value)
+                  except:
+                    value = None
+
+    # if normal value is a callable itself, wrap it
+    if callable(value):
+        value = value.__of__(self)            
+        #value=value() # Mising call ??? XXX Make sure compatible with listbox methods
+
+    if id == 'default':
+        if self.meta_type != 'DateTimeField':
+          # We make sure we convert values to empty strings
+          # for most fields (so that we do not get a 'value'
+          # message on screeen)
+          # This can be overriden by useing TALES in the field
+          if value is None: value = ''
+          
+    return value
+
+psyco.bind(get_value)
+
+def om_icons(self):
+    """Return a list of icon URLs to be displayed by an ObjectManager"""
+    icons = ({'path': self.icon,
+              'alt': self.meta_type, 'title': self.meta_type},)
+    return icons
+
+
+def _get_default(self, key, value, REQUEST):
+    if value is not None:
+        return value
+    try:
+        value = REQUEST.form[key]
+    except (KeyError, AttributeError):
+        # fall back on default
+        return self.get_value('default',REQUEST=REQUEST) # It was missing on Formulator
+    
+    # if we enter a string value while the field expects unicode,
+    # convert to unicode first
+    # this solves a problem when re-rendering a sticky form with
+    # values from request
+    if (self.has_value('unicode') and self.get_value('unicode') and
+        type(value) == type('')):
+        return unicode(value, self.get_form_encoding())
+    else:
+        return value
 
 
 # Dynamic Patch
-Field.get_value = ERP5Field.get_value
-Field._get_default = ERP5Field._get_default
-Field.om_icons = ERP5Field.om_icons
+Field.get_value = get_value
+Field._get_default = _get_default
+Field.om_icons = om_icons
 
 # Constructors
 
diff --git a/product/ERP5Form/FormulatorPatch.py b/product/ERP5Form/FormulatorPatch.py
index 3f0dcde469216a0a65344091f89c070de4a09f0c..deccb86c7484b65556974982773d0891b8c4c8aa 100755
--- a/product/ERP5Form/FormulatorPatch.py
+++ b/product/ERP5Form/FormulatorPatch.py
@@ -26,70 +26,63 @@ from Products.Formulator.Widget import Widget
 from AccessControl import ClassSecurityInfo
 from zLOG import LOG
 
-class PatchedField(Field):
-
-    security = ClassSecurityInfo()
-    security.declareProtected('Access contents information',
-                              'generate_field_key')
-    def generate_field_key(self, validation=0, key=None):
-        """Generate the key Silva uses to render the field in the form.
-        """
-        # Patched by JPS for ERP5 in order to
-        # dynamically change the name
-        if key is not None:
-          return 'field_%s' % key
-        if self.field_record is None:
-            return 'field_%s' % self.id
-        elif validation:
-            return self.id
-        elif isinstance(self.widget, MultiItemsWidget):
-            return "%s.%s:record:list" % (self.field_record, self.id)
-        else:
-            return '%s.%s:record' % (self.field_record, self.id)
-
-    security.declareProtected('View', 'render')
-    def render(self, value=None, REQUEST=None, key=None):
-        """Render the field widget.
-        value -- the value the field should have (for instance
-                 from validation).
-        REQUEST -- REQUEST can contain raw (unvalidated) field
-                 information. If value is None, REQUEST is searched
-                 for this value.
-        if value and REQUEST are both None, the 'default' property of
-        the field will be used for the value.
-        """
-        return self._render_helper(self.generate_field_key(key=key), value, REQUEST)
+def Field_generate_field_key(self, validation=0, key=None):
+    """Generate the key Silva uses to render the field in the form.
+    """
+    # Patched by JPS for ERP5 in order to
+    # dynamically change the name
+    if key is not None:
+      return 'field_%s' % key
+    if self.field_record is None:
+        return 'field_%s' % self.id
+    elif validation:
+        return self.id
+    elif isinstance(self.widget, MultiItemsWidget):
+        return "%s.%s:record:list" % (self.field_record, self.id)
+    else:
+        return '%s.%s:record' % (self.field_record, self.id)
+
+def Field_render(self, value=None, REQUEST=None, key=None):
+    """Render the field widget.
+    value -- the value the field should have (for instance
+              from validation).
+    REQUEST -- REQUEST can contain raw (unvalidated) field
+              information. If value is None, REQUEST is searched
+              for this value.
+    if value and REQUEST are both None, the 'default' property of
+    the field will be used for the value.
+    """
+    return self._render_helper(self.generate_field_key(key=key), value, REQUEST)
 
-    security.declareProtected('View', 'render_sub_field')
-    def render_sub_field(self, id, value=None, REQUEST=None, key=None):
-        """Render a sub field, as part of complete rendering of widget in
-        a form. Works like render() but for sub field.
-           Added key parameter for ERP5 in order to be compatible with listbox/matrixbox
-        """
-        return self.sub_form.get_field(id)._render_helper(
-            self.generate_subfield_key(id, key=key), value, REQUEST)
+def Field_render_sub_field(self, id, value=None, REQUEST=None, key=None):
+    """Render a sub field, as part of complete rendering of widget in
+    a form. Works like render() but for sub field.
+        Added key parameter for ERP5 in order to be compatible with listbox/matrixbox
+    """
+    return self.sub_form.get_field(id)._render_helper(
+        self.generate_subfield_key(id, key=key), value, REQUEST)
 
-    def generate_subfield_key(self, id, validation=0, key=None):
-        """Generate the key Silva uses to render a sub field.
-           Added key parameter for ERP5
-           Added key parameter for ERP5 in order to be compatible with listbox/matrixbox
-        """
-        if key is None: key = self.id
-        if self.field_record is None or validation:
-            return 'subfield_%s_%s'%(key, id)
-        return '%s.subfield_%s_%s:record' % (self.field_record, key, id)                        
+def Field_generate_subfield_key(self, id, validation=0, key=None):
+    """Generate the key Silva uses to render a sub field.
+        Added key parameter for ERP5
+        Added key parameter for ERP5 in order to be compatible with listbox/matrixbox
+    """
+    if key is None: key = self.id
+    if self.field_record is None or validation:
+        return 'subfield_%s_%s'%(key, id)
+    return '%s.subfield_%s_%s:record' % (self.field_record, key, id)                        
 
-    def validate_sub_field(self, id, REQUEST, key=None):
-        """Validates a subfield (as part of field validation).
-        """
-        return self.sub_form.get_field(id)._validate_helper(
-            self.generate_subfield_key(id, validation=1, key=key), REQUEST)
+def Field_validate_sub_field(self, id, REQUEST, key=None):
+    """Validates a subfield (as part of field validation).
+    """
+    return self.sub_form.get_field(id)._validate_helper(
+        self.generate_subfield_key(id, validation=1, key=key), REQUEST)
 
-Field.generate_field_key = PatchedField.generate_field_key
-Field.render = PatchedField.render
-Field.render_sub_field = PatchedField.render_sub_field
-Field.generate_subfield_key = PatchedField.generate_subfield_key
-Field.validate_sub_field = PatchedField.validate_sub_field
+Field.generate_field_key = Field_generate_field_key
+Field.render = Field_render
+Field.render_sub_field = Field_render_sub_field
+Field.generate_subfield_key = Field_generate_subfield_key
+Field.validate_sub_field = Field_validate_sub_field
 
 from Products.Formulator.Validator import SelectionValidator
 from Products.Formulator.Validator import StringBaseValidator
@@ -564,25 +557,18 @@ MultiItemsWidget.render_items = MultiItemsWidget_render_items
 # JPS - Subfield handling with listbox requires extension
 from Products.Formulator.StandardFields import DateTimeField
 
-class PatchedDateTimeField(DateTimeField):
-    """
-      Make sur we test if this REQUEST parameter has a form
-      attribute. In ERP5, we sometimes use the REQUEST to pass
-      subobjects to forms.
-    """
-  
-    def _get_default(self, key, value, REQUEST):
-        if value is not None:
-            return value
-        # if there is something in the request then return None
-        # sub fields should pick up defaults themselves
-        if REQUEST is not None and hasattr(REQUEST, 'form') and \
-          REQUEST.form.has_key('subfield_%s_%s' % (self.id, 'year')):
-            return None
-        else:
-            return self.get_value('default')
+def DateTimeField_get_default(self, key, value, REQUEST):
+    if value is not None:
+        return value
+    # if there is something in the request then return None
+    # sub fields should pick up defaults themselves
+    if REQUEST is not None and hasattr(REQUEST, 'form') and \
+      REQUEST.form.has_key('subfield_%s_%s' % (self.id, 'year')):
+        return None
+    else:
+        return self.get_value('default')
 
-DateTimeField._get_default = PatchedDateTimeField._get_default
+DateTimeField._get_default = DateTimeField_get_default
     
 from Products.Formulator.Widget import DateTimeWidget
 
diff --git a/product/ERP5Form/__init__.py b/product/ERP5Form/__init__.py
index 378bfde1aa1c7180fc9202bfff67d9792c6dee1c..14e2a7af962285f615b35341951a275ebaa06a88 100755
--- a/product/ERP5Form/__init__.py
+++ b/product/ERP5Form/__init__.py
@@ -61,7 +61,7 @@ import FormulatorPatch
 import psyco
 psyco.bind(ListBox.ListBoxWidget.render)
 psyco.bind(ListBox.ListBoxValidator.validate)
-psyco.bind(Form.ERP5Field.get_value)
+#psyco.bind(Form.ERP5Field.get_value)
 #psyco.bind(Form.ERP5Form.__call__)
 #psyco.bind(Form.ERP5Form._exec)
 
diff --git a/product/ERP5Type/CMFCorePatch.py b/product/ERP5Type/CMFCorePatch.py
index e48413196c754c8b545d7878d7b2d2b2f4c5a81e..eca074aa28540eeec29efd9a5ed8e9dd8d8d7ebf 100755
--- a/product/ERP5Type/CMFCorePatch.py
+++ b/product/ERP5Type/CMFCorePatch.py
@@ -24,39 +24,37 @@ from Products.CMFCore.FSZSQLMethod import FSZSQLMethod
 from Products.CMFCore.DirectoryView import expandpath
 from Products.ZSQLMethods.SQL import SQL
 
-class PatchedFSZSQLMethod(FSZSQLMethod):
-
-    def _readFile(self, reparse):
-        fp = expandpath(self._filepath)
-        file = open(fp, 'r')    # not 'rb', as this is a text file!
-        try:
-            data = file.read()
-        finally: file.close()
-
-        RESPONSE = {}
-        RESPONSE['BODY'] = data
-
-        self.PUT(RESPONSE,None)
-
-
-    def _createZODBClone(self):
-        """Create a ZODB (editable) equivalent of this object."""
-        # I guess it's bad to 'reach inside' ourselves like this,
-        # but Z SQL Methods don't have accessor methdods ;-)
-        s = SQL(self.id,
-                self.title,
-                self.connection_id,
-                self.arguments_src,
-                self.src)
-        s.manage_advanced(self.max_rows_,
-                          self.max_cache_,
-                          self.cache_time_,
-                          self.class_name_,
-                          self.class_file_)
-        return s
-
-FSZSQLMethod._readFile = PatchedFSZSQLMethod._readFile
-FSZSQLMethod._createZODBClone = PatchedFSZSQLMethod._createZODBClone
+def FSZSQLMethod_readFile(self, reparse):
+    fp = expandpath(self._filepath)
+    file = open(fp, 'r')    # not 'rb', as this is a text file!
+    try:
+        data = file.read()
+    finally: file.close()
+
+    RESPONSE = {}
+    RESPONSE['BODY'] = data
+
+    self.PUT(RESPONSE,None)
+
+
+def FSZSQLMethod_createZODBClone(self):
+    """Create a ZODB (editable) equivalent of this object."""
+    # I guess it's bad to 'reach inside' ourselves like this,
+    # but Z SQL Methods don't have accessor methdods ;-)
+    s = SQL(self.id,
+            self.title,
+            self.connection_id,
+            self.arguments_src,
+            self.src)
+    s.manage_advanced(self.max_rows_,
+                      self.max_cache_,
+                      self.cache_time_,
+                      self.class_name_,
+                      self.class_file_)
+    return s
+
+FSZSQLMethod._readFile = FSZSQLMethod_readFile
+FSZSQLMethod._createZODBClone = FSZSQLMethod_createZODBClone
 
 from Products.CMFCore import ActionInformation
 from AccessControl import ClassSecurityInfo
@@ -188,146 +186,144 @@ ActionInformation.ActionInformation = PatchedActionInformation
 from Products.CMFCore.ActionProviderBase import ActionProviderBase
 from Products.CMFCore.ActionInformation import ActionInformation
 
-class PatchedActionProviderBase(ActionProviderBase):
-
-    def manage_editActionsForm( self, REQUEST, manage_tabs_message=None ):
-
-        """ Show the 'Actions' management tab.
-        """
-        actions = []
-
-        for a in self.listActions():
-
-            a1 = {}
-            a1['id'] = a.getId()
-            a1['name'] = a.Title()
-            p = a.getPermissions()
-            if p:
-                a1['permission'] = p[0]
-            else:
-                a1['permission'] = ''
-            a1['category'] = a.getCategory() or 'object'
-            a1['visible'] = a.getVisibility()
-            a1['action'] = a.getActionExpression()
-            a1['condition'] = a.getCondition()
-            if hasattr(a, 'getIconExpression') :
-              a1['icon'] = a.getIconExpression()
-            if hasattr(a, 'getOption') :
-              a1['optional'] = a.getOption()
-            actions.append(a1)
-
-        # possible_permissions is in AccessControl.Role.RoleManager.
-        pp = self.possible_permissions()
-        return self._actions_form( self
-                                 , REQUEST
-                                 , actions=actions
-                                 , possible_permissions=pp
-                                 , management_view='Actions'
-                                 , manage_tabs_message=manage_tabs_message
-                                 )
-
-
-    def addAction( self
-                 , id
-                 , name
-                 , action
-                 , condition
-                 , permission
-                 , category
-                 , icon=None
-                 , visible=1
-                 , optional=0
-                 , REQUEST=None
-                 ):
-        """ Add an action to our list.
-        """
-        if not name:
-            raise ValueError('A name is required.')
-
-        a_expr = action and Expression(text=str(action)) or ''
-        i_expr = icon and Expression(text=str(icon)) or ''
-        c_expr = condition and Expression(text=str(condition)) or ''
-
-        if type( permission ) != type( () ):
-            permission = permission and (str(permission),) or ()
-
-        new_actions = self._cloneActions()
-
-        new_action = ActionInformation( id=str(id)
-                                      , title=str(name)
-                                      , action=a_expr
-                                      , icon=i_expr
-                                      , condition=c_expr
-                                      , permissions=permission
-                                      , category=str(category)
-                                      , visible=int(visible)
-                                      , optional=int(optional)
-                                      )
-
-        new_actions.append( new_action )
-        self._actions = tuple( new_actions )
-
-        if REQUEST is not None:
-            return self.manage_editActionsForm(
-                REQUEST, manage_tabs_message='Added.')
-
-
-    def _extractAction( self, properties, index ):
+def ActionProviderBase_manage_editActionsForm( self, REQUEST, manage_tabs_message=None ):
+
+    """ Show the 'Actions' management tab.
+    """
+    actions = []
+
+    for a in self.listActions():
+
+        a1 = {}
+        a1['id'] = a.getId()
+        a1['name'] = a.Title()
+        p = a.getPermissions()
+        if p:
+            a1['permission'] = p[0]
+        else:
+            a1['permission'] = ''
+        a1['category'] = a.getCategory() or 'object'
+        a1['visible'] = a.getVisibility()
+        a1['action'] = a.getActionExpression()
+        a1['condition'] = a.getCondition()
+        if hasattr(a, 'getIconExpression') :
+          a1['icon'] = a.getIconExpression()
+        if hasattr(a, 'getOption') :
+          a1['optional'] = a.getOption()
+        actions.append(a1)
+
+    # possible_permissions is in AccessControl.Role.RoleManager.
+    pp = self.possible_permissions()
+    return self._actions_form( self
+                              , REQUEST
+                              , actions=actions
+                              , possible_permissions=pp
+                              , management_view='Actions'
+                              , manage_tabs_message=manage_tabs_message
+                              )
+
+
+def ActionProviderBase_addAction( self
+              , id
+              , name
+              , action
+              , condition
+              , permission
+              , category
+              , icon=None
+              , visible=1
+              , optional=0
+              , REQUEST=None
+              ):
+    """ Add an action to our list.
+    """
+    if not name:
+        raise ValueError('A name is required.')
+
+    a_expr = action and Expression(text=str(action)) or ''
+    i_expr = icon and Expression(text=str(icon)) or ''
+    c_expr = condition and Expression(text=str(condition)) or ''
+
+    if type( permission ) != type( () ):
+        permission = permission and (str(permission),) or ()
+
+    new_actions = self._cloneActions()
+
+    new_action = ActionInformation( id=str(id)
+                                  , title=str(name)
+                                  , action=a_expr
+                                  , icon=i_expr
+                                  , condition=c_expr
+                                  , permissions=permission
+                                  , category=str(category)
+                                  , visible=int(visible)
+                                  , optional=int(optional)
+                                  )
+
+    new_actions.append( new_action )
+    self._actions = tuple( new_actions )
+
+    if REQUEST is not None:
+        return self.manage_editActionsForm(
+            REQUEST, manage_tabs_message='Added.')
+
+
+def ActionProviderBase_extractAction( self, properties, index ):
+
+    """ Extract an ActionInformation from the funky form properties.
+    """
+    id          = str( properties.get( 'id_%d'          % index, '' ) )
+    name        = str( properties.get( 'name_%d'        % index, '' ) )
+    action      = str( properties.get( 'action_%d'      % index, '' ) )
+    icon        = str( properties.get( 'icon_%d'        % index, '' ) )
+    condition   = str( properties.get( 'condition_%d'   % index, '' ) )
+    category    = str( properties.get( 'category_%d'    % index, '' ))
+    visible     =      properties.get( 'visible_%d'     % index, 0  )
+    optional    =      properties.get( 'optional_%d'    % index, 0  )
+    permissions =      properties.get( 'permission_%d'  % index, () )
+
+    if not name:
+        raise ValueError('A name is required.')
+
+    if action is not '':
+        action = Expression( text=action )
+
+    if icon is not '':
+        icon = Expression( text=icon )
+
+    if condition is not '':
+        condition = Expression( text=condition )
+
+    if category == '':
+        category = 'object'
+
+    if type( visible ) is not type( 0 ):
+        try:
+            visible = int( visible )
+        except:
+            visible = 0
 
-        """ Extract an ActionInformation from the funky form properties.
-        """
-        id          = str( properties.get( 'id_%d'          % index, '' ) )
-        name        = str( properties.get( 'name_%d'        % index, '' ) )
-        action      = str( properties.get( 'action_%d'      % index, '' ) )
-        icon        = str( properties.get( 'icon_%d'        % index, '' ) )
-        condition   = str( properties.get( 'condition_%d'   % index, '' ) )
-        category    = str( properties.get( 'category_%d'    % index, '' ))
-        visible     =      properties.get( 'visible_%d'     % index, 0  )
-        optional    =      properties.get( 'optional_%d'    % index, 0  )
-        permissions =      properties.get( 'permission_%d'  % index, () )
-
-        if not name:
-            raise ValueError('A name is required.')
-
-        if action is not '':
-            action = Expression( text=action )
-
-        if icon is not '':
-            icon = Expression( text=icon )
-
-        if condition is not '':
-            condition = Expression( text=condition )
-
-        if category == '':
-            category = 'object'
-
-        if type( visible ) is not type( 0 ):
-            try:
-                visible = int( visible )
-            except:
-                visible = 0
-
-        if type( optional ) is not type( 0 ):
-            try:
-                optional = int( optional )
-            except:
-                optional = 0
-
-        if type( permissions ) is type( '' ):
-            permissions = ( permissions, )
-
-        return ActionInformation( id=id
-                                , title=name
-                                , action=action
-                                , icon=icon
-                                , condition=condition
-                                , permissions=permissions
-                                , category=category
-                                , visible=visible
-                                , optional=optional
-                                )
-
-ActionProviderBase.manage_editActionsForm = PatchedActionProviderBase.manage_editActionsForm
-ActionProviderBase.addAction = PatchedActionProviderBase.addAction
-ActionProviderBase._extractAction = PatchedActionProviderBase._extractAction
+    if type( optional ) is not type( 0 ):
+        try:
+            optional = int( optional )
+        except:
+            optional = 0
+
+    if type( permissions ) is type( '' ):
+        permissions = ( permissions, )
+
+    return ActionInformation( id=id
+                            , title=name
+                            , action=action
+                            , icon=icon
+                            , condition=condition
+                            , permissions=permissions
+                            , category=category
+                            , visible=visible
+                            , optional=optional
+                            )
+
+ActionProviderBase.manage_editActionsForm = ActionProviderBase_manage_editActionsForm
+ActionProviderBase.addAction = ActionProviderBase_addAction
+ActionProviderBase._extractAction = ActionProviderBase_extractAction
 
diff --git a/product/ERP5Type/ZopePatch.py b/product/ERP5Type/ZopePatch.py
index 7562a105bb17e57087b74e3c1308463672fb9355..49ed4a326e8a27050c6a460c176cde8906556eb3 100755
--- a/product/ERP5Type/ZopePatch.py
+++ b/product/ERP5Type/ZopePatch.py
@@ -36,30 +36,30 @@ MembershipTool.membersfolder_id = 'member'
 ##############################################################################
 # Import: add rename feature
 from OFS.ObjectManager import ObjectManager, customImporters
-class PatchedObjectManager(ObjectManager):
-    def _importObjectFromFile(self, filepath, verify=1, set_owner=1, id=None):
-        #LOG('_importObjectFromFile, filepath',0,filepath)
-        # locate a valid connection
-        connection=self._p_jar
-        obj=self
-
-        while connection is None:
-            obj=obj.aq_parent
-            connection=obj._p_jar
-        ob=connection.importFile(
-            filepath, customImporters=customImporters)
-        if verify: self._verifyObjectPaste(ob, validate_src=0)
-        if id is None:
-          id=ob.id
-        if hasattr(id, 'im_func'): id=id()
-        self._setObject(id, ob, set_owner=set_owner)
-
-        # try to make ownership implicit if possible in the context
-        # that the object was imported into.
-        ob=self._getOb(id)
-        ob.manage_changeOwnershipType(explicit=0)
-
-ObjectManager._importObjectFromFile=PatchedObjectManager._importObjectFromFile
+
+def ObjectManager_importObjectFromFile(self, filepath, verify=1, set_owner=1, id=None):
+    #LOG('_importObjectFromFile, filepath',0,filepath)
+    # locate a valid connection
+    connection=self._p_jar
+    obj=self
+
+    while connection is None:
+        obj=obj.aq_parent
+        connection=obj._p_jar
+    ob=connection.importFile(
+        filepath, customImporters=customImporters)
+    if verify: self._verifyObjectPaste(ob, validate_src=0)
+    if id is None:
+      id=ob.id
+    if hasattr(id, 'im_func'): id=id()
+    self._setObject(id, ob, set_owner=set_owner)
+
+    # try to make ownership implicit if possible in the context
+    # that the object was imported into.
+    ob=self._getOb(id)
+    ob.manage_changeOwnershipType(explicit=0)
+
+ObjectManager._importObjectFromFile=ObjectManager_importObjectFromFile
 
 ##############################################################################
 # Properties
@@ -71,148 +71,152 @@ from Products.ERP5Type.ERP5Type import ERP5TypeInformation
 from Products.CMFCore.Expression import Expression
 
 class ERP5PropertyManager(PropertyManager):
+  """
+    This class is only for backward compatibility.
+  """
+  pass
 
-  manage_propertiesForm=DTMLFile('dtml/properties', globals(),
-                                  property_extensible_schema__=1)
-
-
-  def _updateProperty(self, id, value):
-      # Update the value of an existing property. If value
-      # is a string, an attempt will be made to convert
-      # the value to the type of the existing property.
-      self._wrapperCheck(value)
-      if not hasattr(self, 'isRADContent'):
-        if not self.hasProperty(id):
-            raise 'Bad Request', 'The property %s does not exist' % escape(id)
-      if type(value)==type(''):
-          proptype=self.getPropertyType(id) or 'string'
-          if type_converters.has_key(proptype):
-              value=type_converters[proptype](value)
-      #LOG('_updateProperty', 0, 'self = %r, id = %r, value = %r' % (self, id, value))
-      self._setPropValue(id, value)
-
-  def hasProperty(self, id):
-      """Return true if object has a property 'id'"""
-      for p in self.propertyIds():
-          if id==p:
-              return 1
-      return 0
-
-  def getProperty(self, id, d=None, evaluate=1):
-      """Get the property 'id', returning the optional second
-          argument or None if no such property is found."""
-      type = self.getPropertyType(id)
-      if evaluate and type == 'tales':
-          value = getattr(self, id)
-          expression = Expression(value)
-          econtext = createExpressionContext(self)
-          return expression(econtext)
-      elif type:
-        return getattr(self, id)
-      return d
-
-  def getPropertyType(self, id):
-      """Get the type of property 'id', returning None if no
-        such property exists"""
-      for md in self._propertyMap():
-          if md['id']==id:
-              return md.get('type', 'string')
-      return None
-
-  def _setProperty(self, id, value, type=None):
-      # for selection and multiple selection properties
-      # the value argument indicates the select variable
-      # of the property
-
-      if type is None:
-        # Generate a default type
-        value_type = type(value)
-        if value_type in (type([]), type(())):
-          type = 'lines'
-        elif value_type is type(1):
-          type = 'int'
-        elif value_type is type(1L):
-          type = 'long'
-        elif value_type is type(1.0):
-          type = 'float'
-        elif value_type is type('a'):
-          if len(value_type.split('\n')) > 1:
-            type = 'text'
-          else:
-            type = 'string'
-        else:
-          type = 'string'
+PropertyManager_manage_propertiesForm=DTMLFile('dtml/properties', globals(),
+                                               property_extensible_schema__=1)
 
-      self._wrapperCheck(value)
-      if not self.valid_property_id(id):
-          raise 'Bad Request', 'Invalid or duplicate property id'
-
-      if type in ('selection', 'multiple selection'):
-          if not hasattr(self, value):
-              raise 'Bad Request', 'No select variable %s' % value
-          self._local_properties=getattr(self, '_local_properties', ()) + (
-              {'id':id, 'type':type, 'select_variable':value},)
-          if type=='selection':
-              self._setPropValue(id, '')
-          else:
-              self._setPropValue(id, [])
-      else:
-          self._local_properties=getattr(self, '_local_properties', ())+({'id':id,'type':type},)
-          self._setPropValue(id, value)
 
-  def _delProperty(self, id):
+def PropertyManager_updateProperty(self, id, value):
+    # Update the value of an existing property. If value
+    # is a string, an attempt will be made to convert
+    # the value to the type of the existing property.
+    self._wrapperCheck(value)
+    if not hasattr(self, 'isRADContent'):
       if not self.hasProperty(id):
-          raise ValueError, 'The property %s does not exist' % escape(id)
-      self._delPropValue(id)
-      self._local_properties=tuple(filter(lambda i, n=id: i['id'] != n,
-                                    getattr(self, '_local_properties', ())))
-
-  def propertyIds(self):
-      """Return a list of property ids """
-      return map(lambda i: i['id'], self._propertyMap())
-
-  def propertyValues(self):
-      """Return a list of actual property objects """
-      return map(lambda i,s=self: getattr(s,i['id']), self._propertyMap())
-
-  def propertyItems(self):
-      """Return a list of (id,property) tuples """
-      return map(lambda i,s=self: (i['id'],getattr(s,i['id'])), self._propertyMap())
-
-  def _propertyMap(self):
-      """Return a tuple of mappings, giving meta-data for properties """
-      return tuple(list(self._properties) + list(getattr(self, '_local_properties', ())))
-
-  def propdict(self):
-      dict={}
-      for p in self._propertyMap():
-          dict[p['id']]=p
-      return dict
-
-  def manage_addProperty(self, id, value, type, REQUEST=None):
-      """Add a new property via the web. Sets a new property with
-      the given id, type, and value."""
-      if type_converters.has_key(type):
-          value=type_converters[type](value)
-      #LOG('manage_addProperty', 0, 'id = %r, value = %r, type = %r, REQUEST = %r' % (id, value, type, REQUEST))
-      self._setProperty(id.strip(), value, type)
-      if REQUEST is not None:
-          return self.manage_propertiesForm(self, REQUEST)
-
-PropertyManager.manage_addProperty = ERP5PropertyManager.manage_addProperty
-PropertyManager.manage_propertiesForm = ERP5PropertyManager.manage_propertiesForm
-PropertyManager._updateProperty = ERP5PropertyManager._updateProperty
-PropertyManager.getPropertyType = ERP5PropertyManager.getPropertyType
-PropertyManager._setProperty = ERP5PropertyManager._setProperty
-PropertyManager._delProperty = ERP5PropertyManager._delProperty
-PropertyManager.propertyIds = ERP5PropertyManager.propertyIds
-PropertyManager.propertyValues = ERP5PropertyManager.propertyValues
-PropertyManager.propertyItems = ERP5PropertyManager.propertyItems
-PropertyManager._propertyMap = ERP5PropertyManager._propertyMap
-PropertyManager.propdict = ERP5PropertyManager.propdict
-PropertyManager.hasProperty = ERP5PropertyManager.hasProperty
-PropertyManager.getProperty = ERP5PropertyManager.getProperty
-ERP5TypeInformation.manage_propertiesForm = ERP5PropertyManager.manage_propertiesForm
+          raise 'Bad Request', 'The property %s does not exist' % escape(id)
+    if type(value)==type(''):
+        proptype=self.getPropertyType(id) or 'string'
+        if type_converters.has_key(proptype):
+            value=type_converters[proptype](value)
+    #LOG('_updateProperty', 0, 'self = %r, id = %r, value = %r' % (self, id, value))
+    self._setPropValue(id, value)
+
+def PropertyManager_hasProperty(self, id):
+    """Return true if object has a property 'id'"""
+    for p in self.propertyIds():
+        if id==p:
+            return 1
+    return 0
+
+def PropertyManager_getProperty(self, id, d=None, evaluate=1):
+    """Get the property 'id', returning the optional second
+        argument or None if no such property is found."""
+    type = self.getPropertyType(id)
+    if evaluate and type == 'tales':
+        value = getattr(self, id)
+        expression = Expression(value)
+        econtext = createExpressionContext(self)
+        return expression(econtext)
+    elif type:
+      return getattr(self, id)
+    return d
+
+def PropertyManager_getPropertyType(self, id):
+    """Get the type of property 'id', returning None if no
+      such property exists"""
+    for md in self._propertyMap():
+        if md['id']==id:
+            return md.get('type', 'string')
+    return None
+
+def PropertyManager_setProperty(self, id, value, type=None):
+    # for selection and multiple selection properties
+    # the value argument indicates the select variable
+    # of the property
+
+    if type is None:
+      # Generate a default type
+      value_type = type(value)
+      if value_type in (type([]), type(())):
+        type = 'lines'
+      elif value_type is type(1):
+        type = 'int'
+      elif value_type is type(1L):
+        type = 'long'
+      elif value_type is type(1.0):
+        type = 'float'
+      elif value_type is type('a'):
+        if len(value_type.split('\n')) > 1:
+          type = 'text'
+        else:
+          type = 'string'
+      else:
+        type = 'string'
+
+    self._wrapperCheck(value)
+    if not self.valid_property_id(id):
+        raise 'Bad Request', 'Invalid or duplicate property id'
+
+    if type in ('selection', 'multiple selection'):
+        if not hasattr(self, value):
+            raise 'Bad Request', 'No select variable %s' % value
+        self._local_properties=getattr(self, '_local_properties', ()) + (
+            {'id':id, 'type':type, 'select_variable':value},)
+        if type=='selection':
+            self._setPropValue(id, '')
+        else:
+            self._setPropValue(id, [])
+    else:
+        self._local_properties=getattr(self, '_local_properties', ())+({'id':id,'type':type},)
+        self._setPropValue(id, value)
+
+def PropertyManager_delProperty(self, id):
+    if not self.hasProperty(id):
+        raise ValueError, 'The property %s does not exist' % escape(id)
+    self._delPropValue(id)
+    self._local_properties=tuple(filter(lambda i, n=id: i['id'] != n,
+                                  getattr(self, '_local_properties', ())))
+
+def PropertyManager_propertyIds(self):
+    """Return a list of property ids """
+    return map(lambda i: i['id'], self._propertyMap())
+
+def PropertyManager_propertyValues(self):
+    """Return a list of actual property objects """
+    return map(lambda i,s=self: getattr(s,i['id']), self._propertyMap())
+
+def PropertyManager_propertyItems(self):
+    """Return a list of (id,property) tuples """
+    return map(lambda i,s=self: (i['id'],getattr(s,i['id'])), self._propertyMap())
+
+def PropertyManager_propertyMap(self):
+    """Return a tuple of mappings, giving meta-data for properties """
+    return tuple(list(self._properties) + list(getattr(self, '_local_properties', ())))
+
+def PropertyManager_propdict(self):
+    dict={}
+    for p in self._propertyMap():
+        dict[p['id']]=p
+    return dict
+
+def PropertyManager_manage_addProperty(self, id, value, type, REQUEST=None):
+    """Add a new property via the web. Sets a new property with
+    the given id, type, and value."""
+    if type_converters.has_key(type):
+        value=type_converters[type](value)
+    #LOG('manage_addProperty', 0, 'id = %r, value = %r, type = %r, REQUEST = %r' % (id, value, type, REQUEST))
+    self._setProperty(id.strip(), value, type)
+    if REQUEST is not None:
+        return self.manage_propertiesForm(self, REQUEST)
+
+PropertyManager.manage_addProperty = PropertyManager_manage_addProperty
+PropertyManager.manage_propertiesForm = PropertyManager_manage_propertiesForm
+PropertyManager._updateProperty = PropertyManager_updateProperty
+PropertyManager.getPropertyType = PropertyManager_getPropertyType
+PropertyManager._setProperty = PropertyManager_setProperty
+PropertyManager._delProperty = PropertyManager_delProperty
+PropertyManager.propertyIds = PropertyManager_propertyIds
+PropertyManager.propertyValues = PropertyManager_propertyValues
+PropertyManager.propertyItems = PropertyManager_propertyItems
+PropertyManager._propertyMap = PropertyManager_propertyMap
+PropertyManager.propdict = PropertyManager_propdict
+PropertyManager.hasProperty = PropertyManager_hasProperty
+PropertyManager.getProperty = PropertyManager_getProperty
+ERP5TypeInformation.manage_propertiesForm = PropertyManager_manage_propertiesForm
 
 from ZPublisher.Converters import type_converters, field2string
 
@@ -226,54 +230,51 @@ except: Bucket=lambda:{}
 from Shared.DC.ZRDB.Aqueduct import decodestring, parse
 from Shared.DC.ZRDB.DA import DA
 
-
-class PatchedDA(DA):
-
-    def fromFile(self, filename):
-      """
-        Read the file and update self
-      """
-      f = file(filename)
-      s = f.read()
-      f.close()
-      self.fromText(s)
-
-    def fromText(self, text):
-      """
-        Read the string 'text' and updates self
-      """
-      start = text.find('<dtml-comment>')
-      end = text.find('</dtml-comment>')
-      block = text[start+14:end]
-      parameters = {}
-      for line in block.split('\n'):
-        pair = line.split(':',1)
-        if len(pair)!=2:
-          continue
-        parameters[pair[0].strip().lower()]=pair[1].strip()
-      # check for required and optional parameters
-      max_rows = parameters.get('max_rows',1000)
-      max_cache = parameters.get('max_cache',100)
-      cache_time = parameters.get('cache_time',0)
-      class_name = parameters.get('class_name','')
-      class_file = parameters.get('class_file','')
-      title = parameters.get('title','')
-      connection_id = parameters.get('connection_id','')
-      arguments = parameters.get('arguments','')
-      start = text.rfind('<params>')
-      end = text.rfind('</params>')
-      arguments = text[start+8:end]
-      template = text[end+9:]
-      while template.find('\n')==0:
-        template=template.replace('\n','',1)
-      self.manage_edit(title=title, connection_id=connection_id,
-                       arguments=arguments, template=template)
-      self.manage_advanced(max_rows, max_cache, cache_time, class_name, class_file)
-
-    def manage_FTPget(self):
-        """Get source for FTP download"""
-        self.REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain')
-        return """<dtml-comment>
+def DA_fromFile(self, filename):
+  """
+    Read the file and update self
+  """
+  f = file(filename)
+  s = f.read()
+  f.close()
+  self.fromText(s)
+
+def DA_fromText(self, text):
+  """
+    Read the string 'text' and updates self
+  """
+  start = text.find('<dtml-comment>')
+  end = text.find('</dtml-comment>')
+  block = text[start+14:end]
+  parameters = {}
+  for line in block.split('\n'):
+    pair = line.split(':',1)
+    if len(pair)!=2:
+      continue
+    parameters[pair[0].strip().lower()]=pair[1].strip()
+  # check for required and optional parameters
+  max_rows = parameters.get('max_rows',1000)
+  max_cache = parameters.get('max_cache',100)
+  cache_time = parameters.get('cache_time',0)
+  class_name = parameters.get('class_name','')
+  class_file = parameters.get('class_file','')
+  title = parameters.get('title','')
+  connection_id = parameters.get('connection_id','')
+  arguments = parameters.get('arguments','')
+  start = text.rfind('<params>')
+  end = text.rfind('</params>')
+  arguments = text[start+8:end]
+  template = text[end+9:]
+  while template.find('\n')==0:
+    template=template.replace('\n','',1)
+  self.manage_edit(title=title, connection_id=connection_id,
+                  arguments=arguments, template=template)
+  self.manage_advanced(max_rows, max_cache, cache_time, class_name, class_file)
+
+def DA_manage_FTPget(self):
+    """Get source for FTP download"""
+    self.REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain')
+    return """<dtml-comment>
 title:%s
 connection_id:%s
 max_rows:%s
@@ -288,51 +289,51 @@ class_file:%s
          self.class_name_, self.class_file_,
          self.arguments_src, self.src)
 
-    # This function doesn't take care about properties by default
-    def PUT(self, REQUEST, RESPONSE):
-        """Handle put requests"""
-        if RESPONSE is not None: self.dav__init(REQUEST, RESPONSE)
-        if RESPONSE is not None: self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
-        body = REQUEST.get('BODY', '')
-        m = re.match('\s*<dtml-comment>(.*?)</dtml-comment>\s*\n', body, re.I | re.S)
-        if m:
-            property_src = m.group(1)
-            parameters = {}
-            for line in property_src.split('\n'):
-              pair = line.split(':',1)
-              if len(pair)!=2:
-                continue
-              parameters[pair[0].strip().lower()]=pair[1].strip()
-            # check for required and optional parameters
-            max_rows = parameters.get('max_rows',1000)
-            max_cache = parameters.get('max_cache',100)
-            cache_time = parameters.get('cache_time',0)
-            class_name = parameters.get('class_name','')
-            class_file = parameters.get('class_file','')
-            title = parameters.get('title','')
-            connection_id = parameters.get('connection_id','')
-            self.manage_advanced(max_rows, max_cache, cache_time, class_name, class_file)
-            self.title = str(title)
-            self.connection_id = str(connection_id)
-            body = body[m.end():]
-        m = re.match('\s*<params>(.*)</params>\s*\n', body, re.I | re.S)
-        if m:
-            self.arguments_src = m.group(1)
-            self._arg=parse(self.arguments_src)
-            body = body[m.end():]
-        template = body
-        self.src = template
-        self.template=t=self.template_class(template)
-        t.cook()
-        self._v_cache={}, Bucket()
-        if RESPONSE is not None: RESPONSE.setStatus(204)
-        return RESPONSE
-
-
-DA.fromFile = PatchedDA.fromFile
-DA.fromText = PatchedDA.fromText
-DA.manage_FTPget = PatchedDA.manage_FTPget
-DA.PUT = PatchedDA.PUT
+# This function doesn't take care about properties by default
+def DA_PUT(self, REQUEST, RESPONSE):
+    """Handle put requests"""
+    if RESPONSE is not None: self.dav__init(REQUEST, RESPONSE)
+    if RESPONSE is not None: self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
+    body = REQUEST.get('BODY', '')
+    m = re.match('\s*<dtml-comment>(.*?)</dtml-comment>\s*\n', body, re.I | re.S)
+    if m:
+        property_src = m.group(1)
+        parameters = {}
+        for line in property_src.split('\n'):
+          pair = line.split(':',1)
+          if len(pair)!=2:
+            continue
+          parameters[pair[0].strip().lower()]=pair[1].strip()
+        # check for required and optional parameters
+        max_rows = parameters.get('max_rows',1000)
+        max_cache = parameters.get('max_cache',100)
+        cache_time = parameters.get('cache_time',0)
+        class_name = parameters.get('class_name','')
+        class_file = parameters.get('class_file','')
+        title = parameters.get('title','')
+        connection_id = parameters.get('connection_id','')
+        self.manage_advanced(max_rows, max_cache, cache_time, class_name, class_file)
+        self.title = str(title)
+        self.connection_id = str(connection_id)
+        body = body[m.end():]
+    m = re.match('\s*<params>(.*)</params>\s*\n', body, re.I | re.S)
+    if m:
+        self.arguments_src = m.group(1)
+        self._arg=parse(self.arguments_src)
+        body = body[m.end():]
+    template = body
+    self.src = template
+    self.template=t=self.template_class(template)
+    t.cook()
+    self._v_cache={}, Bucket()
+    if RESPONSE is not None: RESPONSE.setStatus(204)
+    return RESPONSE
+
+
+DA.fromFile = DA_fromFile
+DA.fromText = DA_fromText
+DA.manage_FTPget = DA_manage_FTPget
+DA.PUT = DA_PUT
 
 ##############################################################################
 # Optimized rendering of global actions (cache)
@@ -345,78 +346,76 @@ from Products.CMFCore.utils import  _getAuthenticatedUser
 from time import time
 from Products.ERP5Type.Cache import CachingMethod
 
-class PatchedDCWorkflowDefinition(DCWorkflowDefinition):
-
-    def listGlobalActions(self, info):
-        '''
-        Allows this workflow to
-        include actions to be displayed in the actions box.
-        Called on every request.
-        Returns the actions to be displayed to the user.
-        '''
-        def _listGlobalActions(user=None, id=None, portal_path=None):
-          if not self.worklists:
-              return None  # Optimization
-          sm = getSecurityManager()
-          portal = self._getPortalRoot()
-          res = []
-          fmt_data = None
-          # We want to display some actions depending on the current date
-          # So, we can now put this kind of expression : <= "%(now)s"
-          # May be this patch should be moved to listFilteredActions in the future
-          info.now = DateTime()
-          for id, qdef in self.worklists.items():
-              if qdef.actbox_name:
-                  guard = qdef.guard
-                  # Patch for ERP5 by JP Smets in order
-                  # to implement worklists and search of local roles
-                  searchres_len = 0
-                  var_match_keys = qdef.getVarMatchKeys()
-                  if var_match_keys:
-                      # Check the catalog for items in the worklist.
-                      catalog = getToolByName(self, 'portal_catalog')
-                      dict = {}
-                      for k in var_match_keys:
-                          v = qdef.getVarMatch(k)
-                          v_fmt = map(lambda x, info=info: x%info, v)
-                          dict[k] = v_fmt
-                      # Patch for ERP5 by JP Smets in order
-                      # to implement worklists and search of local roles
-                      if not (guard is None or guard.check(sm, self, portal)):
-                          dict['local_roles'] = guard.roles
-                      # Patch to use ZSQLCatalog and get high speed
-                      # LOG("PatchedDCWorkflowDefinition", 0, dict)
-                      searchres_len = int(apply(catalog.countResults, (), dict)[0][0])
-                      if searchres_len == 0:
-                          continue
-                  if fmt_data is None:
-                      fmt_data = TemplateDict()
-                      fmt_data._push(info)
-                  fmt_data._push({'count': searchres_len})
+def DCWorkflowDefinition_listGlobalActions(self, info):
+    '''
+    Allows this workflow to
+    include actions to be displayed in the actions box.
+    Called on every request.
+    Returns the actions to be displayed to the user.
+    '''
+    def _listGlobalActions(user=None, id=None, portal_path=None):
+      if not self.worklists:
+          return None  # Optimization
+      sm = getSecurityManager()
+      portal = self._getPortalRoot()
+      res = []
+      fmt_data = None
+      # We want to display some actions depending on the current date
+      # So, we can now put this kind of expression : <= "%(now)s"
+      # May be this patch should be moved to listFilteredActions in the future
+      info.now = DateTime()
+      for id, qdef in self.worklists.items():
+          if qdef.actbox_name:
+              guard = qdef.guard
+              # Patch for ERP5 by JP Smets in order
+              # to implement worklists and search of local roles
+              searchres_len = 0
+              var_match_keys = qdef.getVarMatchKeys()
+              if var_match_keys:
+                  # Check the catalog for items in the worklist.
+                  catalog = getToolByName(self, 'portal_catalog')
+                  dict = {}
+                  for k in var_match_keys:
+                      v = qdef.getVarMatch(k)
+                      v_fmt = map(lambda x, info=info: x%info, v)
+                      dict[k] = v_fmt
                   # Patch for ERP5 by JP Smets in order
                   # to implement worklists and search of local roles
-                  if dict.has_key('local_roles'):
-                    fmt_data._push({'local_roles': join(guard.roles,';')})
-                  else:
-                    fmt_data._push({'local_roles': ''})
-                  res.append((id, {'name': qdef.actbox_name % fmt_data,
-                                  'url': qdef.actbox_url % fmt_data,
-                                  'worklist_id': id,
-                                  'workflow_title': self.title,
-                                  'workflow_id': self.id,
-                                  'permissions': (),  # Predetermined.
-                                  'category': qdef.actbox_category}))
-                  fmt_data._pop()
-          res.sort()
-          return map((lambda (id, val): val), res)
-
-        # Return Cache
-        _listGlobalActions = CachingMethod(_listGlobalActions, id='listGlobalActions', cache_duration = 300)
-        user = str(_getAuthenticatedUser(self))
-        return _listGlobalActions(user=user, id=self.id, portal_path=self._getPortalRoot().getPhysicalPath())
-
-
-DCWorkflowDefinition.listGlobalActions = PatchedDCWorkflowDefinition.listGlobalActions
+                  if not (guard is None or guard.check(sm, self, portal)):
+                      dict['local_roles'] = guard.roles
+                  # Patch to use ZSQLCatalog and get high speed
+                  # LOG("PatchedDCWorkflowDefinition", 0, dict)
+                  searchres_len = int(apply(catalog.countResults, (), dict)[0][0])
+                  if searchres_len == 0:
+                      continue
+              if fmt_data is None:
+                  fmt_data = TemplateDict()
+                  fmt_data._push(info)
+              fmt_data._push({'count': searchres_len})
+              # Patch for ERP5 by JP Smets in order
+              # to implement worklists and search of local roles
+              if dict.has_key('local_roles'):
+                fmt_data._push({'local_roles': join(guard.roles,';')})
+              else:
+                fmt_data._push({'local_roles': ''})
+              res.append((id, {'name': qdef.actbox_name % fmt_data,
+                              'url': qdef.actbox_url % fmt_data,
+                              'worklist_id': id,
+                              'workflow_title': self.title,
+                              'workflow_id': self.id,
+                              'permissions': (),  # Predetermined.
+                              'category': qdef.actbox_category}))
+              fmt_data._pop()
+      res.sort()
+      return map((lambda (id, val): val), res)
+
+    # Return Cache
+    _listGlobalActions = CachingMethod(_listGlobalActions, id='listGlobalActions', cache_duration = 300)
+    user = str(_getAuthenticatedUser(self))
+    return _listGlobalActions(user=user, id=self.id, portal_path=self._getPortalRoot().getPhysicalPath())
+
+
+DCWorkflowDefinition.listGlobalActions = DCWorkflowDefinition_listGlobalActions
 
 ##############################################################################
 # Stribger repair of BTreeFolder2
@@ -516,133 +515,131 @@ from AccessControl import ModuleSecurityInfo
 ModuleSecurityInfo('Products.DCWorkflow.DCWorkflow').declarePublic('ValidationFailed')
 
 
-class ERP5DCWorkflowDefinition (DCWorkflowDefinition):
-
-    def _executeTransition(self, ob, tdef=None, kwargs=None):
-        '''
-        Private method.
-        Puts object in a new state.
-        '''
-        sci = None
-        econtext = None
-        moved_exc = None
-
-        # Figure out the old and new states.
-        old_sdef = self._getWorkflowStateOf(ob)
-        old_state = old_sdef.getId()
-        if tdef is None:
-            new_state = self.initial_state
-            former_status = {}
+def DCWorkflowDefinition_executeTransition(self, ob, tdef=None, kwargs=None):
+    '''
+    Private method.
+    Puts object in a new state.
+    '''
+    sci = None
+    econtext = None
+    moved_exc = None
+
+    # Figure out the old and new states.
+    old_sdef = self._getWorkflowStateOf(ob)
+    old_state = old_sdef.getId()
+    if tdef is None:
+        new_state = self.initial_state
+        former_status = {}
+    else:
+        new_state = tdef.new_state_id
+        if not new_state:
+            # Stay in same state.
+            new_state = old_state
+        former_status = self._getStatusOf(ob)
+    new_sdef = self.states.get(new_state, None)
+    if new_sdef is None:
+        raise WorkflowException, (
+            'Destination state undefined: ' + new_state)
+
+    # Execute the "before" script.
+    before_script_success = 1
+    if tdef is not None and tdef.script_name:
+        script = self.scripts[tdef.script_name]
+        # Pass lots of info to the script in a single parameter.
+        sci = StateChangeInfo(
+            ob, self, former_status, tdef, old_sdef, new_sdef, kwargs)
+        try:
+            #LOG('_executeTransition', 0, "script = %s, sci = %s" % (repr(script), repr(sci)))
+            script(sci)  # May throw an exception.
+        except ValidationFailed, validation_exc:
+            before_script_success = 0
+            before_script_error_message = validation_exc
+        except ObjectMoved, moved_exc:
+            ob = moved_exc.getNewObject()
+            # Re-raise after transition
+
+    # Update variables.
+    state_values = new_sdef.var_values
+    if state_values is None: state_values = {}
+    tdef_exprs = None
+    if tdef is not None: tdef_exprs = tdef.var_exprs
+    if tdef_exprs is None: tdef_exprs = {}
+    status = {}
+    for id, vdef in self.variables.items():
+        if not vdef.for_status:
+            continue
+        expr = None
+        if state_values.has_key(id):
+            value = state_values[id]
+        elif tdef_exprs.has_key(id):
+            expr = tdef_exprs[id]
+        elif not vdef.update_always and former_status.has_key(id):
+            # Preserve former value
+            value = former_status[id]
         else:
-            new_state = tdef.new_state_id
-            if not new_state:
-                # Stay in same state.
-                new_state = old_state
-            former_status = self._getStatusOf(ob)
-        new_sdef = self.states.get(new_state, None)
-        if new_sdef is None:
-            raise WorkflowException, (
-                'Destination state undefined: ' + new_state)
-
-        # Execute the "before" script.
-        before_script_success = 1
-        if tdef is not None and tdef.script_name:
-            script = self.scripts[tdef.script_name]
-            # Pass lots of info to the script in a single parameter.
-            sci = StateChangeInfo(
-                ob, self, former_status, tdef, old_sdef, new_sdef, kwargs)
-            try:
-                #LOG('_executeTransition', 0, "script = %s, sci = %s" % (repr(script), repr(sci)))
-                script(sci)  # May throw an exception.
-            except ValidationFailed, validation_exc:
-                before_script_success = 0
-                before_script_error_message = validation_exc
-            except ObjectMoved, moved_exc:
-                ob = moved_exc.getNewObject()
-                # Re-raise after transition
-
-        # Update variables.
-        state_values = new_sdef.var_values
-        if state_values is None: state_values = {}
-        tdef_exprs = None
-        if tdef is not None: tdef_exprs = tdef.var_exprs
-        if tdef_exprs is None: tdef_exprs = {}
-        status = {}
-        for id, vdef in self.variables.items():
-            if not vdef.for_status:
-                continue
-            expr = None
-            if state_values.has_key(id):
-                value = state_values[id]
-            elif tdef_exprs.has_key(id):
-                expr = tdef_exprs[id]
-            elif not vdef.update_always and former_status.has_key(id):
-                # Preserve former value
-                value = former_status[id]
+            if vdef.default_expr is not None:
+                expr = vdef.default_expr
             else:
-                if vdef.default_expr is not None:
-                    expr = vdef.default_expr
-                else:
-                    value = vdef.default_value
-            if expr is not None:
-                # Evaluate an expression.
-                if econtext is None:
-                    # Lazily create the expression context.
-                    if sci is None:
-                        sci = StateChangeInfo(
-                            ob, self, former_status, tdef,
-                            old_sdef, new_sdef, kwargs)
-                    econtext = createExprContext(sci)
-                value = expr(econtext)
-            status[id] = value
-
-        # Do not proceed in case of failure of before script
-        if not before_script_success:
-            status[self.state_var] = old_state # Remain in state
-            tool = aq_parent(aq_inner(self))
-            tool.setStatusOf(self.id, ob, status)
-            sci = StateChangeInfo(
-                ob, self, status, tdef, old_sdef, new_sdef, kwargs)
-            sci.setWorkflowVariable(ob, workflow_id=self.id, error_message = before_script_error_message)
-            return new_sdef
-
-        # Update state.
-        status[self.state_var] = new_state
+                value = vdef.default_value
+        if expr is not None:
+            # Evaluate an expression.
+            if econtext is None:
+                # Lazily create the expression context.
+                if sci is None:
+                    sci = StateChangeInfo(
+                        ob, self, former_status, tdef,
+                        old_sdef, new_sdef, kwargs)
+                econtext = createExprContext(sci)
+            value = expr(econtext)
+        status[id] = value
+
+    # Do not proceed in case of failure of before script
+    if not before_script_success:
+        status[self.state_var] = old_state # Remain in state
         tool = aq_parent(aq_inner(self))
         tool.setStatusOf(self.id, ob, status)
-
-        # Make sure that the error message is empty. # Why ?
-        #sci = StateChangeInfo(
-        #    ob, self, status, tdef, old_sdef, new_sdef, kwargs)
-        #sci.setWorkflowVariable(ob, error_message = '')
-
-        # Update role to permission assignments.
-        self.updateRoleMappingsFor(ob)
-
-        # Execute the "after" script.
-        if tdef is not None and tdef.after_script_name:
-            # Script can be either script or workflow method
-            #LOG('_executeTransition', 0, 'new_sdef.transitions = %s' % (repr(new_sdef.transitions)))
-            if tdef.after_script_name in filter(lambda k: self.transitions[k].trigger_type == TRIGGER_WORKFLOW_METHOD,
-                                                                                     new_sdef.transitions):
-              script = getattr(ob, convertToMixedCase(tdef.after_script_name))
-              script()
-            else:
-              script = self.scripts[tdef.after_script_name]
-              # Pass lots of info to the script in a single parameter.
-              sci = StateChangeInfo(
-                  ob, self, status, tdef, old_sdef, new_sdef, kwargs)
-              script(sci)  # May throw an exception.
-
-        # Return the new state object.
-        if moved_exc is not None:
-            # Propagate the notification that the object has moved.
-            raise moved_exc
+        sci = StateChangeInfo(
+            ob, self, status, tdef, old_sdef, new_sdef, kwargs)
+        sci.setWorkflowVariable(ob, workflow_id=self.id, error_message = before_script_error_message)
+        return new_sdef
+
+    # Update state.
+    status[self.state_var] = new_state
+    tool = aq_parent(aq_inner(self))
+    tool.setStatusOf(self.id, ob, status)
+
+    # Make sure that the error message is empty. # Why ?
+    #sci = StateChangeInfo(
+    #    ob, self, status, tdef, old_sdef, new_sdef, kwargs)
+    #sci.setWorkflowVariable(ob, error_message = '')
+
+    # Update role to permission assignments.
+    self.updateRoleMappingsFor(ob)
+
+    # Execute the "after" script.
+    if tdef is not None and tdef.after_script_name:
+        # Script can be either script or workflow method
+        #LOG('_executeTransition', 0, 'new_sdef.transitions = %s' % (repr(new_sdef.transitions)))
+        if tdef.after_script_name in filter(lambda k: self.transitions[k].trigger_type == TRIGGER_WORKFLOW_METHOD,
+                                                                                  new_sdef.transitions):
+          script = getattr(ob, convertToMixedCase(tdef.after_script_name))
+          script()
         else:
-            return new_sdef
+          script = self.scripts[tdef.after_script_name]
+          # Pass lots of info to the script in a single parameter.
+          sci = StateChangeInfo(
+              ob, self, status, tdef, old_sdef, new_sdef, kwargs)
+          script(sci)  # May throw an exception.
+
+    # Return the new state object.
+    if moved_exc is not None:
+        # Propagate the notification that the object has moved.
+        raise moved_exc
+    else:
+        return new_sdef
 
 
-DCWorkflowDefinition._executeTransition = ERP5DCWorkflowDefinition._executeTransition
+DCWorkflowDefinition._executeTransition = DCWorkflowDefinition_executeTransition
 
 # This patch allows to use workflowmethod as an after_script
 # However, the right way of doing would be to have a combined state of TRIGGER_USER_ACTION and TRIGGER_WORKFLOW_METHOD
@@ -660,164 +657,164 @@ TransitionDefinition.getAvailableScriptIds = ERP5TransitionDefinition.getAvailab
 
 ##############################################################################
 # Adding commit_prepare to the zodb transaction
-from ZODB import Transaction
-
-#class ERP5Transaction(Transaction):
-
-hosed = Transaction.hosed
-free_transaction = Transaction.free_transaction
-jar_cmp = Transaction.jar_cmp
-
-def commit(self, subtransaction=None):
-    """Finalize the transaction."""
-    objects = self._objects
-
-    subjars = []
-    if subtransaction:
-        if self._sub is None:
-            # Must store state across multiple subtransactions
-            # so that the final commit can commit all subjars.
-            self._sub = {}
-    else:
-        if self._sub is not None:
-            # This commit is for a top-level transaction that
-            # has previously committed subtransactions.  Do
-            # one last subtransaction commit to clear out the
-            # current objects, then commit all the subjars.
-            if objects:
-                self.commit(1)
-                objects = []
-            subjars = self._sub.values()
-            subjars.sort(jar_cmp)
-            self._sub = None
-
-            # If there were any non-subtransaction-aware jars
-            # involved in earlier subtransaction commits, we need
-            # to add them to the list of jars to commit.
-            if self._non_st_objects is not None:
-                objects.extend(self._non_st_objects)
-                self._non_st_objects = None
-
-    if (objects or subjars) and hosed:
-        # Something really bad happened and we don't
-        # trust the system state.
-        raise POSException.TransactionError, hosed_msg
-
-    # It's important that:
-    #
-    # - Every object in self._objects is either committed or
-    #   aborted.
-    #
-    # - For each object that is committed we call tpc_begin on
-    #   it's jar at least once
-    #
-    # - For every jar for which we've called tpc_begin on, we
-    #   either call tpc_abort or tpc_finish. It is OK to call
-    #   these multiple times, as the storage is required to ignore
-    #   these calls if tpc_begin has not been called.
-    #
-    # - That we call tpc_begin() in a globally consistent order,
-    #   so that concurrent transactions involving multiple storages
-    #   do not deadlock.
-    try:
-        ncommitted = 0
-        # Do prepare until number of jars is stable - this could
-        # create infinite loop
-        jars_len = -1
-        jars = self._get_jars(objects, subtransaction)
-        while len(jars) != jars_len:
-          jars_len = len(jars)
-          self._commit_prepare(jars, subjars, subtransaction)
-          jars = self._get_jars(objects, subtransaction)
+try:
+    from ZODB import Transaction
+    
+    hosed = Transaction.hosed
+    free_transaction = Transaction.free_transaction
+    jar_cmp = Transaction.jar_cmp
+    
+    def commit(self, subtransaction=None):
+        """Finalize the transaction."""
+        objects = self._objects
+        
+        subjars = []
+        if subtransaction:
+            if self._sub is None:
+                # Must store state across multiple subtransactions
+                # so that the final commit can commit all subjars.
+                self._sub = {}
+        else:
+            if self._sub is not None:
+                # This commit is for a top-level transaction that
+                # has previously committed subtransactions.  Do
+                # one last subtransaction commit to clear out the
+                # current objects, then commit all the subjars.
+                if objects:
+                    self.commit(1)
+                    objects = []
+                subjars = self._sub.values()
+                subjars.sort(jar_cmp)
+                self._sub = None
+                
+                # If there were any non-subtransaction-aware jars
+                # involved in earlier subtransaction commits, we need
+                # to add them to the list of jars to commit.
+                if self._non_st_objects is not None:
+                    objects.extend(self._non_st_objects)
+                    self._non_st_objects = None
+
+        if (objects or subjars) and hosed:
+            # Something really bad happened and we don't
+            # trust the system state.
+            raise POSException.TransactionError, hosed_msg
+
+        # It's important that:
+        #
+        # - Every object in self._objects is either committed or
+        #   aborted.
+        #
+        # - For each object that is committed we call tpc_begin on
+        #   it's jar at least once
+        #
+        # - For every jar for which we've called tpc_begin on, we
+        #   either call tpc_abort or tpc_finish. It is OK to call
+        #   these multiple times, as the storage is required to ignore
+        #   these calls if tpc_begin has not been called.
+        #
+        # - That we call tpc_begin() in a globally consistent order,
+        #   so that concurrent transactions involving multiple storages
+        #   do not deadlock.
         try:
-            # If not subtransaction, then jars will be modified.
-            self._commit_begin(jars, subjars, subtransaction)
-            ncommitted += self._commit_objects(objects)
-            if not subtransaction:
-                # Unless this is a really old jar that doesn't
-                # implement tpc_vote(), it must raise an exception
-                # if it can't commit the transaction.
-                for jar in jars:
-                    try:
-                        vote = jar.tpc_vote
-                    except AttributeError:
-                        pass
-                    else:
-                        vote(self)
-
-            # Handle multiple jars separately.  If there are
-            # multiple jars and one fails during the finish, we
-            # mark this transaction manager as hosed.
-            if len(jars) == 1:
-                self._finish_one(jars[0])
-            else:
-                self._finish_many(jars)
-        except:
-            # Ugh, we got an got an error during commit, so we
-            # have to clean up.  First save the original exception
-            # in case the cleanup process causes another
-            # exception.
-            error = sys.exc_info()
+            ncommitted = 0
+            # Do prepare until number of jars is stable - this could
+            # create infinite loop
+            jars_len = -1
+            jars = self._get_jars(objects, subtransaction)
+            while len(jars) != jars_len:
+                jars_len = len(jars)
+                self._commit_prepare(jars, subjars, subtransaction)
+                jars = self._get_jars(objects, subtransaction)
             try:
-                self._commit_error(objects, ncommitted, jars, subjars)
+                # If not subtransaction, then jars will be modified.
+                self._commit_begin(jars, subjars, subtransaction)
+                ncommitted += self._commit_objects(objects)
+                if not subtransaction:
+                    # Unless this is a really old jar that doesn't
+                    # implement tpc_vote(), it must raise an exception
+                    # if it can't commit the transaction.
+                    for jar in jars:
+                        try:
+                            vote = jar.tpc_vote
+                        except AttributeError:
+                            pass
+                        else:
+                            vote(self)
+
+                # Handle multiple jars separately.  If there are
+                # multiple jars and one fails during the finish, we
+                # mark this transaction manager as hosed.
+                if len(jars) == 1:
+                    self._finish_one(jars[0])
+                else:
+                    self._finish_many(jars)
             except:
-                LOG('ZODB', ERROR,
-                    "A storage error occured during transaction "
-                    "abort.  This shouldn't happen.",
-                    error=error)
-            raise error[0], error[1], error[2]
-    finally:
-        del objects[:] # clear registered
-        if not subtransaction and self._id is not None:
-            free_transaction()
-
-def _commit_prepare(self, jars, subjars, subtransaction):
-    if subtransaction:
-        assert not subjars
-        for jar in jars:
-            try:
-                jar.tpc_prepare(self, subtransaction)
-            except TypeError:
-                # Assume that TypeError means that tpc_begin() only
-                # takes one argument, and that the jar doesn't
-                # support subtransactions.
-                jar.tpc_prepare(self)
-            except AttributeError:
-                # Assume that KeyError means that tpc_prepare
-                # not available
-                pass
-    else:
-        # Merge in all the jars used by one of the subtransactions.
-
-        # When the top-level subtransaction commits, the tm must
-        # call commit_sub() for each jar involved in one of the
-        # subtransactions.  The commit_sub() method should call
-        # tpc_begin() on the storage object.
-
-        # It must also call tpc_begin() on jars that were used in
-        # a subtransaction but don't support subtransactions.
-
-        # These operations must be performed on the jars in order.
-
-        # Modify jars inplace to include the subjars, too.
-        jars += subjars
-        jars.sort(jar_cmp)
-        # assume that subjars is small, so that it's cheaper to test
-        # whether jar in subjars than to make a dict and do has_key.
-        for jar in jars:
-            #if jar in subjars:
-            #  pass
-            #else:
-            try:
-                jar.tpc_prepare(self)
-            except AttributeError:
-                # Assume that KeyError means that tpc_prepare
-                # not available
-                pass
-
-Transaction.Transaction.commit = commit
-Transaction.Transaction._commit_prepare = _commit_prepare
-
+                # Ugh, we got an got an error during commit, so we
+                # have to clean up.  First save the original exception
+                # in case the cleanup process causes another
+                # exception.
+                error = sys.exc_info()
+                try:
+                    self._commit_error(objects, ncommitted, jars, subjars)
+                except:
+                    LOG('ZODB', ERROR,
+                        "A storage error occured during transaction "
+                        "abort.  This shouldn't happen.",
+                        error=error)
+                    raise error[0], error[1], error[2]
+        finally:
+            del objects[:] # clear registered
+            if not subtransaction and self._id is not None:
+                free_transaction()
+
+    def _commit_prepare(self, jars, subjars, subtransaction):
+        if subtransaction:
+            assert not subjars
+            for jar in jars:
+                try:
+                    jar.tpc_prepare(self, subtransaction)
+                except TypeError:
+                    # Assume that TypeError means that tpc_begin() only
+                    # takes one argument, and that the jar doesn't
+                    # support subtransactions.
+                    jar.tpc_prepare(self)
+                except AttributeError:
+                    # Assume that KeyError means that tpc_prepare
+                    # not available
+                    pass
+        else:
+            # Merge in all the jars used by one of the subtransactions.
+            
+            # When the top-level subtransaction commits, the tm must
+            # call commit_sub() for each jar involved in one of the
+            # subtransactions.  The commit_sub() method should call
+            # tpc_begin() on the storage object.
+            
+            # It must also call tpc_begin() on jars that were used in
+            # a subtransaction but don't support subtransactions.
+            
+            # These operations must be performed on the jars in order.
+            
+            # Modify jars inplace to include the subjars, too.
+            jars += subjars
+            jars.sort(jar_cmp)
+            # assume that subjars is small, so that it's cheaper to test
+            # whether jar in subjars than to make a dict and do has_key.
+            for jar in jars:
+                #if jar in subjars:
+                #  pass
+                #else:
+                try:
+                    jar.tpc_prepare(self)
+                except AttributeError:
+                    # Assume that KeyError means that tpc_prepare
+                    # not available
+                    pass
+
+    Transaction.Transaction.commit = commit
+    Transaction.Transaction._commit_prepare = _commit_prepare
+except ImportError:
+    pass
 
 
 ##############################################################################
@@ -825,77 +822,73 @@ Transaction.Transaction._commit_prepare = _commit_prepare
 
 from Products.CMFCore.WorkflowTool import WorkflowTool
 
-class ERP5WorkflowTool(WorkflowTool):
+def WorkflowTool_wrapWorkflowMethod(self, ob, method_id, func, args, kw):
 
-    def wrapWorkflowMethod(self, ob, method_id, func, args, kw):
+    """ To be invoked only by WorkflowCore.
+        Allows a workflow definition to wrap a WorkflowMethod.
 
-        """ To be invoked only by WorkflowCore.
-            Allows a workflow definition to wrap a WorkflowMethod.
+        By default, the workflow tool takes the first workflow wich
+        support the method_id. In ERP5, with Interaction Worfklows, we
+        may have many workflows wich can support a worfklow method,
+        that's why we need this patch
 
-            By default, the workflow tool takes the first workflow wich
-            support the method_id. In ERP5, with Interaction Worfklows, we
-            may have many workflows wich can support a worfklow method,
-            that's why we need this patch
-
-            We should have 1 or 0 classic workflow (ie a DCWorkflow), and
-            0 or many Interaction workflows. We should take care that the
-            method will be called once
-        """
-        wf_list = []
-        wfs = self.getWorkflowsFor(ob)
-        if wfs:
-            for w in wfs:
-                #LOG('ERP5WorkflowTool.wrapWorkflowMethod, is wfMSupported', 0, repr(( w.isWorkflowMethodSupported(ob, method_id), w.getId(), ob, method_id )))
-                if (hasattr(w, 'isWorkflowMethodSupported')
-                    and w.isWorkflowMethodSupported(ob, method_id)):
-                    #wf = w
-                    #break
-                    wf_list.append(w)
-        else:
-            wfs = ()
-        if len(wf_list)==0:
-            return apply(func, args, kw)
-        no_interaction = 0
-        for w in wf_list:
-          if w.__class__.__name__ != 'InteractionWorkflowDefinition':
-            no_interaction = 1
-        for w in wfs:
-            w.notifyBefore(ob, method_id, args=args, kw=kw)
-        # Check if there is at least 1 non interaction workflow
-        if no_interaction:
-          for w in wf_list:
-             if w.__class__.__name__ != 'InteractionWorkflowDefinition':
-              result = self._invokeWithNotification(
-                  [], ob, method_id, w.wrapWorkflowMethod,
-                  (ob, method_id, func, args, kw), {})
-        else:
-          result = apply(func, args, kw)
+        We should have 1 or 0 classic workflow (ie a DCWorkflow), and
+        0 or many Interaction workflows. We should take care that the
+        method will be called once
+    """
+    wf_list = []
+    wfs = self.getWorkflowsFor(ob)
+    if wfs:
         for w in wfs:
-            w.notifySuccess(ob, method_id, result, args=args, kw=kw)
+            #LOG('ERP5WorkflowTool.wrapWorkflowMethod, is wfMSupported', 0, repr(( w.isWorkflowMethodSupported(ob, method_id), w.getId(), ob, method_id )))
+            if (hasattr(w, 'isWorkflowMethodSupported')
+                and w.isWorkflowMethodSupported(ob, method_id)):
+                #wf = w
+                #break
+                wf_list.append(w)
+    else:
+        wfs = ()
+    if len(wf_list)==0:
+        return apply(func, args, kw)
+    no_interaction = 0
+    for w in wf_list:
+      if w.__class__.__name__ != 'InteractionWorkflowDefinition':
+        no_interaction = 1
+    for w in wfs:
+        w.notifyBefore(ob, method_id, args=args, kw=kw)
+    # Check if there is at least 1 non interaction workflow
+    if no_interaction:
+      for w in wf_list:
+          if w.__class__.__name__ != 'InteractionWorkflowDefinition':
+            result = self._invokeWithNotification(
+                [], ob, method_id, w.wrapWorkflowMethod,
+                (ob, method_id, func, args, kw), {})
+    else:
+      result = apply(func, args, kw)
+    for w in wfs:
+        w.notifySuccess(ob, method_id, result, args=args, kw=kw)
 
-WorkflowTool.wrapWorkflowMethod = ERP5WorkflowTool.wrapWorkflowMethod
+WorkflowTool.wrapWorkflowMethod = WorkflowTool_wrapWorkflowMethod
 
 from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
 
-class ERP5DCWorkflow(DCWorkflowDefinition):
-
-    def notifyBefore(self, ob, action, args=None, kw=None):
-        '''
-        Notifies this workflow of an action before it happens,
-        allowing veto by exception.  Unless an exception is thrown, either
-        a notifySuccess() or notifyException() can be expected later on.
-        The action usually corresponds to a method name.
-        '''
-        pass
+def DCWorkflowDefinition_notifyBefore(self, ob, action, args=None, kw=None):
+    '''
+    Notifies this workflow of an action before it happens,
+    allowing veto by exception.  Unless an exception is thrown, either
+    a notifySuccess() or notifyException() can be expected later on.
+    The action usually corresponds to a method name.
+    '''
+    pass
 
-    def notifySuccess(self, ob, action, result, args=None, kw=None):
-        '''
-        Notifies this workflow that an action has taken place.
-        '''
-        pass
+def DCWorkflowDefinition_notifySuccess(self, ob, action, result, args=None, kw=None):
+    '''
+    Notifies this workflow that an action has taken place.
+    '''
+    pass
 
-DCWorkflowDefinition.notifyBefore = ERP5DCWorkflow.notifyBefore
-DCWorkflowDefinition.notifySuccess = ERP5DCWorkflow.notifySuccess
+DCWorkflowDefinition.notifyBefore = DCWorkflowDefinition_notifyBefore
+DCWorkflowDefinition.notifySuccess = DCWorkflowDefinition_notifySuccess
 
 ##############################################################################
 # Make sure the xml export will be ordered
@@ -903,7 +896,10 @@ DCWorkflowDefinition.notifySuccess = ERP5DCWorkflow.notifySuccess
 from Shared.DC.xml import ppml
 from base64 import encodestring
 from cStringIO import StringIO
-from ZODB.referencesf import referencesf
+try:
+  from ZODB.serialize import referencesf
+except ImportError:
+  from ZODB.referencesf import referencesf
 from ZODB.ExportImport import TemporaryFile
 from pickle import Pickler, EMPTY_DICT, MARK, DICT
 from cPickle import loads, dumps
@@ -1911,3 +1907,21 @@ def erp5_new_traverse(request, path, response=None, validated_hook=None):
 
 BaseRequest.traverse = erp5_new_traverse
 
+######################################################################################
+# AttrDict patch for more dict-like methods.
+try:
+    from App.ProductContext import AttrDict
+
+    def AttrDict_getitem(self, name):
+        try:
+            return getattr(self.ob, name)
+        except AttributeError:
+            raise KeyError
+
+    def AttrDict_has_key(self, name):
+        return hasattr(self.ob, name)
+
+    AttrDict.__getitem__ = AttrDict_getitem
+    AttrDict.has_key = AttrDict_has_key
+except ImportError:
+    pass