diff --git a/analyze.py b/analyze.py
index 23162ef3b96587c3754e9a8b14eba76df632fb3c_YW5hbHl6ZS5weQ==..024751194fb743f8fbb0e948df1ac3e733994d36_YW5hbHl6ZS5weQ== 100644
--- a/analyze.py
+++ b/analyze.py
@@ -22,7 +22,7 @@
 except ImportError:
     rql_solve = None
     # Gecode solver not available
-
+# rql_solve = None # uncomment to force using logilab-constraint
 
 class ConstraintCSPProblem(object):
     def __init__(self):
@@ -93,14 +93,5 @@
         expr = " or ".join( list(orred) )
         self.add_expr( tuple(variables), expr )
 
-class _eq(object):
-    def __init__(self, var, val):
-        self.var = var
-        self.val = val
-
-    def __str__(self):
-        return '%s == "%s"' % (self.var, self.val)
-
-    def get_vars(self, s):
-        s.add(self.var)
+# GECODE based constraint solver
 
@@ -106,4 +97,6 @@
 
-    def for_gecode(self, all_vars, all_values):
-        return ["eq", all_vars.index( self.var ), all_values.index(self.val) ]
+_AND = "and"
+_OR = "or"
+_EQ = "eq"
+_EQV = "eqv"
 
@@ -109,14 +102,6 @@
 
-class _eqv(object):
-    def __init__(self, vars):
-        self.vars = set(vars)
-    def __str__(self):
-        return '(' + " == ".join( str(t) for t in self.vars ) + ')'
-    def get_vars(self, s):
-        s+=self.vars
-    def for_gecode(self, all_vars, all_values):
-        l = ["eqv"]
-        for v in self.vars:
-            l.append( all_vars.index( v ) )
-        return l
+class GecodeCSPProblem(object):
+    """Builds an internal representation of the constraint
+    that will be passed to the rql_solve module which implements
+    a gecode-based solver
 
@@ -122,19 +107,8 @@
 
-class _and(object):
-    def __init__(self):
-        self.cond = []
-    def add(self, expr):
-        self.cond.append( expr )
-        #if expr not in self.cond:
-        #    self.cond.append( expr )
-    def __str__(self):
-        return '(' + " and ".join( str(t) for t in self.cond ) + ')'
-    def get_vars(self, s):
-        for t in self.cond:
-            t.get_vars(s)
-    def for_gecode(self, all_vars, all_values):
-        l = ["and"]
-        for n in self.cond:
-            l.append( n.for_gecode(all_vars, all_values) )
-        return l
+    The internal representation is a tree builds with lists of lists
+    the first item of the list is the node type (_AND,_OR,_EQ,_EQV)
+    
+    an example : ["and", [ "eq",0,0 ], ["or", ["eq", 1, 1], ["eq", 1, 2] ] ]
+
+    means Var(0) == Value(0) and ( Var(1)==Val(1) or Var(1) == Val(2)
 
@@ -140,17 +114,9 @@
 
-
-class _or(_and):
-    def __str__(self):
-        return '(' + " or ".join( str(t) for t in self.cond ) + ')'
-    def for_gecode(self, all_vars, all_values):
-        l = ["or"]
-        for n in self.cond:
-            l.append( n.for_gecode(all_vars, all_values) )
-        return l
-# TODO: refactor/optimize:
-# now that gecode solver is working we don't need the above _and/_or... classes
-# we can generate the constraint tree directly as ["and", ['or',...], ... ]
-# Another thing that 
-class GecodeCSPProblem(object):
+    TODO: at the moment the solver makes no type checking on the structure
+    of the tree thus can crash badly if something wrong is handled to it
+    this should not happend as the building of the tree is done internally
+    but it should be fixed anyways.
+    When fixing that we should also replace string nodes by integers
+    """
     def __init__(self):
         self.constraints = []
@@ -155,4 +121,4 @@
     def __init__(self):
         self.constraints = []
-        self.op = _and()
+        self.op = [ _AND ]
         self.domains = {}
@@ -158,6 +124,8 @@
         self.domains = {}
+        self.variables = {}
+        self.values = {}
 
     def get_output(self):
         return ""
     def solve(self):
         # assign an integer to each var and each domain values
@@ -159,12 +127,8 @@
 
     def get_output(self):
         return ""
     def solve(self):
         # assign an integer to each var and each domain values
