diff --git a/controllers/plugin_dbui.py b/controllers/plugin_dbui.py
index 8c8baaf30ac6cd1e44936dbca3407562acdb5b9c..085e96d942bdf075bf27681907e9575c8c79435d 100644
--- a/controllers/plugin_dbui.py
+++ b/controllers/plugin_dbui.py
@@ -119,7 +119,8 @@ def get_api():
     
     """
     from gluon.contrib import simplejson as json
-
+    dbui = local_import('plugin_dbui')
+    
     di = {}
     dbui = local_import('plugin_dbui')
     
@@ -141,7 +142,7 @@ def get_api():
     # the stores configuration for each table
     storeCfgs = {}
     for table in db:
-        storeCfgs[table._tablename] = cvtSvc.to_jsonstore(table)
+        storeCfgs[table._tablename] = dbui.to_jsonstore(table)
         
     # fill the javascript template
     app = request.application
diff --git a/models/plugin_dbui.py b/models/plugin_dbui.py
index 18b0c717aaeea1d26297cf8a913e6ff24c541898..7c27a738eca5d44df74c7c9f55b030042ec78a5d 100644
--- a/models/plugin_dbui.py
+++ b/models/plugin_dbui.py
@@ -44,27 +44,25 @@ plugins = PluginManager('dbui',
 
 # Start common services
 dbSvc = dbui.DbSvc(globals())
-cvtSvc = dbui.CvtSvc(globals())
 directSvc = dbui.DirectSvc(globals())
 
 # activate the debug mode
 # this session variable is set by the control index or debug
 dbSvc.debug = session.debug
-cvtSvc.debug = session.debug
 directSvc.debug = session.debug
 
 # register method available on the client side
 @directSvc.register
 def getForm(tablename): 
-    return cvtSvc.to_form_panel(db[tablename])
+    return dbui.to_formPanel(db[tablename])
 
 @directSvc.register
 def getGrid(tablename): 
-    return cvtSvc.to_grid_panel(db[tablename])
+    return dbui.to_gridPanel(db[tablename])
 
 @directSvc.register
 def getTree(node): 
-    return cvtSvc.to_tree(node)
+    return dbui.to_tree(node)
 
 @directSvc.register
 def create(data): 
diff --git a/models/widgets.py b/models/widgets.py
index 6be3dfade3907844fba3ac2d54c5c07bf34580ca..92c718949affe59abd2d6f26e89d1fe93681f851 100755
--- a/models/widgets.py
+++ b/models/widgets.py
@@ -184,24 +184,23 @@ gridModifier.set_filters(*filters,
 # The navigation tree
 #
 formNode = dbui.Node(T('Forms'))
-configurator = lambda tablename: cvtSvc.to_form_panel(db[tablename])
+configurator = lambda tablename: dbui.to_formPanel(db[tablename])
 formNode.add_children(db.tables, func=configurator)
 
 gridNode = dbui.Node(T('Tables'))
-configurator = lambda tablename: cvtSvc.to_grid_panel(db[tablename]) 
+configurator = lambda tablename: dbui.to_gridPanel(db[tablename]) 
 gridNode.add_children(db.tables, func=configurator) 
 
 reportNode = dbui.Node(T('Reports'))
-node = dbui.to_panel(html='salut ma poule')
+node = dbui.Panel(html='salut ma poule')
 reportNode.add_child(T('report_1'), node)
 
-panel = dbui.to_panel()
-fields = cvtSvc.to_form_items(dummy.foo1)
-selector = dbui.to_fieldset(fields, title=T('Select'))
-node = dbui.to_panelWithUrlSelector(panel,
-                                    selector,
-                                    controller="reports",
-                                    function="report_2")
+fields = dbui.to_fields(dummy.foo1)
+selector = dbui.FieldSet(items=fields, title=T('Select'))
+node = dbui.PanelWithUrlSelector(baseUrl=URL('reports', 'report_2'),
+                                 isMathJax=dbui.is_mathjax(),
+                                 panelCfg=dbui.Panel(),
+                                 selectorCfg=selector)
 reportNode.add_child(T('report_2'), node)
 
 viewportModifier = dbui.ViewportModifier()
diff --git a/modules/plugin_dbui/__init__.py b/modules/plugin_dbui/__init__.py
index 1988a8c846673c3290292d5ed233c18ddba12da5..9f0bed21624fd620827e837b46d555538e4d8c38 100755
--- a/modules/plugin_dbui/__init__.py
+++ b/modules/plugin_dbui/__init__.py
@@ -2,9 +2,42 @@
 
 """
 
-from cvtsvc import CvtSvc
+from converter import (to_field,
+                       to_fields,
+                       to_formPanel,
+                       to_gridColumn,
+                       to_gridColumnModel,
+                       to_gridFilter,
+                       to_gridPanel,
+                       to_jsonstore,
+                       to_tree)
 from dbsvc import DbSvc
 from directsvc import DBUI, DirectSvc
+from extjs import (CheckBox,
+                   ComboBox,
+                   CompositeField,
+                   DateField,
+                   DirectStore,
+                   Field,
+                   FieldSet,
+                   FormPanel,
+                   GridColumn,
+                   GridColumnModel,
+                   GridFilter,
+                   GridPanel,
+                   GridRowNumberer,
+                   GridTemplateColumn,
+                   GridWithFilter,
+                   NumberField,
+                   Panel,
+                   PanelWithUrlSelector,
+                   SetBox,
+                   Spacer,
+                   TabPanel,
+                   TextArea,
+                   TextField,
+                   TimeField,
+                   Viewport)
 from fieldsmodifier import FieldsModifier
 from formmodifier import configure_forms, FormModifier
 from gridmodifier import configure_grids, GridModifier
@@ -27,10 +60,5 @@ from helper import (as_list,
                     is_table_with_foreign_fields,
                     rows_serializer)
 from mapper import map_default, map_tabpanel
-from modifier import Spacer, Widget
-from navtree import (Node,
-                     to_fieldset,
-                     to_panel, 
-                     to_panelWithUrlSelector, 
-                     to_urlPanel)
+from navtree import Node
 from viewportmodifier import ViewportModifier
