Index: trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/main/java/org/gvsig/expressionevaluator/impl/DefaultExpression.java
===================================================================
--- trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/main/java/org/gvsig/expressionevaluator/impl/DefaultExpression.java	(revision 44621)
+++ trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/main/java/org/gvsig/expressionevaluator/impl/DefaultExpression.java	(revision 44622)
@@ -1,5 +1,7 @@
 package org.gvsig.expressionevaluator.impl;
 
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
 import java.util.Objects;
 import org.apache.commons.lang3.StringUtils;
 import org.gvsig.expressionevaluator.Code;
@@ -35,6 +37,7 @@
     private Interpreter interpreter;
     private boolean hasNotBeenOptimized = true;
     private SymbolTable mySymbolTable = null;
+    private WeakReference<SymbolTable> lastSymbolTable = null;    
     private boolean useBracketsForIdentifiers = false;
 
     public DefaultExpression() {
@@ -216,11 +219,23 @@
             this.interpreter = manager.createInterpreter();
         }
         boolean added = this.getSymbolTable().addSymbolTable(symbolTable);
+        if( this.lastSymbolTable==null ) {
+            this.lastSymbolTable = new WeakReference<>(symbolTable);            
+        } else if( this.lastSymbolTable.get()!=symbolTable ) {
+            this.link(this.getSymbolTable());
+            this.lastSymbolTable = new WeakReference<>(symbolTable);
+            this.hasNotBeenOptimized = true;            
+        }
         try {
             this.interpreter.setSymbolTable(this.mySymbolTable);
             if( this.hasNotBeenOptimized  ) {
-                Optimizer optimizer = new DefaultOptimizer(symbolTable);
-                this.code = optimizer.optimize(this.getCode());
+                try {
+                    Optimizer optimizer = new DefaultOptimizer(this.getSymbolTable());
+                    this.code = optimizer.optimize(this.getCode());
+                } catch(Throwable th) {
+                    // Si no es capaz de optimizar la expresion no, peta y la
+                    // ejecuta tal cual.
+                }
                 this.hasNotBeenOptimized = false;
             }
             Object x = this.interpreter.run(this.getCode());
Index: trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/main/java/org/gvsig/expressionevaluator/impl/DefaultOptimizer.java
===================================================================
--- trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/main/java/org/gvsig/expressionevaluator/impl/DefaultOptimizer.java	(revision 44621)
+++ trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/main/java/org/gvsig/expressionevaluator/impl/DefaultOptimizer.java	(revision 44622)
@@ -168,18 +168,20 @@
         switch (code.code()) {
             case Code.CALLER:
                 Caller caller = (Caller) code;
-                if (caller.function() == null) {
+                Function function = caller.function();
+                if ( function == null) {
                     // resolve and link function
-                    caller.function(this.getSymbolTable().function(caller.name()));
+                    function = this.getSymbolTable().function(caller.name());
+                    caller.function(function);
                 }
-                if (caller.function() instanceof FunctionOptimizer) {
+                if (function instanceof FunctionOptimizer) {
                     return ((FunctionOptimizer) caller.function()).optimize(this, caller);
                 } else {
                     switch (caller.type()) {
                         case Caller.BINARY_OPERATOR: {
                             Code op1 = this.doOptimize(caller.parameters().get(0));
                             Code op2 = this.doOptimize(caller.parameters().get(1));
-                            if (caller.function().allowConstantFolding()) {
+                            if ( function.allowConstantFolding()) {
                                 if (op1.code() == Code.CONSTANT && op2.code() == Code.CONSTANT) {
                                     Object value = this.getInterpreter().run(code);
                                     Code newCode = this.getCodeBuilder().constant(value);
@@ -192,7 +194,7 @@
 
                         case Code.Caller.UNARY_OPERATOR: {
                             Code op1 = this.doOptimize(caller.parameters().get(0));
-                            if (caller.function().allowConstantFolding()
+                            if (function.allowConstantFolding()
                                     && op1.code() == Code.CONSTANT) {
                                 Object value = this.getInterpreter().run(code);
                                 Code newCode = this.getCodeBuilder().constant(value);
@@ -215,7 +217,7 @@
                                     }
                                 }
                             }
-                            if (canOptimize && caller.function()!=null && caller.function().allowConstantFolding()) {
+                            if (canOptimize && function!=null && function.allowConstantFolding()) {
                                 Object value = this.getInterpreter().run(code);
                                 Code newCode = this.getCodeBuilder().constant(value);
                                 return newCode;
Index: trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/test/java/org/gvsig/expresionevaluator/impl/TestExpression.java
===================================================================
--- trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/test/java/org/gvsig/expresionevaluator/impl/TestExpression.java	(revision 44621)
+++ trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/test/java/org/gvsig/expresionevaluator/impl/TestExpression.java	(revision 44622)
@@ -110,22 +110,21 @@
     public void testB() {
 
         Expression expression = createExpression();
-        expression.setPhrase("MYVALUE()");
+        expression.setPhrase("MYVALUE()*10");
 
         MyValueSymbolTable t1 = new MyValueSymbolTable("MyValueSymbolTable1");
         t1.setValue(2);
         Object v1 = expression.execute(t1);
-        assertEquals(2, (int) v1);
+        assertEquals(20, (int) v1);
 
         t1.setValue(3);
         v1 = expression.execute(t1);
-        assertEquals(3, (int) v1);
+        assertEquals(30, (int) v1);
 
         MyValueSymbolTable t2 = new MyValueSymbolTable("MyValueSymbolTable2");
-        expression.link(t2);
         t2.setValue(4);
         v1 = expression.execute(t2);
-        assertEquals(4, (int) v1);
+        assertEquals(40, (int) v1);
 
     }
 