-        all_values = set()
-        all_vars = sorted(self.domains.keys())
-        for values in self.domains.values():
-            all_values.update(values)
-        all_values = sorted(all_values)
-        constraints = self.op.for_gecode( all_vars, all_values )
+        all_values = range(len(self.values))
+        constraints = self.op #.for_gecode( all_vars, all_values )
         var_domains = []
@@ -170,9 +134,8 @@
         var_domains = []
-        for var in all_vars:
-            dom = []
-            for val in self.domains[var]:
-                dom.append( all_values.index(val) )
-            var_domains.append( dom )
+        # loop through variables in increasing order of the number they have been assigned
+        variables = [ var_name for var_name, var_value in sorted(self.variables.items(), key=lambda item:item[1] ) ]
+        for var_name in variables:
+            var_domains.append( self.domains[var_name] )
 
         sols = rql_solve.solve( var_domains, len(all_values), constraints )
         rql_sols = []
@@ -176,5 +139,7 @@
 
         sols = rql_solve.solve( var_domains, len(all_values), constraints )
         rql_sols = []
+        # values is the list of values (string) order according to the integer value they have been assigned
+        values = [ val_name for val_name, val_value in sorted(self.values.items(), key=lambda item:item[1] ) ]
         for s in sols:
             r={}
@@ -179,8 +144,8 @@
         for s in sols:
             r={}
-            for var,val in zip(all_vars,s):
-                r[var] = all_values[val]
+            for var, val in zip(variables, s):
+                r[var] = values[val]
             rql_sols.append(r)
         return rql_sols
 
     def add_var(self, name, values):
@@ -183,7 +148,13 @@
             rql_sols.append(r)
         return rql_sols
 
     def add_var(self, name, values):
-        self.domains[name] = set(values)
+        domain = []
+        var_value = self.variables.setdefault( name, len(self.variables) )
+        for val in values:
+            val_value = self.values.setdefault( val, len(self.values) )
+            domain.append( val_value )
+        self.domains[name] = domain
+        
 
     def and_eq( self, var, value ):
@@ -188,7 +159,6 @@
 
     def and_eq( self, var, value ):
-        eq = _eq(var, value)
-        self.op.add(eq)
+        self.op.append( [_EQ, self.variables[var], self.values[value] ] )
 
     def equal_vars(self, varnames):
         if len(varnames)>1:
@@ -192,7 +162,7 @@
 
     def equal_vars(self, varnames):
         if len(varnames)>1:
-            self.op.add( _eqv(varnames) )
+            self.op.append( [ _EQV] + [ self.variables[v] for v in varnames ] )
 
     def var_has_type(self, var, etype):
         self.and_eq( var, etype)
@@ -203,5 +173,5 @@
         if len(etypes) == 1:
             self.and_eq( var, tuple(etypes)[0] )
         else:
-            orred = _or()
+            orred = [ _OR ]
             for t in etypes:
@@ -207,6 +177,6 @@
             for t in etypes:
-                orred.add( _eq(var, t) )
-            self.op.add( orred )
+                orred.append( [ _EQ, self.variables[var], self.values[t] ] )
+            self.op.append( orred )
 
     def vars_have_types(self, varnames, types):
         self.equal_vars( varnames )
@@ -214,5 +184,5 @@
             self.var_has_types( var, types )
 
     def or_and(self, equalities):
-        orred = _or()
+        orred = [ _OR ]
         for orred_expr in equalities:
@@ -218,8 +188,8 @@
         for orred_expr in equalities:
-            anded = _and()
+            anded = [ _AND ]
             for vars, types in orred_expr:
                 self.equal_vars( vars )
                 for t in types:
                     assert isinstance(t, (str,unicode))
                 for var in vars:
                     if len(types)==1:
@@ -220,8 +190,8 @@
             for vars, types in orred_expr:
                 self.equal_vars( vars )
                 for t in types:
                     assert isinstance(t, (str,unicode))
                 for var in vars:
                     if len(types)==1:
-                        anded.add( _eq(var, types[0]) )
+                        anded.append( [ _EQ, self.variables[var], self.values[types[0]] ] )
                     else:
@@ -227,3 +197,3 @@
                     else:
-                        or2 = _or()
+                        or2 = [ _OR ]
                         for t in types:
@@ -229,8 +199,8 @@
                         for t in types:
-                            or2.add( _eq(var, t) )
-                        anded.add( or2 )
-            orred.add(anded)
-        self.op.add(orred)
+                            or2.append(  [_EQ, self.variables[var], self.values[t] ] )
+                        anded.append( or2 )
+            orred.append(anded)
+        self.op.append(orred)
 
 if rql_solve is None:
     CSPProblem = ConstraintCSPProblem