\ No newline at end of file
diff --git a/modules/plugin_dbui/converter.py b/modules/plugin_dbui/converter.py
new file mode 100644
index 0000000000000000000000000000000000000000..824930a66dd32cb52dd8b1629022c87d1fba7fb3
--- /dev/null
+++ b/modules/plugin_dbui/converter.py
@@ -0,0 +1,550 @@
+""" Converters transforming Web2py DAL objects into ExtJS widgets.
+
+Author: R. Le Gac
+
+"""
+from extjs import *
+from gluon import current
+from helper import (encode_field,
+                    get_field_validators,
+                    get_foreign_field,
+                    get_set_field, 
+                    is_foreign_field,
+                    is_set_field)
+from mapper import map_default
+
+# Associated gluon.dal.field type with an ExtJS widget
+# The dictionary contains configuration parameters of the Ext JS widget
+FTYPE_TO_XTYPE = {'boolean':   (CheckBox, {}),\
+                  'date':      (DateField, {'format': 'Y-m-d'}),\
+                  'datetime':  (DateField, {'format': 'Y-m-d H:i:s'}),\
+                  'double':    (NumberField, {'decimalPrecision':2,
+                                              'decimalSeparator': '.'}),\
+                  'id':        (TextField, {}),\
+                  'integer':   (NumberField, {}),\
+                  'password':  (TextField, {'inputType': 'password'}),\
+                  'reference': (ComboBox, {}),\
+                  'string':    (TextField, {}),\
+                  'text':      (TextArea, {}),\
+                  'time':      (TimeField, {}),\
+                  'upload':    (TextField, {'inputType': 'file'})}
+
+
+# constant defining a ExtJS store
+ROOT = 'records'
+STOREID = '%sStore'
+SUCCESS= 'success'
+TOTAL = 'count'
+
+
+def _to_field(field, **kwargs):
+    """Private converter. It is recommended to used to_field.
+    
+    Convert a gluon.dal.Field into an ExtJS.form.Field and its
+    inherited class. It does not handle composite field.
+    The conversion takes into account the FieldsModifier instructions.
+    
+    ExtJS configuration parameters are applied in the following order:
+    constructor, modifers, keyword arguments.
+    
+    """
+    T = current.T
+    
+    fieldname = field.name
+    tablename = field.tablename
+
+    f_name = encode_field(tablename, fieldname)
+                
+    # foreign key
+    if is_foreign_field(field):
+            
+        k_tablename, k_fieldname, k_key = get_foreign_field(field)
+        
+        cfg = ComboBox(name=f_name,
+                       hiddenName=f_name,
+                       displayField=encode_field(k_tablename, k_fieldname),
+                       valueField=encode_field(k_tablename, k_key),
+                       store=STOREID % k_tablename)
+
+    # set field
+    elif is_set_field(field):
+        cfg = SetBox(name=f_name,
+                     model={"setData": get_set_field(field)})
+        
+    # other types of fields
+    else:
+        cls, di = FTYPE_TO_XTYPE[field.type] 
+        cfg = cls(name=f_name, **di)
+
+    # field label translate in the local languqge
+    cfg["fieldLabel"] = str(T(field.label))
+
+    # default value and not null
+    # NOTE: the entryForm doesn't work when both default and
+    # notnull condition are defined.
+    if field.default:
+        cfg["value"] = str(field.default)
+    elif field.notnull:
+        cfg["allowBlank"] = False
+
+    # read only field
+    if field.readable and not field.writable:
+        cfg["readOnly"] = True
+
+    # tool tip
+    if field.comment:
+        cfg["tipText"] = field.comment
+     
+    # validator constraints
+    cfg.update(get_field_validators(field))
+    
+    # hide primary key
+    # hide field which are not readable and not writable
+    # hide field request by the form modifier
+    hidden = field.name == "id"
+    hidden = hidden or ((not field.readable) and (not field.writable))
+    
+    modifier_forms = PluginManager('dbui').dbui.modifier_forms
+    if tablename in modifier_forms:
+        if fieldname in modifier_forms[tablename].hidden_fields:
+            hidden = True
+            
+    if hidden:
+        cfg["hidden"] = True
+        cfg["hideLabel"] = True
+        cfg["readOnly"] = True
+
+    # configuration options set by the field_modifers
+    modifier_fields = PluginManager('dbui').dbui.modifier_fields
+    if tablename in modifier_fields:
+        if fieldname in modifier_fields[tablename].extjs_fields:
+            cfg.update(modifier_fields[tablename].extjs_fields[fieldname])
+
+    # configuration options from the keyword arguments
+    cfg.update(kwargs)
+    
+    return cfg
+
+
+def to_field(field, **kwargs):
+    """Convert a gluon.dal.Field into an Ext.form.Field and its inherited class
+    as well as into  a composite field, i.e Ext.form.CompositeField.
+     
+    Composite fields are set using the FieldsModifer.
+    
+    Return None if the field is comsumed by a CompositeField.
+
+    ExtJS configuration parameters are applied in the following order:
+    constructor, modifers, keyword arguments.
+
+    """
+    table = field.table
+    tablename = field.tablename
+    modifier_fields = PluginManager('dbui').dbui.modifier_fields
+
+    # do we have composite field for this table ?
+    composite_fields = None
+    if tablename in modifier_fields:
+        modifier_field = modifier_fields[tablename]
+        composite_fields = modifier_field.composite_fields
+
+    # main field of the composite field
+    # it will consume the embedded field too
+    if composite_fields and field.name in composite_fields.main:
+            
+        cfg = CompositeField()
+
+        for fieldname in composite_fields[field.name].fields:
+            cfg.append_items(_to_field(table[fieldname]))
+        
+        # use configuration options from the modifier
+        cfg.update(composite_fields[field.name].extjs)
+    
+    # an embedded field already used in a composite field
+    elif composite_fields and field.name in composite_fields.others:
+        cfg = None
+    
+    # a basic field
+    else:
+        cfg = _to_field(field)
+
+    # configuration options from keyword arguments
+    if cfg:
+        cfg.update(kwargs)
+    
+    return cfg
+
+    
+def to_fields(table):
+    """Convert a gluon.dal.Table into a list of Ext.form.Field,  
+    Ext.form.CompositeField or and Ext.form.FieldSet. 
+
+    Individual fields can be organized in Fieldset and in CompositeField.
+    They are defined in the application model using modifiers namely
+    the FormModifier and the FieldsModifier respectively.
+
+    The conversion takes into account the modifier instructions.
+    
+    """
+    li = []
+    tablename = table._tablename
+    modifier_forms =  PluginManager('dbui').dbui.modifier_forms
+
+    # do we have FieldSets
+    field_sets, modifier_form = None, None
+    if tablename in modifier_forms:
+        modifier_form = modifier_forms[tablename]
+        if modifier_form and modifier_form.field_sets:
+            field_sets = modifier_form.field_sets
+            
+    # Table with Ext.form.FieldSet and/or Ext.form.CompositeFields 
+    # and/or Ext.form.Field and/or Spacer
+
+    # NOTE: the field id is add in order to run this form
+    # in all context, create, update, destroy.
+    # It is add to the latest fieldset.
+    id_is_used = False 
+
+    if field_sets:
+        for fieldset in field_sets:
+            
+            cfg = FieldSet()            
+            for fieldname in fieldset.fields:
+                        
+                if isinstance(fieldname, Base):
+                    cfg.append_items(fieldname)
+                    continue
+
+                if fieldname == 'id':
+                    id_is_used = True
+
+                field = table[fieldname]
+                item = to_field(field)
+                if item:
+                    cfg.append_items(item)
+        
+            # fieldset configuration options ser by the modifier
+            cfg.update(fieldset.extjs)
+            li.append(cfg)
+            
+        # append the field Id the last field set
+        if not id_is_used:
+            li[-1].append_items(to_field(table['id']))
+
+    # Table with Ext.form.CompositeFields and/or Ext.form.Fields
+    else:
+        for field in table:
+            cfg = to_field(field)
+            if cfg:
+                li.append(cfg)
+    
+    # map the list of fields/fieldSets on Ext.form.formPanel
+    mapper = map_default
+    if modifier_form and modifier_form.mapper:
+        mapper = modifier_form.mapper
+
+    li = mapper(li)
+
+    return li
+
+
+def to_formPanel(table, **kwargs):
+    """Convert a gluon.dal.Table into a ExtJS App.form.FormPanel.
+    The conversion takes into account the form modifier instructions.
+
+    ExtJS configuration parameters are applied in the following order:
+    constructor, modifers, keyword arguments.
+    
+    """
+    tablename = table._tablename
+
+    fields = to_fields(table)
+    cfg = FormPanel(items=fields)
+
+    # add a store for non dummy database        
+    if table._db._uri:
+        cfg['store'] = STOREID % tablename
+    
+    # configuration options from form modifier
+    modifier_forms = PluginManager('dbui').dbui.modifier_forms
+    if tablename in modifier_forms:
+        cfg.update(modifier_forms[tablename].extjs)
+        
+    # configuration options form the keyword arguments
+    cfg.update(kwargs)
+    
+    return cfg 
+
+
+def to_gridColumn(field, **kwargs):
+    """Convert a gluon.dal.Field into an Ext.grid.Column.
+    The conversion takes into account the grid modifier instructions.
+
+    ExtJS configuration parameters are applied in the following order:
+    constructor, modifers, keyword arguments.
+            
+    """
+    T = current.T
+    
+    fieldname = field.name
+    tablename = field.tablename
+    
+    cfg = GridColumn(header=str(T(field.label)),
+                     sortable=True)
+    
+    # name of the field in the data store
+    # replace foreign key by the pointing column
+    if is_foreign_field(field):
+        k_tablename, k_fieldname, k_key = get_foreign_field(field)
+        index = encode_field(k_tablename, k_fieldname)
+
+    else:
+        index  = encode_field(tablename, fieldname)
+
+    cfg["dataIndex"] = index
+        
+    # hide the primary key
+    if fieldname == "id":
+        cfg["hidden"] = True
+
+    # hide field which are not readable and not writable
+    if (not field.readable) and (not field.writable):
+        cfg["hidden"] = True
+
+    # Hide fields request by the grid modifiers
+    modifier_grids = PluginManager('dbui').dbui.modifier_grids
+    if tablename in modifier_grids:
+        if fieldname in modifier_grids[tablename].hidden_columns:
+            cfg["hidden"] = True
+    
+    # configuration options from the grid modifier
+    if tablename in modifier_grids:
+        if fieldname in modifier_grids[tablename].configure_columns:
+            cfg.update(modifier_grids[tablename].configure_columns[fieldname])
+    
+    # configuration options from the keyword arguments
+    cfg.update(kwargs)
+    
+    return cfg
+
+
+def to_gridColumnModel(table):
+    """Convert a gluon.dal.Table into an Ext.grid.ColumnModel.
+    The conversion takes into account the grid modifier instructions.
+    
+    Currently the gridColumModel is implemented as a list of gridColumn.
+    
+    """
+    delete_columns = []
+    template_columns = []
+    tablename = table._tablename
+
+    # get modifier requirements
+    modifier_grids = PluginManager('dbui').dbui.modifier_grids
+    if tablename in modifier_grids:
+        delete_columns = modifier_grids[tablename].delete_columns
+        template_columns = modifier_grids[tablename].template_columns
+
+    # standard column
+    cfg = GridColumnModel()  
+    for field in table:
+        fieldname = field.name
+        if fieldname not in delete_columns:
+            cfg.append(to_gridColumn(field))
+    
+    # template column
+    for tpl in template_columns:
+        col = GridTemplateColumn(sortable=True)
+        col.update(tpl.extjs)
+        cfg.insert(tpl.position, col)
+
+    # row numbering in the first column
+    if modifier_grids[tablename].row_numbering:
+        cfg.insert(0, GridRowNumberer())
+        
+    return cfg
+
+
+def to_gridFilter(table, **kwargs):
+    """Convert a gluon.dal.Table into an ExtJS App.grid.GridFilter.
+    The grid filter is set using the grid modifiers.
+    Return an empty dictionary if not defined
+    
+    ExtJS configuration parameters are applied in the following order:
+    constructor, modifers, keyword arguments.
+    
+    """    
+    T = current.T
+    tablename = table._tablename
+     
+    modifier_grids = PluginManager('dbui').dbui.modifier_grids
+    if tablename not in modifier_grids:
+        return {}
+        
+    grid_filters = modifier_grids[tablename].grid_filters
+    if not grid_filters:
+        return {}
+    
+    di = GridFilter(title=T('Filter %s' % tablename))
+    
+    for (fieldname, operator, comment) in grid_filters.filters:
+        field = table[fieldname]
+        
+        # get the standard configuration for the field
+        cfg = to_field(field)
+        
+        # remove default value for fields which are not comboBox
+        if cfg['xtype'] != 'xcombobox':
+            cfg['value'] = ''
+            cfg['allowBlank'] = True
+        
+        # replace all textarea by textfield
+        if cfg['xtype'] == 'textarea':
+            cfg['xtype'] = 'textfield'
+        
+        # prepare the name for the where close
+        cfg['name'] = '[%s.%s]' % (tablename, fieldname)    
+            
+        # store information to customize the filter
+        cfg['filterComment'] = comment  
+        cfg['filterOperator'] = operator
+        cfg['filterType'] = field.type
+        
+        di.append_items(cfg)
+    
+    # configuration options from the grid modifier
+    di.update(grid_filters.extjs)
+    
+    # configuration option from keyword arguments
+    di.update(kwargs)
+    
+    return di
+    
+
+def to_gridPanel(table, **kwargs):
+    """Convert a gluon.dal.Table into an ExtJS App.grid.GridPanel.
+    The conversion takes into account the grid modifier instructions.
+
+    ExtJS configuration parameters are applied in the following order:
+    constructor, modifers, keyword arguments.
+    
+    """
+    tablename = table._tablename
+
+    cfg = GridPanel(columns=to_gridColumnModel(table),
+                    frame=False,
+                    viewConfig={'forceFit': True})
+    
+    # add a store for non dummy database        
+    if table._db._uri:
+        cfg['store'] = STOREID % tablename
+    
+    # configuration option from the grid modifier
+    modifier_grids = PluginManager('dbui').dbui.modifier_grids
+    if tablename in modifier_grids:
+        cfg.update(modifier_grids[tablename].extjs)
+
+    # configuration option from the keyword arguments
+    cfg.update(kwargs)
+    
+    # grid with filter
+    filter = to_gridFilter(table)
+    if filter:
+        cfg = GridWithFilter(panelCfg=dict(cfg),
+                             selectorCfg=filter)
+        
+    return cfg
+
+
+def to_jsonstore(table, **kwargs):
+    """Convert a gluon.dal.Table into an App.data.DirectStore.
+
+    ExtJS configuration parameters are applied in the following order:
+    constructor, modifers, keyword arguments.
+    
+    """
+    db = table._db
+    tablename = table._tablename
+
+    # NOTE: the configuration option baseParams defined the
+    # transactions parameters seen by the server
+    # This dictionary contains 3 keys:
+    #    tablename: name of the table in the database
+    #    dbFields: list of fields which should be red
+    #    where: define inner join, mainly to resolve foreign key
+    base_params = {'tableName': tablename, 'dbFields': []}
+    
+    cfg = DirectStore(autoLoad=False,
+                      autoSave=True,
+                      baseParams=base_params,
+                      fields=[],
+                      idProperty=encode_field(tablename,'id'),
+                      root=ROOT,
+                      successProperty=SUCCESS,
+                      storeId=STOREID % tablename,
+                      totalProperty=TOTAL)
+
+    for field in table:        
+        fieldname = field.name
+
+        # the field of the table
+        # encode field name and define default value
+        field_cfg = {'name': encode_field(tablename, fieldname)}
+        if field.default:
+            field_cfg['defaultValue'] = str(field.default)
+        
+        base_params['dbFields'].append([tablename, fieldname])
+        cfg['fields'].append(field_cfg)
+        
+        # NOTE: the store contains all fields of the table.
+        # It also contains the pointing values for foreign keys
+        # Therefore the store has the the id and the value for 
+        # each foreign key. This technique is use to resolve foreign key
+        # in form (combobox) and in grid.
+        if is_foreign_field(field):
+            
+            if 'where' not in base_params: base_params['where'] = []
+            k_tablename, k_fieldname, k_key = get_foreign_field(field)
+            
+            # encode the field name
+            k_field_cfg = {'name': encode_field(k_tablename, k_fieldname)}
+            base_params['dbFields'].append([k_tablename, k_fieldname])
+            cfg['fields'].append(k_field_cfg)
+            
+            # retrieve the default value for the foreign key
+            if field.default:
+                row = db(db[k_tablename].id == field.default).select().first()
+                if row:
+                    k_field_cfg['defaultValue'] = row[k_fieldname]
+            
+            # define the where close
+            nt = (tablename, fieldname, k_tablename, k_key)
+            base_params['where'].append("[%s.%s] == [%s.%s]" % nt)
+    
+    # configuration options from the keyword arguments
+    cfg.update(kwargs)
+    
+    return cfg
+
+
+def to_tree(node):
+    """Convert the Node structure into a list of dictionary
+    configuring Ext.tree.TreeNode.
+
+    The application navigation tree is defined using ViewportModifier.
+    
+    The argument node is required by ExtJS 3.4 but it is not
+    used here.
+    
+    """
+    cfg = []
+    
+    modifier_viewports = PluginManager('dbui').dbui.modifier_viewports
+
+    if modifier_viewports:
+        nav_nodes = modifier_viewports.nodes
+        for node in nav_nodes:
+            cfg.append(node.get_node())
+
+    return cfg
+
diff --git a/modules/plugin_dbui/cvtsvc.py b/modules/plugin_dbui/cvtsvc.py
deleted file mode 100644
index fef95b88f8d8a01b39969d36cbb08e5faadf85f2..0000000000000000000000000000000000000000
--- a/modules/plugin_dbui/cvtsvc.py
+++ /dev/null
@@ -1,526 +0,0 @@
-""" Service to convert gluon.dal object (Table, Field) into configuration 
-dictionary for ExtJS widget (Ext.form.FormPanel, Ext.grid.GridPanel, 
-Ext.data.DirectJsonStore). 
-
-It can also convert Node into Ext.tree.TreeNode
-    
-The table can belong to a to a dummy database.
-It is useful to create standalone form with the powerful validation 
-mechanism provided by web2py.
-    
-"""
-
-import modifier
-
-from basesvc import BaseSvc
-from gluon.dal import Field
-from helper import (encode_field,
-                    get_field_validators,
-                    get_foreign_field,
-                    get_set_field, 
-                    is_foreign_field,
-                    is_set_field)
-from mapper import map_default
-from modifier import Widget
-
-
-# Convert a field type into a widget xtype
-# The dictionary contain the configuration parameters of the Ext JS widget
-FTYPE_TO_XTYPE = {'boolean':   {'xtype': 'checkbox'},\
-                  'date':      {'xtype': 'datefield', 'format': 'Y-m-d'},\
-                  'datetime':  {'xtype': 'datefield', 'format': 'Y-m-d H:i:s'},\
-                  'double':    {'xtype': 'numberfield', 'decimalPrecision':2,
-                                                        'decimalSeparator': '.'},\
-                  'id':        {'xtype': 'textfield'},\
-                  'integer':   {'xtype': 'numberfield'},\
-                  'password':  {'xtype': 'textfield', 'inputType': 'password'},\
-                  'reference': {'xtype': 'xcombobox'},\
-                  'string':    {'xtype': 'textfield'},\
-                  'text':      {'xtype': 'textarea'},\
-                  'time':      {'xtype': 'timefield'},\
-                  'upload':    {'xtype': 'textfield', 'inputType': 'file'}}
-
-# constant defining a store
-ROOT = 'records'
-STOREID = '%sStore'
-SUCCESS= 'success'
-TOTAL = 'count'
-
-
-class CvtSvc(BaseSvc):
-    
-    
-    def __init__(self, environment):
-        BaseSvc.__init__(self, environment)
-
-
-    def to_column_model(self, field):
-        """Convert a gluon.dal.Field into a configuration dictionary
-        for and Ext.grid.Column.
-                
-        """
-        T = self.environment['T']
-        
-        fieldname = field.name
-        tablename = field.tablename
-        model = {'sortable': True}
-        
-        # column header
-        model["header"] = str(T(field.label))
-        
-        # replace foreign key by the pointing column
-        if is_foreign_field(field):
-            
-            k_tablename, k_fieldname, k_key = get_foreign_field(field)
-            model["dataIndex"] = encode_field(k_tablename, k_fieldname)
-        
-        # standard column
-        else:
-            model["dataIndex"] = encode_field(tablename, fieldname)
-            
-        # hide the primary key
-        if fieldname == "id":
-            model["hidden"] = True
-
-        # hide field which are not readable and not writable
-        if (not field.readable) and (not field.writable):
-            model["hidden"] = True
-
-        # Hide fields request by the grid modifiers
-        modifier_grids = self.environment['plugins'].dbui.modifier_grids
-        if tablename in modifier_grids:
-            if fieldname in modifier_grids[tablename].hidden_columns:
-                model["hidden"] = True
-                
-        return model
-
-
-    def to_columns_models(self, table):
-        """Convert a gluon.dal.Table into a configuration dictionary
-        for an the Ext.grid.ColumnModel.
-
-        """
-        
-        models = [] 
-        delete_columns = []
-        template_columns = []
-        
-        tablename = table._tablename
-        
-        # get modifier requirements
-        modifier_grids = self.environment['plugins'].dbui.modifier_grids
-        if tablename in modifier_grids:
-            configure_columns = modifier_grids[tablename].configure_columns
-            delete_columns = modifier_grids[tablename].delete_columns
-            template_columns = modifier_grids[tablename].template_columns
-        
-        # standard column
-        for field in table:
-            fieldname = field.name
-            if fieldname not in delete_columns:
-                model = self.to_column_model(field)
-                if fieldname in configure_columns:
-                    model.update(configure_columns[fieldname])
-                models.append(model)
-        
-        # template column
-        for tpl in template_columns:
-            col = {'xtype': 'templatecolumn', 'sortable': True}
-            col.update(tpl.extjs)
-            models.insert(tpl.position, col)
-
-        # row numbering in the first column
-        if modifier_grids[tablename].row_numbering:
-            models.insert(0, {'xtype': 'rownumberer'})
-            
-                
-        return models
-
-
-    def to_field_item(self, field):
-        """Convert a gluon.dal.Field into a configuration dictionary
-        for an Ext.formField.
-        
-        The field can also be translated into an Ext.form.CompositeField.
-        if it corresponds to the field field of the composite field.
-        Composite field are define using the FieldsModifer.
-        
-        Return None if the field is used in a CompositeField
-
-        """
-        modifier_fields = self.environment['plugins'].dbui.modifier_fields
-        table = field.table
-        tablename = field.tablename
-
-        # do we have composite field for this table ?
-        composite_fields = None
-        if tablename in modifier_fields:
-            modifier_field = modifier_fields[tablename]
-            composite_fields = modifier_field.composite_fields
-
-        # main field of the composite field
-        # it will consume the embedded field too
-        if composite_fields and field.name in composite_fields.main:
-                
-            cfg = {'xtype': 'compositefield', 'items':[]}
-
-            for fieldname in composite_fields[field.name].fields:
-                cfg['items'].append(self.to_field(table[fieldname]))
-                
-            cfg.update(composite_fields[field.name].extjs)
-            return cfg
-        
-        # an embedded field already used in a composite field
-        elif composite_fields and field.name in composite_fields.others:
-            return None
-        
-        # a standard field
-        else:
-            return self.to_field(field)
-
-
-    def to_field(self, field):
-        """Convert a gluon.dal.Field into a configuration dictionary for
-        an ExtJS.form.Field.
-        
-        The configuration dictionary can be tune using the FieldsModifier.
-        
-        """
-        T = self.environment['T']
-        
-        fieldname = field.name
-        tablename = field.tablename
-
-        cfg= {"name": encode_field(tablename, fieldname)}
-                    
-        # foreign key
-        if is_foreign_field(field):
-                
-            k_tablename, k_fieldname, k_key = get_foreign_field(field)
-            
-            cfg["xtype"] = "xcombobox"
-            cfg["hiddenName"] = encode_field(tablename, fieldname)
-            cfg["displayField"] = encode_field(k_tablename, k_fieldname)
-            cfg["valueField"] = encode_field(k_tablename, k_key)
-            cfg["store"] = STOREID % k_tablename
-    
-        # set field
-        elif is_set_field(field):
-            cfg["xtype"] = "xsetbox"
-            cfg["model"] = {"setData": get_set_field(field)}
-            
-        # other types of fields
-        else:
-            cfg.update(FTYPE_TO_XTYPE[field.type])
-
-        # field label
-        cfg["fieldLabel"] = str(T(field.label))
-
-        # default value and not null
-        # NOTE: the entryForm doesn't work when both default and
-        # notnull condition are defined.
-        if field.default:
-            cfg["value"] = str(field.default)
-        elif field.notnull:
-            cfg["allowBlank"] = False
-
-        # read only field
-        if field.readable and not field.writable:
-            cfg["readOnly"] = True
-
-        # tool tip
-        if field.comment:
-            cfg["tipText"] = field.comment
-         
-        # validators
-        cfg.update(get_field_validators(field))
-        
-        # hide primary key
-        # hide field which are not readable and not writable
-        # hide field request by the form modifier
-        hidden = field.name == "id"
-        hidden = hidden or ((not field.readable) and (not field.writable))
-        
-        modifier_forms = self.environment['plugins'].dbui.modifier_forms
-        if tablename in modifier_forms:
-            if fieldname in modifier_forms[tablename].hidden_fields:
-                hidden = True
-                
-        if hidden:
-            cfg["hidden"] = True
-            cfg["hideLabel"] = True
-            cfg["readOnly"] = True
-
-        # configuration options set by the field_modifers
-        modifier_fields = self.environment['plugins'].dbui.modifier_fields
-        if tablename in modifier_fields:
-            if fieldname in modifier_fields[tablename].extjs_fields:
-                cfg.update(modifier_fields[tablename].extjs_fields[fieldname])
-                
-        return cfg
-
-
-    def to_form_items(self, table):
-        """Convert a gluon.dal.Table into a list of Ext.form.Field,  
-        Ext.form.CompositeField or and Ext.form.FieldSet. 
-        
-        Composite fields are defined using FieldsModifier.
-        Field sets are defined using FormModifier.
-        
-        """
-        
-        items = []
-        
-        modifier_forms =  self.environment['plugins'].dbui.modifier_forms
-        tablename = table._tablename
-
-        # do we have FieldSets
-        field_sets, modifier_form = None, None
-        if tablename in modifier_forms:
-            modifier_form = modifier_forms[tablename]
-            if modifier_form and modifier_form.field_sets:
-                field_sets = modifier_form.field_sets
-                
-        # Table with Ext.form.FieldSet and/or Ext.form.CompositeFields 
-        # and/or Ext.form.Field and/or Spacer
-
-        # NOTE: the field id is add in order to run this form
-        # in all context, create, update, destroy.
-        # It is add to the latest fieldset.
-        id_is_used = False 
-
-        if field_sets:
-            for fieldset in field_sets:
-                
-                cfg = {'xtype': 'fieldset', 'items': []}
-                items.append(cfg)
-                
-                for fieldname in fieldset.fields:
-                            
-                    if isinstance(fieldname, Widget):
-                        cfg['items'].append(fieldname.extjs)
-                        continue
-
-                    if fieldname == 'id':
-                        id_is_used = True
-
-                    field = table[fieldname]
-                    item = self.to_field_item(field)
-                    if item:
-                        cfg['items'].append(item)
-            
-                cfg.update(fieldset.extjs)
-                
-            # append the field Id the last field set
-            if not id_is_used:
-                items[-1]['items'].append(self.to_field(table['id']))
-        
-        # Table with Ext.form.CompositeFields and/or Ext.form.Fields
-        else:
-            for field in table:
-                item = self.to_field_item(field)
-                if item:
-                    items.append(item)
-        
-        # map the list of fields/fieldSets on Ext.form.formPanel
-        mapper = map_default
-        if modifier_form and modifier_form.mapper:
-            mapper = modifier_form.mapper
-            
-        items = mapper(items)
- 
-        return items
-
-
-    def to_form_panel(self, table):
-        """Convert a gluon.dal.Table into a configuration dictionary
-        for the App.form.FormPanel.
-        
-        the configuration dictionary can be tunes using the FormModifier.
-        
-        """
-        tablename = table._tablename
-                
-        cfg = {'items': self.to_form_items(table),
-               'xtype': 'xform'}
-
-        # add a store for non dummy database        
-        if table._db._uri:
-            cfg['store'] = STOREID % tablename
-        
-        # handle form modifier
-        modifier_forms = self.environment['plugins'].dbui.modifier_forms
-        if tablename in modifier_forms:
-            cfg.update(modifier_forms[tablename].extjs)
-            
-        return cfg 
-
-
-    def to_grid_filter(self, table):
-        """Get configuration dictionary for the Ext.grid.GridFiler.
-        A grid filter is defined using the GridModifier.
-        
-        """
-        T = self.environment['T']
-        tablename = table._tablename
-        
-        modifier_grids = self.environment['plugins'].dbui.modifier_grids
-        if tablename not in modifier_grids:
-            return {}
-            
-        grid_filters = modifier_grids[tablename].grid_filters
-        if not grid_filters:
-            return {}
-        
-        di = {'xtype':'xgridfilter',
-              'items': [],
-              'title': T('Filter %s' % tablename)}
-        
-        for (fieldname, operator, comment) in grid_filters.filters:
-            field = table[fieldname]
-            
-            # get the standard configuration for the field
-            cfg = self.to_field(field)
-            
-            # remove default value for fields which are not comboBox
-            if cfg['xtype'] != 'xcombobox':
-                cfg['value'] = ''
-                cfg['allowBlank'] = True
-            
-            # replace all textarea by textfield
-            if cfg['xtype'] == 'textarea':
-                cfg['xtype'] = 'textfield'
-            
-            # prepare the name for the where close
-            cfg['name'] = '[%s.%s]' % (tablename, fieldname)    
-                
-            # store information to customize the filter
-            cfg['filterComment'] = comment  
-            cfg['filterOperator'] = operator
-            cfg['filterType'] = field.type
-            
-            di['items'].append(cfg)
-        
-        # user configuration options for Ext.form.FieldSet
-        di.update(grid_filters.extjs)
-        
-        return di
-        
-
-    def to_grid_panel(self, table):
-        """Convert a gluon.dal.Table into a configuration dictionary
-        for the App.grid.GridPanel.
-        
-        The configuration dictionary can be tuned using the GridModifier.
-        
-        """
-        tablename = table._tablename
-
-        cfg = {'columns': self.to_columns_models(table),
-               'frame': False,
-               'store': STOREID % tablename,
-               'viewConfig': {'forceFit': True},
-               'xtype': 'xgrid'}
-                
-        # handle the user configuration option for Ext.grid.GridPanel
-        modifier_grids = self.environment['plugins'].dbui.modifier_grids
-        if tablename in modifier_grids:
-            cfg.update(modifier_grids[tablename].extjs)
-
-        # grid with filter
-        filter = self.to_grid_filter(table)
-        if filter:
-            cfg = {'panelCfg': dict(cfg),
-                   'selectorCfg': filter,
-                   'xtype': 'xgridwithfilter'}
-            
-        return cfg
-
-
-    def to_jsonstore(self, table):
-        """convert a gluon.dal.Table into a configuration dictionary 
-        for the Ext.data.DirectJsonStore.
-        
-        """
-        db = table._db
-        tablename = table._tablename
-
-        # NOTE: the configuration option baseParams defined the
-        # transactions parameters seen by the server
-        # This dictionary contains 3 keys:
-        #    tablename: name of the table in the database
-        #    dbFields: list of fields which should be red
-        #    where: define inner join, mainly to resolve foreign key
-        base_params = {'tableName': tablename, 'dbFields': []}
-        
-        cfg = {'autoLoad': False,
-               'autoSave': True,
-               'baseParams': base_params,
-               'fields': [],
-               'idProperty': encode_field(tablename,'id'),
-               'root': ROOT,
-               'successProperty': SUCCESS,
-               'storeId': STOREID % tablename,
-               'totalProperty': TOTAL,
-               'xtype': 'xdirectstore'}
-
-        for field in table:        
-            fieldname = field.name
-    
-            # the field of the table
-            # encode field name and define default value
-            field_cfg = {'name': encode_field(tablename, fieldname)}
-            if field.default:
-                field_cfg['defaultValue'] = str(field.default)
-            
-            base_params['dbFields'].append([tablename, fieldname])
-            cfg['fields'].append(field_cfg)
-            
-            # NOTE: the store contains all fields of the table.
-            # It also contains the pointing values for foreign keys
-            # Therefore the store has the the id and the value for 
-            # each foreign key. This technique is use to resolve foreign key
-            # in form (combobox) and in grid.
-            if is_foreign_field(field):
-                
-                if 'where' not in base_params: base_params['where'] = []
-                k_tablename, k_fieldname, k_key = get_foreign_field(field)
-                
-                # encode the field name
-                k_field_cfg = {'name': encode_field(k_tablename, k_fieldname)}
-                base_params['dbFields'].append([k_tablename, k_fieldname])
-                cfg['fields'].append(k_field_cfg)
-                
-                # retrieve the default value for the foreign key
-                if field.default:
-                    row = db(db[k_tablename].id == field.default).select().first()
-                    if row:
-                        k_field_cfg['defaultValue'] = row[k_fieldname]
-                
-                # define the where close
-                nt = (tablename, fieldname, k_tablename, k_key)
-                base_params['where'].append("[%s.%s] == [%s.%s]" % nt)
-        
-        return cfg
-
-
-    def to_tree(self, node):
-        """Convert the Node structure into a list of dictionary
-        configuring Ext.tree.TreeNode.
-
-        Teh application navigation tree is defined using ViewportModifier.
-        
-        The argument node is required by ExtJS 3.4 but it is not
-        used here.
-        
-        """
-        cfg = []
-        
-        modifier_viewports = self.environment['plugins'].dbui.modifier_viewports
-
-        if modifier_viewports:
-            nav_nodes = modifier_viewports.nodes
-            for node in nav_nodes:
-                cfg.append(node.get_node())
-
-        return cfg
diff --git a/modules/plugin_dbui/dbsvc.py b/modules/plugin_dbui/dbsvc.py
index cc61c52f27f92779f7cbb88e1db11a282e8b305a..d84417d1d483aa091f747dd3d480b1be03d66fcb 100644
--- a/modules/plugin_dbui/dbsvc.py
+++ b/modules/plugin_dbui/dbsvc.py
@@ -3,7 +3,7 @@
 """
 
 from basesvc import BaseSvc
-from cvtsvc import ROOT, SUCCESS, TOTAL
+from converter import ROOT, SUCCESS, TOTAL
 from gluon.contrib import simplejson as json
 from helper import (encode_field, 
                     decode_field,
diff --git a/modules/plugin_dbui/extjs.py b/modules/plugin_dbui/extjs.py
new file mode 100644
index 0000000000000000000000000000000000000000..4b55ab33f65686582c3f8d6a45081eb0e2af425a
--- /dev/null
+++ b/modules/plugin_dbui/extjs.py
@@ -0,0 +1,184 @@
+""" ExtJS components configurators 
+
+Author: R. Le Gac
+
+"""
+
+from gluon import current
+from gluon.tools import PluginManager
+
+MSG_XTYPE = 'Invalid keyword "xtype"'
+
+
+class ExtJSException(BaseException): pass
+
+
+class Base(dict):
+    """Base class for ExtJS configurator.
+    A protection is set to avoid changing the xtype of the element.
+
+    Two helper functions append_items and append_plugins
+    to deal with items and plugins.
+    
+    """
+    xtype = None
+    
+    def __init__(self, **kwargs):
+
+        if 'xtype' in kwargs:
+            raise ExtJSException(MSG_XTYPE)
+
+        self['xtype'] = self.xtype
+        self.update(kwargs)
+
+
+    def _append(self, key, t):
+        li = list(t)
+        if key in self:
+            self[key].extend(li)
+        else:
+            self[key] = li
+
+
+    def append_items(self, *args):
+        self._append('items', args)
+
+        
+    def append_plugins(self, *args):
+        self._append('plugins', args)
+
+
+class CheckBox(Base):
+    """Configurator for Ext.form.Checkbox."""
+    xtype = 'checkbox'
+
+
+class ComboBox(Base):
+    """Configurator for App.form.CombBox."""
+    xtype = 'xcombobox'
+
+
+class CompositeField(Base):
+    """Configurator for Ext.form.CompositeField."""
+    xtype = 'compositefield'
+
+
+class DateField(Base):
+    """Configurator for Ext.form.DateField."""
+    xtype = 'datefield'
+
+
+class DirectStore(Base):
+    """Configurator for App.data.DirectStore."""
+    xtype = 'xdirectstore'
+
+
+class Field(Base):
+    """Configurator for Ext.form.Field."""
+    xtype = 'field'
+
+
+class FieldSet(Base):
+    """Configurator for Ext.form.FieldSet.
+
+    By default, the layout for children Field is set to anchor 99%.
+    It can be overwritten using the keywords defaults.
+       
+    """
+    xtype = 'fieldset'
+    
+    def __init__(self, **kwargs):
+        self['defaults'] = {'anchor': '99%'}
+        Base.__init__(self, **kwargs)
+
+
+class FormPanel(Base):
+    """Configurator for App.form.FormPanel."""
+    xtype = 'xform'
+
+
+class GridColumn(dict):
+    """Configurator for Ext.grid.Column."""
+
+
+class GridColumnModel(list):
+    """Configurator for Ext.grid.ColumnModel implemented 
+    as a list of GridColumn.
+    
+    """
+
+
+class GridFilter(Base):
+    """Configurator for App.grid.GridFilter."""
+    xtype = 'xgridfilter'
+
+
+class GridPanel(Base):
+    """Configurator for App.grid.Grid."""
+    xtype = 'xgrid'
+
+
+class GridRowNumberer(dict):
+    """Configurator for Ext.grid.RowNumberer."""
+    xtype = 'rownumberer'
+
+
+class GridTemplateColumn(Base):
+    """Configurator for Ext.grid.TemplateColumn."""
+    xtype = 'templatecolumn'
+
+
+class GridWithFilter(Base):
+    """Configurator for App.grid.GridWithFilter."""
+    xtype = 'xgridwithfilter'
+
+
+class NumberField(Base):
+    """Configurator for Ext.form.NumberField."""
+    xtype = 'numberfield'
+
+
+class Panel(Base):
+    """Configurator for Ext.Panel."""
+    xtype = 'panel'
+
+
+class PanelWithUrlSelector(Base):
+    """Configurator for App.PanelWithUrlSelector."""
+    xtype = 'xpanelwithurlselector'
+
+
+class SetBox(Base):
+    """Configurator for App.form.SetBox."""
+    xtype = 'xsetbox'
+
+
+class Spacer(Base):
+    """Configurator for Ext.Spacer."""
+    xtype = 'spacer'
+
+
+class TabPanel(Base):
+    """Configurator for Ext.TabPanel."""
+    xtype = 'tabpanel'
+
+
+class TextArea(Base):
+    """Configurator for Ext.form.TextArea."""
+    xtype = 'textarea'
+
+    
+class TextField(Base):
+    """Configurator for Ext.form.TextField."""
+    xtype = 'textfield'
+
+    
+class TimeField(Base):
+    """Configurator for Ext.form.TimeField."""
+    xtype = 'timefield'
+
+
+class Viewport(Base):
+    """Configurator for App.Viewport."""
+    xtype = 'xviewport'
+    
\ No newline at end of file
diff --git a/modules/plugin_dbui/mapper.py b/modules/plugin_dbui/mapper.py
index 5a55f4b57c049864905036126dcac910a8a31065..d0fba586d378c536222e7cbb77f8a861dc99d57b 100644
--- a/modules/plugin_dbui/mapper.py
+++ b/modules/plugin_dbui/mapper.py
@@ -1,6 +1,8 @@
 """ Author: R. Le Gac
 
 """
+from extjs import TabPanel
+
 
 def map_default(fields):
     """Map a list of field in the Ext.form.formPanel
@@ -18,10 +20,9 @@ def map_tabpanel(fieldsets):
     Return the items list for the Ext.form.FormPanel.
     
     """
-    tabpanel = {'activeTab': 0,
-                'defaults': {'anchor': '100%'},
-                'items': [],
-                'xtype': 'tabpanel'}
+    
+    tabpanel = TabPanel(activeTab=0,
+                        defaults={'anchor': '98%'})
     
     for fieldset in fieldsets:
         
@@ -33,6 +34,6 @@ def map_tabpanel(fieldsets):
                'items': fieldset,
                'title': title}
         
-        tabpanel['items'].append(tab)
+        tabpanel.append_items(tab)
 
     return [tabpanel]
\ No newline at end of file
diff --git a/modules/plugin_dbui/modifier.py b/modules/plugin_dbui/modifier.py
index 82008f1ff2bdcee618be216f6d5c4a6bfa152913..c0cb223c850302622f6a0ce4eb632e47da869e51 100644
--- a/modules/plugin_dbui/modifier.py
+++ b/modules/plugin_dbui/modifier.py
@@ -79,21 +79,3 @@ class Modifier(object):
         
         """
         self.data.extjs.update(extjs)
-
-
-class Widget(object):
-    """Base class defining a the configuration of an ExtJS widget.
-    
-    """
-    def __init__(self, xtype, **kwargs):
-        self.extjs = dict(xtype=xtype, **kwargs)
-
-
-class Spacer(Widget):
-    """Define a spacer which can be add when combining fields in fieldset
-    or in field container.
-    
-    """
-    def __init__(self, **kwargs):
-        Widget.__init__(self, 'spacer', **kwargs)
-
diff --git a/modules/plugin_dbui/navtree.py b/modules/plugin_dbui/navtree.py
index b5b9e39cc349d670183d4a1119a3bbffd4a86e40..9b70e582954b519a08185ba544a9d3e14264f71e 100644
--- a/modules/plugin_dbui/navtree.py
+++ b/modules/plugin_dbui/navtree.py
@@ -3,141 +3,7 @@
 """
 
 import locale
-import os
 from gluon import current
-from helper import is_mathjax
-
-
-def to_panel(**kwargs):
-    """Return the configuration dictionary of an Ext.Panel.
-
-    The keyword arguments are the configuration options of
-    the Ext.Panel widget.
-    
-    """
-    cfg = {'xtype': 'panel'}
-    cfg.update(kwargs)
-    return cfg
-
-
-def to_fieldset(fields, **kwargs):
-    """Return the confiuration dictionary of Ext.form.Fieldset.
-    This widget contains list of Ext.form.Field.
-    
-    fields is a list of configuration dictioanry for form.Fields.
-
-    The keyword arguments are the configuration options of
-    the Ext.form.FieldSet widget.
-    
-    """
-    cfg = {'defaults': {'anchor': '99%'},
-           'items': fields,
-           'xtype': 'fieldset'}
-    cfg.update(kwargs)
-    return cfg
-
-    
-def to_panelWithUrlSelector(panelCfg,
-                            selectorCfg,
-                            baseUrl=None,
-                            application=None,
-                            controller=None,
-                            function=None,
-                            ctrlField=None,
-                            extField=None,
-                            funcField=None):
-    """Return the configuration dictionary for an App.PanelWithUrlSelector.
-    
-    This widget is split in two part a main panel and a selector.
-    The selector display a list of fields organized in fieldset.
-    There values define the URL parameters. The main panel displays 
-    the URL content.
-    
-    Configuration dictionary for the main panel and fieldset are set via:
-    
-        panelCfg
-        
-        selectorCfg
-        
-    In web2py an URL is defined as application/controller/function.extension
-    There are several ways to define it. 
-    
-        application
-            The base URL is: /application
-            By default the application is the current application.
-            
-        baseUrl
-            Another way to defined the URL associated to the panel.
-            It should be a well-formed URL string, i.e http://blabla.
-            It is a more general approach where the URL can point to a
-            any links.
-            
-        controller
-            The base URL is: /application/controller.
-
-        function
-            The base URL is: /application/controller/function.
-        
-    The URL can be modified dynamicaly by extracting the name of the
-    controller, function and/or  extension from the selector fields.
-                        
-        ctrlField
-            Name of the field defining the name of the controller.
-            When define the URL become baseURL/ctrlFieldValue.
-        
-        extField
-            Name of the field defining the name of the extension.
-            When define the URL become baseUrl.extFieldValue.
-            Useful to play with different view rendering the same
-            controller/function.
-
-        funcField
-            Name of the form field defining the name of the function.
-            When define the URL become baseURL/funcFieldValue.
-            To be used with ctrlField. In that case the URL is
-            /application/ctrFieldValue/funcFieldValue.
-    
-    """
-    url = baseUrl
-    if not url:
-        if application:
-            url = os.path.join('/', application)
-        else:
-            url = os.path.join('/', current.request.application)
-
-        if controller:
-            url = os.path.join(url, controller)
-
-        if function:
-            url = os.path.join(url, function)
-        
-    cfg = {'baseUrl': url,
-           'ctrlField': ctrlField,
-           'extField': extField,
-           'funcField': funcField,
-           'isMathJax': is_mathjax(),
-           'panelCfg': panelCfg,
-           'selectorCfg': selectorCfg,
-           'xtype': 'xpanelwithurlselector'}
-
-    return cfg
-
-
-def to_urlPanel(url):
-    """Return the configuration dictionary for an Ext.Panel
-    displaying an URL.
-    
-        url
-            well-formed URL string, i.e http://blabla
-    
-    """
-    cfg = to_panel(autoload=url,
-                   preventBodyReset=True)
-
-    if is_mathjax():
-        cfg['plugins'] = ['pPanelMathJax']
-    
-    return cfg
 
 
 class Node(object):
diff --git a/static/plugin_dbui/CHANGELOG b/static/plugin_dbui/CHANGELOG
index ec45b714f5b3b5a9fe2505edf460a4caeebb1e15..4c2eda0ad6e338f6f6b25b2d5fa3519ad037181d 100644
--- a/static/plugin_dbui/CHANGELOG
+++ b/static/plugin_dbui/CHANGELOG
@@ -2,8 +2,11 @@
 
 HEAD
   - Bugs fixed
-  - Add the configuration parameter extField in App.PanelWithUrlSelector.
-    Design to manipulate different web2py views like foo.html, foo.xml, ...
+  - More general configuration for App.PanelWithUrlSelector.
+  - Major redesign of the configuration section. Remove the CvtSvc and
+    add two modules extjs and converter. The first one contains a serie
+    of configurators mapping ExtJS components while the second one contained
+    functions translating DAL object into ExtJS configurator.
   
 0.4.5 (Feb 2012)
   - Consolidation version
diff --git a/static/plugin_dbui/src/appviewport.js b/static/plugin_dbui/src/appviewport.js
index 23f7b79b299de54f56cc28a9a3ed59169d3585a0..05ca3e6027cf0bbf98ac745bc94ed7c95fe840aa 100644
--- a/static/plugin_dbui/src/appviewport.js
+++ b/static/plugin_dbui/src/appviewport.js
@@ -142,3 +142,5 @@ App.Viewport = Ext.extend(Ext.Viewport, {
         this.tabPanel.setActiveTab(tabId);
     }
 });
+
+Ext.reg('xviewport', App.Viewport);
\ No newline at end of file