]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/function/All.java
Spreadsheet changes
[simantics/platform.git] / bundles / org.simantics.spreadsheet.graph / src / org / simantics / spreadsheet / graph / function / All.java
index 98ef90231fc6be36999667b377ad46fe1cd5b516..9b0f708df8c11628fbb1c13af1dabf76bf46b669 100644 (file)
@@ -54,22 +54,26 @@ import org.simantics.simulator.variable.exceptions.NodeManagerException;
 import org.simantics.spreadsheet.CellEditor;
 import org.simantics.spreadsheet.ClientModel;
 import org.simantics.spreadsheet.Range;
-import org.simantics.spreadsheet.graph.ExcelFormula;
-import org.simantics.spreadsheet.graph.SheetNode;
-import org.simantics.spreadsheet.graph.SpreadsheetBook;
-import org.simantics.spreadsheet.graph.SpreadsheetCell;
-import org.simantics.spreadsheet.graph.SpreadsheetCellContent;
-import org.simantics.spreadsheet.graph.SpreadsheetFormula;
+import org.simantics.spreadsheet.Spreadsheets;
 import org.simantics.spreadsheet.graph.SpreadsheetGraphUtils;
-import org.simantics.spreadsheet.graph.SpreadsheetSCLConstant;
+import org.simantics.spreadsheet.graph.SpreadsheetNodeManager;
 import org.simantics.spreadsheet.graph.SpreadsheetSessionManager;
-import org.simantics.spreadsheet.graph.SpreadsheetStyle;
-import org.simantics.spreadsheet.graph.SpreadsheetStyle.SpreadsheetStyleBuilder;
 import org.simantics.spreadsheet.graph.celleditor.GraphCellEditorAdapter;
-import org.simantics.spreadsheet.graph.parser.ParseException;
-import org.simantics.spreadsheet.graph.parser.SheetFormulaParser;
-import org.simantics.spreadsheet.graph.parser.ast.AstValue;
 import org.simantics.spreadsheet.resource.SpreadsheetResource;
+import org.simantics.spreadsheet.solver.SheetNode;
+import org.simantics.spreadsheet.solver.SpreadsheetBook;
+import org.simantics.spreadsheet.solver.SpreadsheetCell;
+import org.simantics.spreadsheet.solver.SpreadsheetCellContent;
+import org.simantics.spreadsheet.solver.SpreadsheetFormula;
+import org.simantics.spreadsheet.solver.SpreadsheetSCLConstant;
+import org.simantics.spreadsheet.solver.SpreadsheetStyle;
+import org.simantics.spreadsheet.solver.SpreadsheetStyle.SpreadsheetStyleBuilder;
+import org.simantics.spreadsheet.solver.formula.parser.ParseException;
+import org.simantics.spreadsheet.solver.formula.parser.SheetFormulaParser;
+import org.simantics.spreadsheet.solver.formula.parser.ast.AstValue;
+import org.simantics.spreadsheet.synchronization.ExcelFormula;
+import org.simantics.spreadsheet.synchronization.LineContentBean;
+import org.simantics.spreadsheet.synchronization.LineContentBeanCell;
 import org.simantics.spreadsheet.util.SpreadsheetUtils;
 
 import gnu.trove.map.TMap;
@@ -80,127 +84,135 @@ public class All {
 
     @SCLValue(type = "ReadGraph -> Resource -> a -> String")
     public static String cellLabel(ReadGraph graph, Resource resource, Object context) throws DatabaseException {
-       if(context instanceof Resource) {
-               return NameUtils.getSafeLabel(graph, ((Resource)context));      
-       } else if (context instanceof Variable) {
-               Variable parent = ((Variable)context).getParent(graph);
-               Variable content =  parent.getPossibleProperty(graph, ClientModel.CONTENT);
-               if(content != null) {
-               Databoard db = graph.getService(Databoard.class);
-                       Variant variant = content.getValue(graph, db.VARIANT);
-                       return variant.getValue().toString();
-               } else {
-                       return parent.getName(graph);
-               }
-       } else {
-               throw new DatabaseException("Unknown context " + context);
-       }
+        if(context instanceof Resource) {
+            return NameUtils.getSafeLabel(graph, ((Resource)context)); 
+        } else if (context instanceof Variable) {
+            Variable parent = ((Variable)context).getParent(graph);
+            Variable content =  parent.getPossibleProperty(graph, ClientModel.CONTENT);
+            if(content != null) {
+                Databoard db = graph.getService(Databoard.class);
+                Variant variant = content.getValue(graph, db.VARIANT);
+                return variant.getValue().toString();
+            } else {
+                return parent.getName(graph);
+            }
+        } else {
+            throw new DatabaseException("Unknown context " + context);
+        }
     }
 
-       private static Set<String> CLASSIFICATIONS = new HashSet<String>();
-       private static ConstantPropertyVariableBuilder immutableBuilder = new ConstantPropertyVariableBuilder("immutable", true, Bindings.BOOLEAN); 
-       
-       static {
-               CLASSIFICATIONS.add(SpreadsheetResource.URIs.Attribute);
-       }
+    private static Set<String> CLASSIFICATIONS = new HashSet<String>();
+    private static ConstantPropertyVariableBuilder immutableBuilder = new ConstantPropertyVariableBuilder("immutable", true, Bindings.BOOLEAN); 
+
+    static {
+        CLASSIFICATIONS.add(SpreadsheetResource.URIs.Attribute);
+    }
 
     @SCLValue(type = "ValueAccessor")
-       public static ValueAccessor contentValueAccessor = new ValueAccessor() {
-               
-               @Override
-               public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {
-                   System.out.println("contentValueAccessor.context=" + context.getURI(graph));
-                       if(value instanceof String) {
-                               
-                               // Expressions are given as string
-                               String text = (String)value;
-                               SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
-                               if (text.startsWith("==")) {
-                       if(!Layer0Utils.setOrClearExpression(graph, context, text.substring(1), SHEET.SCLValue)) {
-                           org.simantics.db.layer0.function.All.standardSetValue3(graph, context, Variant.ofInstance(value), Bindings.VARIANT);
-                           //StandardValueAccessor.setValue(graph, context, Variant.ofInstance(value), Bindings.VARIANT);
-                           //org.simantics.db.layer0.function.All.standardValueAccessor.setValue(graph, context, Variant.ofInstance(value), Bindings.VARIANT);
-                       }
-                       return;
-                               } else {
-                                   
-                                   Variable cell = context.getParent(graph);
-                                   System.out.println("setValue : " + cell.getURI(graph));
-                                   
+    public static ValueAccessor contentValueAccessor = new ValueAccessor() {
+
+        @Override
+        public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {
+            System.out.println("contentValueAccessor.context=" + context.getURI(graph));
+            if(value instanceof String) {
+
+                // Expressions are given as string
+                String text = (String)value;
+                SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
+                if (text.startsWith("==")) {
+
+                    if(ProxyVariables.isProxy(graph, context))
+                        // SCL expressions are not supported in solver
+                        return;
+
+                    if(!Layer0Utils.setOrClearExpression(graph, context, text.substring(1), SHEET.SCLValue)) {
+                        org.simantics.db.layer0.function.All.standardSetValue3(graph, context, Variant.ofInstance(value), Bindings.VARIANT);
+                        //StandardValueAccessor.setValue(graph, context, Variant.ofInstance(value), Bindings.VARIANT);
+                        //org.simantics.db.layer0.function.All.standardValueAccessor.setValue(graph, context, Variant.ofInstance(value), Bindings.VARIANT);
+                    }
+                    return;
+                } else {
+
+                    Variable cell = context.getParent(graph);
+                    System.out.println("setValue : " + cell.getURI(graph));
+
                     String formula = text.substring(1);
-                    
+
                     if (ProxyVariables.isProxy(graph, context)) {
                         try {
                             SheetFormulaParser p = new SheetFormulaParser(new StringReader(formula));
                             AstValue v = p.relation();
                             SpreadsheetFormula sformula = new SpreadsheetFormula(v, formula);
-                            setValueToEngine(graph, cell, context, sformula, binding);
+                            setValueToEngine(graph, cell, context, sformula, SpreadsheetFormula.BINDING);
                         } catch (ParseException e) {
                             e.printStackTrace();
                         }
                         return;
+
                     }
-                    
+
                     Variant v = new Variant(ExcelFormula.BINDING, new ExcelFormula(formula));
-                    graph.claimLiteral(cell.getRepresents(graph), SHEET.Cell_content, SHEET.Cell_content_Inverse, Layer0.getInstance(graph).Variant, v, Bindings.VARIANT);
-                               }
-                       } else {
-                               
-                               if(ProxyVariables.isProxy(graph, context)) {
-                                       
-                                       Variable cell = context.getParent(graph);
-                                       setValueToEngine(graph, cell, context, value, binding);
-                                       return;
-                               }
-                               
-                               // Values are given as Variant
-                               String expression = context.getPossiblePropertyValue(graph, "expression");
-                               if(expression != null) {
-                                       Object current_ = context.getPossibleValue(graph);
-                                       if(current_ instanceof Variable) {
-                                               Variable current = (Variable)current_;
-                                               Variant variant = (Variant)value;
-                                               Datatype dt = current.getDatatype(graph);
-                                               if (dt == null) {
-                                                       throw new DatabaseException();
-                                               }
-                                               Binding variableBinding = Bindings.getBinding(dt);
-                                               try {
-                                                       Object adapted = variant.getValue(variableBinding);
-                                                       current.setValue(graph, adapted, variableBinding);
-                                               } catch (AdaptException e) {
-                                                       Logger.defaultLogError(e);
-                                               }
-                                               return;
-                                       }
-                                       SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
-                                       Layer0Utils.clearExpression(graph, context, SHEET.SCLValue);
-                               }
-                               org.simantics.db.layer0.function.All.standardSetValue3(graph, context, value, binding);
-                               //org.simantics.db.layer0.function.All.standardValueAccessor.setValue(graph, context, value, binding);
-                       }
-               }
-               
-               private void setValueToEngine(WriteGraph graph, Variable cell, Variable context, Object value, Binding binding) throws DatabaseException {
+                    Layer0Utils.claimLiteral(graph, cell.getRepresents(graph), SHEET.Cell_content, SHEET.Cell_content_Inverse, Layer0.getInstance(graph).Variant, v, Bindings.VARIANT);
+                    
+                }
+            } else {
+
+                if(ProxyVariables.isProxy(graph, context)) {
+
+                    Variable cell = context.getParent(graph);
+                    setValueToEngine(graph, cell, context, value, binding);
+                    return;
+                }
+
+                // Values are given as Variant
+                String expression = context.getPossiblePropertyValue(graph, "expression");
+                if(expression != null) {
+                    Object current_ = context.getPossibleValue(graph);
+                    if(current_ instanceof Variable) {
+                        Variable current = (Variable)current_;
+                        Variant variant = (Variant)value;
+                        Datatype dt = current.getDatatype(graph);
+                        if (dt == null) {
+                            throw new DatabaseException();
+                        }
+                        Binding variableBinding = Bindings.getBinding(dt);
+                        try {
+                            Object adapted = variant.getValue(variableBinding);
+                            current.setValue(graph, adapted, variableBinding);
+                        } catch (AdaptException e) {
+                            Logger.defaultLogError(e);
+                        }
+                        return;
+                    }
+                    SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
+                    Layer0Utils.clearExpression(graph, context, SHEET.SCLValue);
+                }
+                org.simantics.db.layer0.function.All.standardSetValue3(graph, context, value, binding);
+                //org.simantics.db.layer0.function.All.standardValueAccessor.setValue(graph, context, value, binding);
+            }
+        }
+
+        private void setValueToEngine(WriteGraph graph, Variable cell, Variable context, Object value, Binding binding) throws DatabaseException {
             Variable sheet = cell.getParent(graph);
 
+            if(Bindings.STRING.equals(binding) && !(value instanceof String))
+                System.err.println("asd");
+
             SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
 
             while(!sheet.getType(graph).equals(SHEET.Spreadsheet)) {
                 sheet = sheet.getParent(graph);
             }
-            
-            Range r = SpreadsheetUtils.decodeCellAbsolute(cell.getName(graph));
-            
+
+            Range r = Spreadsheets.decodeCellAbsolute(cell.getName(graph));
+
             Variable root = ProxyVariables.proxyVariableRoot(graph, context);
-            
+
             String sessionName = root.getParent(graph).getURI(graph);
             StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
             SpreadsheetBook book = realm.getEngine();
             SpreadsheetCell sc = book.get(sheet.getName(graph), r.startRow, r.startColumn);
             sc.setContent(value);
-//          book.accept(new InvalidateAll());
-//                     List<SpreadsheetCell> changed = book.invalidate(sc); //Invalidation handled by SpreadsheetNodeManager
             realm.asyncExec(new Runnable() {
 
                 @Override
@@ -208,306 +220,287 @@ public class All {
                     try {
                         SpreadsheetCellContent content = (SpreadsheetCellContent)sc.getProperties().get("content");
                         realm.getNodeManager().setValue(content, value, binding);
-//                      for(SpreadsheetCell cell : changed) {
-//                          content = (SpreadsheetCellContent)cell.getProperties().get("content");
-//                          realm.getNodeManager().setValue(content, value, binding);
-//                      }
                     } catch (NodeManagerException e) {
                         Logger.defaultLogError(e);
                     }
                 }
             });
-               }
-               
-               @Override
-               public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {
-                       if(value instanceof String) setValue(graph, context, value, Bindings.STRING);
-                       else if(value instanceof Variant) setValue(graph, context, value, Bindings.VARIANT);
-                       else throw new DatabaseException("Unsupported value type " + value);
-               }
-               
-               @Override
-               public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {
-                       return org.simantics.db.layer0.function.All.standardGetValue2(graph, context, binding);
-                       //return org.simantics.db.layer0.function.All.standardValueAccessor.getValue(graph, context, binding);
-               }
-               
-               @Override
-               public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {
-                       return org.simantics.db.layer0.function.All.standardGetValue1(graph, ((StandardGraphPropertyVariable)context));
+        }
+
+        @Override
+        public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {
+            if(value instanceof String) setValue(graph, context, value, Bindings.STRING);
+            else if(value instanceof Variant) setValue(graph, context, value, Bindings.VARIANT);
+            else throw new DatabaseException("Unsupported value type " + value);
+        }
+
+        @Override
+        public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {
+            return org.simantics.db.layer0.function.All.standardGetValue2(graph, context, binding);
+            //return org.simantics.db.layer0.function.All.standardValueAccessor.getValue(graph, context, binding);
+        }
+
+        @Override
+        public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {
+            return org.simantics.db.layer0.function.All.standardGetValue1(graph, ((StandardGraphPropertyVariable)context));
 //                     return org.simantics.db.layer0.function.All.standardValueAccessor.getValue(graph, context);
-               }
+        }
 
-               @Override
-               public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {
-                       return org.simantics.db.layer0.function.All.standardGetDatatype(graph, context);
+        @Override
+        public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {
+            return org.simantics.db.layer0.function.All.standardGetDatatype(graph, context);
 //                     return org.simantics.db.layer0.function.All.standardValueAccessor.getDatatype(graph, context);
-               }
-               
-       };
+        }
+
+    };
 
     @SCLValue(type = "ValueAccessor")
-       public static ValueAccessor contentDisplayValueAccessor = new ValueAccessor() {
-               
-               @Override
-               public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {
-                       if (!Bindings.STRING.equals(binding)) throw new IllegalArgumentException();
-                       if (!(value instanceof String)) throw new IllegalArgumentException();
-                       
-                       if (((String)value).startsWith("=")) {
-                               context.getParent(graph).setValue(graph, value, Bindings.STRING);
-                       } else {
-                               context.getParent(graph).setValue(graph, new Variant(Bindings.STRING, value), Bindings.VARIANT);
-                       }
-               }
-               
-               @Override
-               public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {
-                       if (!(value instanceof String)) throw new IllegalArgumentException();
-                       
-                       if (((String)value).startsWith("=")) {
-                               context.getParent(graph).setValue(graph, value, Bindings.STRING);
-                       } else {
-                               context.getParent(graph).setValue(graph, new Variant(Bindings.STRING, value), Bindings.VARIANT);
-                       }
-               }
-               
-               @Override
-               public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {
-                       return context.getParent(graph).getValue(graph, binding);
-               }
-               
-               @Override
-               public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {
-                       return context.getParent(graph).getValue(graph);
-               }
-
-               @Override
-               public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {
-                       return context.getParent(graph).getDatatype(graph);
-               }
-               
-       };
-
-       @SCLValue(type = "VariableMap")
-       public static VariableMap stringArrayChildren = new VariableMapImpl() {
-       
-               @Override
-               public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
-                       
-                       TMap<String, Variable> map = new THashMap<String, Variable>();
-                       getVariables(graph, context, map);
-                       return map.get(name);                                   
-                       
-               }
-
-               @Override
-               public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
-                       
-                       Resource resource = context.getRepresents(graph);
-                       
-               SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
-               
-               String location = graph.getPossibleRelatedValue(resource, sr.Range_location, Bindings.STRING);
-               if(location == null) return map;
-               Integer width = graph.getPossibleRelatedValue(resource, sr.Range_widthBound, Bindings.INTEGER);
-               if(width == null) return map;
-               String[] array = graph.getPossibleRelatedValue(resource, sr.StringArrayRange_array, Bindings.STRING_ARRAY);
-               if(array == null) return map;
-               
-               int rows = array.length / width;
-               
-               if(map == null) map = new HashMap<String,Variable>();
-               
-               for(int offset=0,i=0;i<rows;i++) {
-                       for(int j=0;j<width;j++) {
-                               
-                               String value = array[offset++];
-                               String valueLocation = SpreadsheetUtils.offset(location, i, j);
-
-                               ConstantPropertyVariableBuilder labelBuilder = new ConstantPropertyVariableBuilder(ClientModel.LABEL, value, Bindings.STRING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS);
-                               ConstantPropertyVariableBuilder typeBuilder = new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet());
-                               
-                               map.put(valueLocation, new ConstantChildVariable(context, valueLocation, labelBuilder, typeBuilder, immutableBuilder));
-                               
-                       }
-               }
-               
-               return map;
-               
-               }
-               
+    public static ValueAccessor contentDisplayValueAccessor = new ValueAccessor() {
+
+        @Override
+        public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {
+            if (!Bindings.STRING.equals(binding)) throw new IllegalArgumentException();
+            if (!(value instanceof String)) throw new IllegalArgumentException();
+
+            if (((String)value).startsWith("=")) {
+                context.getParent(graph).setValue(graph, value, Bindings.STRING);
+            } else {
+                context.getParent(graph).setValue(graph, new Variant(Bindings.STRING, value), Bindings.VARIANT);
+            }
+        }
+
+        @Override
+        public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {
+            if (!(value instanceof String)) throw new IllegalArgumentException();
+
+            if (((String)value).startsWith("=")) {
+                context.getParent(graph).setValue(graph, value, Bindings.STRING);
+            } else {
+                context.getParent(graph).setValue(graph, new Variant(Bindings.STRING, value), Bindings.VARIANT);
+            }
+        }
+
+        @Override
+        public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {
+            return context.getParent(graph).getValue(graph, binding);
+        }
+
+        @Override
+        public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {
+            return context.getParent(graph).getValue(graph);
+        }
+
+        @Override
+        public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {
+            return context.getParent(graph).getDatatype(graph);
+        }
+
     };
 
-       @SCLValue(type = "VariableMap")
-       public static VariableMap queryRangeChildren = new VariableMapImpl() {
-       
-               @Override
-               public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
-                       
-                       TMap<String, Variable> map = new THashMap<String, Variable>();
-                       getVariables(graph, context, map);
-                       return map.get(name);                                   
-                       
-               }
-
-               @Override
-               public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
-                       
-               SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
-    
-               String location = "A1";
-               
-               try {
-                       
-                       Object object = context.getPropertyValue(graph, sr.ExpressionRange_cells);
-                       
-                       List<?> data = (List<?>)object;
-                       
-                       if(map == null) map = new HashMap<String,Variable>();
-                       
-                       for(Object o : data) {
-                               if(o instanceof ITableCell) {
-
-                                       ITableCell cell = (ITableCell)o;
-                                       
-                                       String valueLocation = SpreadsheetUtils.offset(location, cell.getRow(), cell.getColumn());
-
-                                       ArrayList<ConstantPropertyVariableBuilder> builders = new ArrayList<ConstantPropertyVariableBuilder>();
-                                       
-                                       builders.add(new ConstantPropertyVariableBuilder(ClientModel.CONTENT, Variant.ofInstance(cell.getText()), Bindings.VARIANT, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
-                                       builders.add(new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet()));
-                                       
-                                       IFont font = cell.getFont();
-                                       if(font != null) {
-                                               builders.add(new ConstantPropertyVariableBuilder(ClientModel.FONT, new Font(font.getFamily(), font.getHeight(), font.getStyle()), Font.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
-                                       }
-
-                                       int align = cell.getAlign();
-                                       builders.add(new ConstantPropertyVariableBuilder(ClientModel.ALIGN, align, Bindings.INTEGER, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
-                                       
-                                       IColor foreground = cell.getFGColor();
-                                       if(foreground != null) {
-                                               builders.add(new ConstantPropertyVariableBuilder(ClientModel.FOREGROUND, new RGB.Integer(foreground.red(), foreground.green(), foreground.blue()), RGB.Integer.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
-                                       }
-
-                                       IColor background = cell.getBGColor();
-                                       if(background != null) {
-                                               builders.add(new ConstantPropertyVariableBuilder(ClientModel.BACKGROUND, new RGB.Integer(background.red(), background.green(), background.blue()), RGB.Integer.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
-                                       }
-
-                                       map.put(valueLocation, new ConstantChildVariable(context, valueLocation, builders));
-
-                               }
-                       }
-                       
-               } catch (DatabaseException e) {
-                       throw (DatabaseException)e;
-               } catch (Throwable t) {
-                       throw new DatabaseException(t);
-               } finally {
-               }
-
-               return map;
-               
-               }
-               
+    @SCLValue(type = "VariableMap")
+    public static VariableMap stringArrayChildren = new VariableMapImpl() {
+
+        @Override
+        public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
+
+            TMap<String, Variable> map = new THashMap<String, Variable>();
+            getVariables(graph, context, map);
+            return map.get(name);                                      
+
+        }
+
+        @Override
+        public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
+
+            Resource resource = context.getRepresents(graph);
+
+            SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
+
+            String location = graph.getPossibleRelatedValue(resource, sr.Range_location, Bindings.STRING);
+            if(location == null) return map;
+            Integer width = graph.getPossibleRelatedValue(resource, sr.Range_widthBound, Bindings.INTEGER);
+            if(width == null) return map;
+            String[] array = graph.getPossibleRelatedValue(resource, sr.StringArrayRange_array, Bindings.STRING_ARRAY);
+            if(array == null) return map;
+
+            int rows = array.length / width;
+
+            if(map == null) map = new HashMap<String,Variable>();
+
+            for(int offset=0,i=0;i<rows;i++) {
+                for(int j=0;j<width;j++) {
+
+                    String value = array[offset++];
+                    String valueLocation = Spreadsheets.offset(location, i, j);
+
+                    ConstantPropertyVariableBuilder labelBuilder = new ConstantPropertyVariableBuilder(ClientModel.LABEL, value, Bindings.STRING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS);
+                    ConstantPropertyVariableBuilder typeBuilder = new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet());
+
+                    map.put(valueLocation, new ConstantChildVariable(context, valueLocation, labelBuilder, typeBuilder, immutableBuilder));
+
+                }
+            }
+
+            return map;
+
+        }
+
+    };
+
+    @SCLValue(type = "VariableMap")
+    public static VariableMap queryRangeChildren = new VariableMapImpl() {
+
+        @Override
+        public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
+
+            TMap<String, Variable> map = new THashMap<String, Variable>();
+            getVariables(graph, context, map);
+            return map.get(name);                                      
+
+        }
+
+        @Override
+        public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
+
+            SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
+
+            String location = "A1";
+
+            try {
+
+                Object object = context.getPropertyValue(graph, sr.ExpressionRange_cells);
+
+                List<?> data = (List<?>)object;
+
+                if(map == null) map = new HashMap<String,Variable>();
+
+                for(Object o : data) {
+                    if(o instanceof ITableCell) {
+
+                        ITableCell cell = (ITableCell)o;
+
+                        String valueLocation = Spreadsheets.offset(location, cell.getRow(), cell.getColumn());
+
+                        ArrayList<ConstantPropertyVariableBuilder> builders = new ArrayList<ConstantPropertyVariableBuilder>();
+
+                        builders.add(new ConstantPropertyVariableBuilder(ClientModel.CONTENT, Variant.ofInstance(cell.getText()), Bindings.VARIANT, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
+                        builders.add(new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet()));
+
+                        IFont font = cell.getFont();
+                        if(font != null) {
+                            builders.add(new ConstantPropertyVariableBuilder(ClientModel.FONT, new Font(font.getFamily(), font.getHeight(), font.getStyle()), Font.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
+                        }
+
+                        int align = cell.getAlign();
+                        builders.add(new ConstantPropertyVariableBuilder(ClientModel.ALIGN, align, Bindings.INTEGER, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
+
+                        IColor foreground = cell.getFGColor();
+                        if(foreground != null) {
+                            builders.add(new ConstantPropertyVariableBuilder(ClientModel.FOREGROUND, new RGB.Integer(foreground.red(), foreground.green(), foreground.blue()), RGB.Integer.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
+                        }
+
+                        IColor background = cell.getBGColor();
+                        if(background != null) {
+                            builders.add(new ConstantPropertyVariableBuilder(ClientModel.BACKGROUND, new RGB.Integer(background.red(), background.green(), background.blue()), RGB.Integer.BINDING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS));
+                        }
+
+                        map.put(valueLocation, new ConstantChildVariable(context, valueLocation, builders));
+
+                    }
+                }
+
+            } catch (DatabaseException e) {
+                throw (DatabaseException)e;
+            } catch (Throwable t) {
+                throw new DatabaseException(t);
+            } finally {
+            }
+
+            return map;
+
+        }
+
     };
 
-       @SCLValue(type = "VariableMap")
-       public static VariableMap spreadsheetLinesChildren = new StandardChildDomainChildren() {
-       
-               @Override
-               public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
-                       
-                       if(ProxyVariables.isProxy(graph, context))
-                               return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, null, name);
-                       
-                       return super.getVariable(graph, context, name);
-                       
+    @SCLValue(type = "VariableMap")
+    public static VariableMap spreadsheetLinesChildren = new StandardChildDomainChildren() {
+
+        @Override
+        public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
+
+            if(ProxyVariables.isProxy(graph, context))
+                return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, null, name);
+
+            return super.getVariable(graph, context, name);
+
 //                     TMap<String, Variable> map = new THashMap<String, Variable>();
 //                     getVariables(graph, context, map);
 //                     return map.get(name);
 
-               }
-
-               @Override
-               public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
-
-                       if(ProxyVariables.isProxy(graph, context))
-                               return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, Collections.emptyMap(), map);
-
-//             Resource lines = context.getRepresents(graph);
-//             
-//             BTree bt = new BTree(graph, lines, true);
-//             List<Tuple2> entries = bt.entriesOfBTree(graph);
-//             for(Tuple2 tuple : entries) {
-//                     Variant v = (Variant)tuple.get(0);
-//                     Resource line = (Resource)tuple.get(1);
-//                     String name = v.getValue().toString();
-//                     Variable child = org.simantics.db.layer0.function.All.getStandardChildDomainChildVariable(graph, context, line, name);
-//                     if(map == null) map = new THashMap<String,Variable>();
-//                     map.put(name, child);
-//             }
-//    
-//             return map;
-
-//                     return org.simantics.db.layer0.function.All.standardChildDomainChildren.getVariables(graph, context, map);
-
-                       return super.getVariables(graph, context, map);
-                       
-               }
-               
+        }
+
+        @Override
+        public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
+
+            System.err.println("getVariables " + context.getURI(graph));
+
+            if(ProxyVariables.isProxy(graph, context))
+                return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, Collections.emptyMap(), map);
+
+            return super.getVariables(graph, context, map);
+
+        }
+
     };
-    
+
     @SCLValue(type = "VariableMap")
-       public static VariableMap doubleArrayChildren = new VariableMapImpl() {
-       
-               @Override
-               public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
-                       
-                       TMap<String, Variable> map = new THashMap<String, Variable>();
-                       getVariables(graph, context, map);
-                       return map.get(name);                                   
-                       
-               }
-
-               @Override
-               public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
-                       
-                       Resource resource = context.getRepresents(graph);
-                       
-               SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
-               
-               String location = graph.getPossibleRelatedValue(resource, sr.Range_location, Bindings.STRING);
-               if(location == null) return map;
-               Integer width = graph.getPossibleRelatedValue(resource, sr.Range_widthBound, Bindings.INTEGER);
-               if(width == null) return map;
-               double[] array = graph.getPossibleRelatedValue(resource, sr.DoubleArrayRange_array, Bindings.DOUBLE_ARRAY);
-               if(array == null) return map;
-               
-               if(map == null) map = new HashMap<String,Variable>();
-               
-               int rows = array.length / width;
-               
-               for(int offset=0,i=0;i<rows;i++) {
-                       for(int j=0;j<width;j++) {
-                               
-                               double value = array[offset++];
-                               String valueLocation = SpreadsheetUtils.offset(location, i, j);
-
-                               ConstantPropertyVariableBuilder labelBuilder = new ConstantPropertyVariableBuilder(ClientModel.LABEL, String.valueOf(value), Bindings.STRING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS);
-                               ConstantPropertyVariableBuilder typeBuilder = new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet());
-                               
-                               map.put(valueLocation, new ConstantChildVariable(context, valueLocation, labelBuilder, typeBuilder, immutableBuilder));
-                               
-                       }
-               }
-
-               return map;
-               
-               }
-               
+    public static VariableMap doubleArrayChildren = new VariableMapImpl() {
+
+        @Override
+        public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
+
+            TMap<String, Variable> map = new THashMap<String, Variable>();
+            getVariables(graph, context, map);
+            return map.get(name);                                      
+
+        }
+
+        @Override
+        public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
+
+            Resource resource = context.getRepresents(graph);
+
+            SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
+
+            String location = graph.getPossibleRelatedValue(resource, sr.Range_location, Bindings.STRING);
+            if(location == null) return map;
+            Integer width = graph.getPossibleRelatedValue(resource, sr.Range_widthBound, Bindings.INTEGER);
+            if(width == null) return map;
+            double[] array = graph.getPossibleRelatedValue(resource, sr.DoubleArrayRange_array, Bindings.DOUBLE_ARRAY);
+            if(array == null) return map;
+
+            if(map == null) map = new HashMap<String,Variable>();
+
+            int rows = array.length / width;
+
+            for(int offset=0,i=0;i<rows;i++) {
+                for(int j=0;j<width;j++) {
+
+                    double value = array[offset++];
+                    String valueLocation = Spreadsheets.offset(location, i, j);
+
+                    ConstantPropertyVariableBuilder labelBuilder = new ConstantPropertyVariableBuilder(ClientModel.LABEL, String.valueOf(value), Bindings.STRING, Collections.<ConstantPropertyVariableBuilder>emptyList(), CLASSIFICATIONS);
+                    ConstantPropertyVariableBuilder typeBuilder = new ConstantPropertyVariableBuilder(Variables.TYPE, sr.Cell, null, Collections.<ConstantPropertyVariableBuilder>emptyList(), Collections.<String>emptySet());
+
+                    map.put(valueLocation, new ConstantChildVariable(context, valueLocation, labelBuilder, typeBuilder, immutableBuilder));
+
+                }
+            }
+
+            return map;
+
+        }
+
     };
 
     static class SpreadsheetProxyChildVariable extends ProxyChildVariable {
@@ -515,38 +508,38 @@ public class All {
         public SpreadsheetProxyChildVariable(Variable base, Variable parent, Variable other, String name) {
             super(base, parent, other, name);
         }
-    
+
         @Override
         public Variable create(Variable base, Variable parent, Variable other, String name) {
             return new SpreadsheetProxyChildVariable(base, parent, other, name);
         }
-        
+
         public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {
-            
-               if(CONTEXT_END.equals(name)) {
-               if(other instanceof ProxyChildVariable) {
-                       // The context is also a proxy - let it do the job
+
+            if(CONTEXT_END.equals(name)) {
+                if(other instanceof ProxyChildVariable) {
+                    // The context is also a proxy - let it do the job
                     return super.getPossibleChild(graph, name);
-               } else {
-                       return org.simantics.db.layer0.function.All.buildChildVariable(graph, this, base.getRepresents(graph), null);
-               }
-               }
-            
+                } else {
+                    return org.simantics.db.layer0.function.All.buildChildVariable(graph, this, base.getRepresents(graph), null);
+                }
+            }
+
             return super.getPossibleChild(graph, name);
-            
+
         }
-        
+
         public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {
 
             Collection<Variable> result = super.getChildren(graph);
             if(!(base instanceof ProxyChildVariable)) {
-               Variable root = org.simantics.db.layer0.function.All.buildChildVariable(graph, this, base.getRepresents(graph), null);
-               result.add(root);
+                Variable root = org.simantics.db.layer0.function.All.buildChildVariable(graph, this, base.getRepresents(graph), null);
+                result.add(root);
             }
             return result;
-            
+
         }       
-             
+
     }
 
     @SCLValue(type = "VariableMap")
@@ -554,10 +547,10 @@ public class All {
 
         @Override
         public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
-               
-               if(ProxyChildVariable.CONTEXT_BEGIN.equals(name)) return getProxy(graph, context);
+
+            if(ProxyChildVariable.CONTEXT_BEGIN.equals(name)) return getProxy(graph, context);
             return org.simantics.db.layer0.function.All.standardChildDomainChildren.getVariable(graph, context, name);
-            
+
         }
 
         private Variable getProxy(ReadGraph graph, Variable context) throws DatabaseException {
@@ -569,9 +562,9 @@ public class All {
         @Override
         public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map)
                 throws DatabaseException {
-               
+
             map = org.simantics.db.layer0.function.All.standardChildDomainChildren.getVariables(graph, context, map);
-            
+
             if(map == null) map = new HashMap<String,Variable>();
             map.put(ProxyChildVariable.CONTEXT_BEGIN, getProxy(graph, context));
             return map;
@@ -579,160 +572,160 @@ public class All {
 
     };
 
-   
+
     @SCLValue(type = "ReadGraph -> Resource -> Variable -> CellEditor")
     public static CellEditor<Write> defaultSheetCellEditor(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {
 
-       final Variable sheet = context_.getParent(graph);
-       
-       return new GraphCellEditorAdapter(null) {
-
-               @Override
-               public <T> void edit(final Transaction<Write> transaction, final String location, final String property, final T value, final Binding binding, Consumer<?> callback) {
-
-                       SpreadsheetUtils.schedule(transaction, new WriteRequest() {
-                               
-                               @Override
-                               public void perform(WriteGraph graph) throws DatabaseException {
-                                       CellEditor<Write> editor = getPossibleCellEditor(graph, location, value == null ? null : new Variant(binding, value));
-                                       if (editor == null)
-                                           return;
-                                       editor.edit(transaction, location, property, value, binding, callback);
-                               }
-                       });
-                       
-               }
-               
-               @Override
-               public void edit(final Transaction<Write> transaction, final String location, final Variant value, Consumer<?> callback) {
-                       SpreadsheetUtils.schedule(transaction, new WriteRequest() {
-                               
-                               @Override
-                               public void perform(WriteGraph graph) throws DatabaseException {
-                                   CellEditor<Write> editor = getPossibleCellEditor(graph, location, value);
-                                   if (editor == null)
-                                       return;
-                                       editor.edit(transaction, location, value, callback);
-                               }
-                       });
-                       
-               }
-               
+        final Variable sheet = context_.getParent(graph);
+
+        return new GraphCellEditorAdapter(null) {
+
+            @Override
+            public <T> void edit(final Transaction<Write> transaction, final String location, final String property, final T value, final Binding binding, Consumer<?> callback) {
+
+                SpreadsheetUtils.schedule(transaction, new WriteRequest() {
+
+                    @Override
+                    public void perform(WriteGraph graph) throws DatabaseException {
+                        CellEditor<Write> editor = getPossibleCellEditor(graph, location, value == null ? null : new Variant(binding, value));
+                        if (editor == null)
+                            return;
+                        editor.edit(transaction, location, property, value, binding, callback);
+                    }
+                });
+
+            }
+
+            @Override
+            public void edit(final Transaction<Write> transaction, final String location, final Variant value, Consumer<?> callback) {
+                SpreadsheetUtils.schedule(transaction, new WriteRequest() {
+
+                    @Override
+                    public void perform(WriteGraph graph) throws DatabaseException {
+                        CellEditor<Write> editor = getPossibleCellEditor(graph, location, value);
+                        if (editor == null)
+                            return;
+                        editor.edit(transaction, location, value, callback);
+                    }
+                });
+
+            }
+
             private CellEditor<Write> getPossibleCellEditor(WriteGraph graph, String location, Variant value) throws DatabaseException {
                 SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
-                   Range range = SpreadsheetUtils.decodePossibleCellAbsolute(location);
-                   if(range == null) return null; //No editor found
-                   
-                   List<Variable> cells = SpreadsheetGraphUtils.possibleConfigurationCellVariables(graph, sheet, range);
-                   if (cells.isEmpty()) {
-                       if (value == null) {
-                           return null;
-                       } else {
-                           cells = SpreadsheetGraphUtils.getOrCreateConfigurationCellVariables(graph, sheet, range);
-                       }
-                   }
-                   if (cells.size() != 1)
-                       throw new DatabaseException("Can edit only one cell at a time!");
-                       
-                   return cells.iterator().next().getPropertyValue(graph, SHEET.cellEditor);
+                Range range = Spreadsheets.decodePossibleCellAbsolute(location);
+                if(range == null) return null; //No editor found
+
+                List<Variable> cells = SpreadsheetGraphUtils.possibleConfigurationCellVariables(graph, sheet, range);
+                if (cells.isEmpty()) {
+                    if (value == null) {
+                        return null;
+                    } else {
+                        cells = SpreadsheetGraphUtils.getOrCreateConfigurationCellVariables(graph, sheet, range);
+                    }
+                }
+                if (cells.size() != 1)
+                    throw new DatabaseException("Can edit only one cell at a time!");
+
+                return cells.iterator().next().getPropertyValue(graph, SHEET.cellEditor);
             }
 
-               @Override
-               public void copy(final Transaction<Write> transaction, final String location, final MutableVariant variant, Consumer<?> callback) {
+            @Override
+            public void copy(final Transaction<Write> transaction, final String location, final MutableVariant variant, Consumer<?> callback) {
+
+                SpreadsheetUtils.schedule(transaction, new WriteRequest() {
+
+                    @Override
+                    public void perform(WriteGraph graph) throws DatabaseException {
 
-                       SpreadsheetUtils.schedule(transaction, new WriteRequest() {
+                        SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
+                        Variable variable = sheet.getPossibleChild(graph, location);
+                        if(variable != null) {
+                            CellEditor<Write> editor = variable.getPossiblePropertyValue(graph, SHEET.cellEditor);
+                            if(editor != null) {
+                                editor.copy(transaction, location, variant, null);
+                            }
+                        }
+                    }
 
-                               @Override
-                               public void perform(WriteGraph graph) throws DatabaseException {
+                });
 
-                                       SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
-                                       Variable variable = sheet.getPossibleChild(graph, location);
-                                       if(variable != null) {
-                                                       CellEditor<Write> editor = variable.getPossiblePropertyValue(graph, SHEET.cellEditor);
-                                                       if(editor != null) {
-                                                               editor.copy(transaction, location, variant, null);
-                                                       }
-                                       }
-                               }
+            }
 
-                       });
+        };
 
-               }
-               
-       };
-       
     }
 
     @SCLValue(type = "ReadGraph -> Resource -> Variable -> CellEditor")
     public static CellEditor<Write> variableCellEditor(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {
 
-       final Variable cell = context_.getParent(graph);
-       
-       return new GraphCellEditorAdapter(cell) {
+        final Variable cell = context_.getParent(graph);
 
-               @Override
-               public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, String property, T value, Binding binding) throws DatabaseException {
-                       cell.setPropertyValue(graph, property, value, binding);
-               }
-       };
+        return new GraphCellEditorAdapter(cell) {
+
+            @Override
+            public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, String property, T value, Binding binding) throws DatabaseException {
+                cell.setPropertyValue(graph, property, value, binding);
+            }
+        };
     }
-    
+
     private static int encodeLineOrNode(ReadGraph graph, Resource r) throws DatabaseException {
-       if(r == null) return 0;
-       Layer0 L0 = Layer0.getInstance(graph);
-               String name = graph.getRelatedValue(r, L0.HasName, Bindings.STRING);
-               if(name.charAt(0) == 'R') {
-               return -Integer.parseInt(name.substring(3));
-               } else {
-                       return Integer.parseInt(name);
-               }
+        if(r == null) return 0;
+        Layer0 L0 = Layer0.getInstance(graph);
+        String name = graph.getRelatedValue(r, L0.HasName, Bindings.STRING);
+        if(name.charAt(0) == 'R') {
+            return -Integer.parseInt(name.substring(3));
+        } else {
+            return Integer.parseInt(name);
+        }
     }
 
     @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
     public static int[] lineNodeKeys(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {
 
-       Resource node = context_.getParent(graph).getRepresents(graph);
-       BTreeContentBean bean = BTreeContentBean.readPossible(graph, node);
-       if(bean == null) return new int[0];
-       // There are n keys and n+1 resources
-       int[] result = new int[2*bean.n+1];
-       for(int i=0;i<bean.n;i++) {
-               result[2*i] = encodeLineOrNode(graph, bean.getChild(i));
-               result[2*i+1] = (int)bean.getKey(i).getValue();
-       }
-       result[2*bean.n] = encodeLineOrNode(graph, bean.getChild(bean.n));
-       return result;
-       
+        Resource node = context_.getParent(graph).getRepresents(graph);
+        BTreeContentBean bean = BTreeContentBean.readPossible(graph, node);
+        if(bean == null) return new int[0];
+        // There are n keys and n+1 resources
+        int[] result = new int[2*bean.n+1];
+        for(int i=0;i<bean.n;i++) {
+            result[2*i] = encodeLineOrNode(graph, bean.getChild(i));
+            result[2*i+1] = (int)bean.getKey(i).getValue();
+        }
+        result[2*bean.n] = encodeLineOrNode(graph, bean.getChild(bean.n));
+        return result;
+
     }
 
     @SCLValue(type = "ReadGraph -> Resource -> Variable -> LineContentBean")
     public static LineContentBean defaultLineCells(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {
-       
+
         String contextUri = context_.getURI(graph);
-        
-       Variable line = context_.getParent(graph);
-       
-       Collection<Variable> children = line.getChildren(graph);
-       ObjectArrayList<LineContentBeanCell> result = new ObjectArrayList<>();
-       SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
-       for (Variable child : children) {
-           Resource repr = child.getRepresents(graph);
-           
-           Resource style = graph.getPossibleObject(repr, SR.Cell_HasStyle);
-           Integer styleId = null;
-           if (style != null)
-               styleId = graph.getPossibleRelatedValue(style, SR.Style_id, Bindings.INTEGER);
-           if (styleId == null) {
-               System.err.println("Style " + style + " has no ID or either cell "+ repr + " has no style attached to it !!");
-               styleId = SpreadsheetStyle.empty().getStyleId();
-           }
-
-               LineContentBeanCell cell = new LineContentBeanCell(styleId);
-               
-               Variant variant = child.getPossiblePropertyValue(graph, SR.Cell_content);
-               
+
+        Variable line = context_.getParent(graph);
+
+        Collection<Variable> children = line.getChildren(graph);
+        ObjectArrayList<LineContentBeanCell> result = new ObjectArrayList<>();
+        SpreadsheetResource SR = SpreadsheetResource.getInstance(graph);
+        for (Variable child : children) {
+            Resource repr = child.getRepresents(graph);
+
+            Resource style = graph.getPossibleObject(repr, SR.Cell_HasStyle);
+            Integer styleId = null;
+            if (style != null)
+                styleId = graph.getPossibleRelatedValue(style, SR.Style_id, Bindings.INTEGER);
+            if (styleId == null) {
+                System.err.println("Style " + style + " has no ID or either cell "+ repr + " has no style attached to it !!");
+                styleId = SpreadsheetStyle.empty().getStyleId();
+            }
+
+            LineContentBeanCell cell = new LineContentBeanCell(styleId);
+
+            Variant variant = child.getPossiblePropertyValue(graph, SR.Cell_content);
+
             if(variant != null) {
-                
+
                 Variable var = child.getPossibleProperty(graph, SR.Cell_content);
                 String expression = var.getPossiblePropertyValue(graph, "expression");
                 if (expression != null) {
@@ -740,35 +733,35 @@ public class All {
                 } else {
                     cell.setContent(variant);
                 }
-                Range r = SpreadsheetUtils.decodeCellAbsolute(child.getName(graph));
+                Range r = Spreadsheets.decodeCellAbsolute(child.getName(graph));
 //                result.add(cell);
                 while(result.size() < r.startColumn + 1)
                     result.add(new LineContentBeanCell());
                 result.set(r.startColumn, cell);
-                    
+
             }
 
-       }
-       LineContentBean bean = new LineContentBean();
-       bean.cells = result.toArray(new LineContentBeanCell[result.size()]);
-       return bean;
-       
+        }
+        LineContentBean bean = new LineContentBean();
+        bean.cells = result.toArray(new LineContentBeanCell[result.size()]);
+        return bean;
+
     }
-    
+
     @SCLValue(type = "ReadGraph -> Resource -> Variable -> CellEditor")
     public static CellEditor<Write> textCellEditor(ReadGraph graph, Resource resource, final Variable context_) throws DatabaseException {
 
         System.out.println("Context URI : " + context_.getURI(graph));
-       Variable cells = context_.getParent(graph);
-       System.out.println("Cell URI : " + cells.getURI(graph));
-       
-       return new GraphCellEditorAdapter(cells) {
-
-               public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, String property, T value, Binding binding) throws DatabaseException {
-                   
-                       SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
-                       if(ClientModel.CONTENT.equals(property)) {
-                               cell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);
+        Variable cells = context_.getParent(graph);
+        System.out.println("Cell URI : " + cells.getURI(graph));
+
+        return new GraphCellEditorAdapter(cells) {
+
+            public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, String property, T value, Binding binding) throws DatabaseException {
+
+                SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
+                if(ClientModel.CONTENT.equals(property)) {
+                    cell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);
                     Variable runCell = null;
                     Object transactionContext = transaction.getContext();
                     if (transactionContext != null && transactionContext instanceof Variable) {
@@ -781,10 +774,11 @@ public class All {
                             transaction.needSynchronization(cell.getParent(graph));
                         }
                     }
-                               if (runCell != null)
-                                   runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);
-                       } else if(ClientModel.CONTENT_EXPRESSION.equals(property)) {
-                               cell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.STRING);
+                    if (runCell != null)
+                        runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);
+                } else if(ClientModel.CONTENT_EXPRESSION.equals(property)) {
+                    System.err.println("cell: " + cell.getURI(graph));
+                    cell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.STRING);
                     Variable runCell = null;
                     Object transactionContext = transaction.getContext();
                     if (transactionContext != null && transactionContext instanceof Variable) {
@@ -797,53 +791,56 @@ public class All {
                             transaction.needSynchronization(cell.getParent(graph));
                         }
                     }
-                               if (runCell != null)
-                                   runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.STRING);
-                       } else if(ClientModel.BORDER.equals(property)) {
+                    if (runCell != null)
+                        runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.STRING);
+                    // SCL expressions always require synchronization
+                    if(value.toString().startsWith("=="))
+                        transaction.needSynchronization(cell.getParent(graph));
+                } else if(ClientModel.BORDER.equals(property)) {
                     Resource textCell = cell.getRepresents(graph);
                     Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);
                     SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);
                     builder.border((Integer)value);
                     finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);
-                       } else if(ClientModel.ALIGN.equals(property)) {
+                } else if(ClientModel.ALIGN.equals(property)) {
                     Resource textCell = cell.getRepresents(graph);
                     Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);
                     SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);
                     builder.align((Integer)value);
                     finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);
-                       } else if(ClientModel.LOCKED.equals(property)) {
-                               cell.setPropertyValue(graph, SHEET.Cell_locked, value, Bindings.BOOLEAN);       
-                       } else if(ClientModel.ROW_SPAN.equals(property)) {
-                               cell.setPropertyValue(graph, SHEET.Cell_rowSpan, value, Bindings.INTEGER);
-                       } else if(ClientModel.COLUMN_SPAN.equals(property)) {
-                               cell.setPropertyValue(graph, SHEET.Cell_columnSpan, value, Bindings.INTEGER);
-                       } else if(ClientModel.FONT.equals(property)) {
+                } else if(ClientModel.LOCKED.equals(property)) {
+                    cell.setPropertyValue(graph, SHEET.Cell_locked, value, Bindings.BOOLEAN);  
+                } else if(ClientModel.ROW_SPAN.equals(property)) {
+                    cell.setPropertyValue(graph, SHEET.Cell_rowSpan, value, Bindings.INTEGER);
+                } else if(ClientModel.COLUMN_SPAN.equals(property)) {
+                    cell.setPropertyValue(graph, SHEET.Cell_columnSpan, value, Bindings.INTEGER);
+                } else if(ClientModel.FONT.equals(property)) {
                     Resource textCell = cell.getRepresents(graph);
                     Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);
                     SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);
                     builder.font((Font)value);
                     finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);
-                       } else if(ClientModel.FOREGROUND.equals(property)) {
-                           Resource textCell = cell.getRepresents(graph);
-                           Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);
-                           SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);
-                           builder.foreground((RGB.Integer)value);
-                           finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);
-                       } else if(ClientModel.BACKGROUND.equals(property)) {
+                } else if(ClientModel.FOREGROUND.equals(property)) {
+                    Resource textCell = cell.getRepresents(graph);
+                    Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);
+                    SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);
+                    builder.foreground((RGB.Integer)value);
+                    finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);
+                } else if(ClientModel.BACKGROUND.equals(property)) {
                     Resource textCell = cell.getRepresents(graph);
                     Resource styleContainer = graph.getSingleObject(textCell, SHEET.Cell_HasStyle);
                     SpreadsheetStyleBuilder builder = computeStyleBuilder(SHEET, graph, styleContainer);
                     builder.background((RGB.Integer)value);
                     finishStyleUpdate(graph, SHEET, styleContainer, textCell, builder, transaction);
-                       }
-               }
-               
-               private void finishStyleUpdate(WriteGraph graph, SpreadsheetResource SHEET, Resource styleContainer, Resource textCell, SpreadsheetStyleBuilder builder, Transaction<?> transaction) throws DatabaseException {
-                
+                }
+            }
+
+            private void finishStyleUpdate(WriteGraph graph, SpreadsheetResource SHEET, Resource styleContainer, Resource textCell, SpreadsheetStyleBuilder builder, Transaction<?> transaction) throws DatabaseException {
+
                 Variable bookVariable = Variables.getContext(graph, cell);
                 Resource book = bookVariable.getRepresents(graph);
                 Resource createdStyle = null;
-                
+
                 SpreadsheetStyle style = builder.build();
                 int styleId = style.getStyleId();
 
@@ -856,34 +853,17 @@ public class All {
                     }
                 }
                 if (createdStyle == null) {
-                       style = builder.name("Style_" + existingStyles.size()).build();
+                    style = builder.name("Style_" + existingStyles.size()).build();
                     createdStyle = SpreadsheetGraphUtils.createStyle(graph, book, style);
                 }
-                
+
                 graph.deny(textCell, SHEET.Cell_HasStyle);
                 Collection<Resource> cellsOfStyle = graph.getObjects(styleContainer, SHEET.Cell_StyleOf);
                 if (cellsOfStyle.isEmpty()) {
                     graph.deny(styleContainer);
                 }
                 graph.claim(textCell, SHEET.Cell_HasStyle, createdStyle);
-                
-//                Variable runCell = null;
-//                Object transactionContext = transaction.getContext();
-//                if (transactionContext != null && transactionContext instanceof Variable) {
-//                    Variable varContext = (Variable) transactionContext;
-//                    Variable context = Variables.getContext(graph, varContext);
-//                    try {
-//                        runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);
-//                    } catch (MissingVariableException e) {
-//                        //Creating new cell, need synchronizing
-//                        transaction.needSynchronization(cell.getParent(graph));
-//                    }
-//                }
-//                if (runCell != null) {
-//                    Datatype type = new RecordType();
-//                    Binding b = Bindings.getBinding(type);
-//                    runCell.setPropertyValue(graph, SHEET.Cell_style, style, b);
-//                }
+
             }
 
             private SpreadsheetStyleBuilder computeStyleBuilder(SpreadsheetResource SHEET, WriteGraph graph, Resource styleContainer) throws DatabaseException {
@@ -892,18 +872,18 @@ public class All {
                 Font font = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_font, Font.BINDING);
                 Integer align = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_align, Bindings.INTEGER);
                 Integer border = graph.getPossibleRelatedValue2(styleContainer, SHEET.Cell_border, Bindings.INTEGER);
-                
+
                 return SpreadsheetStyle.newInstace().foreground(foreground).background(background).font(font).align(align).border(border);
             }
 
             @Override
-               public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, Variant value) throws DatabaseException {
-                       SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
-                       
-                       // Handle possible deletes
-                       if (value == null)
-                           value = Variant.ofInstance("");
-                       
+            public <T> void edit(WriteGraph graph, Transaction<Write> transaction, String location, Variant value) throws DatabaseException {
+                SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
+
+                // Handle possible deletes
+                if (value == null)
+                    value = Variant.ofInstance("");
+
                 if (!transaction.isOperationMode()) {
                     cell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);
 //                    return;
@@ -919,19 +899,19 @@ public class All {
                         // Creating cell for the first time so no runCell available at this time, needs synchronization
                         transaction.needSynchronization(cell.getParent(graph));
                     }
-                    
+
                 }
 
-                       if (runCell != null) {
-                           System.out.println("All.edit " + runCell.getURI(graph));
-                           runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);
-                       }
-               }
-               
-               @Override
-               public <T> void copy(WriteGraph graph, Transaction<Write> transaction, String location, MutableVariant variant) throws DatabaseException {
-                       SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
-                       
+                if (runCell != null) {
+                    System.out.println("All.edit " + runCell.getURI(graph));
+                    runCell.setPropertyValue(graph, SHEET.Cell_content, value, Bindings.VARIANT);
+                }
+            }
+
+            @Override
+            public <T> void copy(WriteGraph graph, Transaction<Write> transaction, String location, MutableVariant variant) throws DatabaseException {
+                SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
+
                 Variable runCell = null;
                 Object transactionContext = transaction.getContext();
                 if (transactionContext != null && transactionContext instanceof Variable) {
@@ -939,55 +919,55 @@ public class All {
                     Variable context = Variables.getContext(graph, varContext);
                     runCell = Variables.switchRealization(graph, cell, context.getRepresents(graph), context);
                 }
-                       
-                       //Variant content = cell.getPropertyValue(graph, SHEET.Cell_content, Bindings.VARIANT);
-                       Object object = cell.getPropertyValue(graph, SHEET.Cell_content);
-                       Variant content = null;
-                       if (object instanceof Variant) {
-                           content = (Variant)object;
-                       } else if (object instanceof Double) {
-                           content = Variant.ofInstance((Double)object);
-                       } else if (object instanceof Float) {
-                               content = Variant.ofInstance((Float)object);
-                       } else if (object instanceof Integer) {
-                           content = Variant.ofInstance((Integer)object);
-                       } else if (object instanceof Long) {
-                           content = Variant.ofInstance((Long)object);
-                       } else if (object instanceof String) {
-                           content = Variant.ofInstance((String)object);
-                       } else if (object instanceof Variable) {
-                           content = Variant.ofInstance((Variable)object);
-                       } else {
-                           throw new DatabaseException("");
-                       }
-                       variant.setValue(content);
-               }
-               
-       };
-       
+
+                //Variant content = cell.getPropertyValue(graph, SHEET.Cell_content, Bindings.VARIANT);
+                Object object = cell.getPropertyValue(graph, SHEET.Cell_content);
+                Variant content = null;
+                if (object instanceof Variant) {
+                    content = (Variant)object;
+                } else if (object instanceof Double) {
+                    content = Variant.ofInstance((Double)object);
+                } else if (object instanceof Float) {
+                    content = Variant.ofInstance((Float)object);
+                } else if (object instanceof Integer) {
+                    content = Variant.ofInstance((Integer)object);
+                } else if (object instanceof Long) {
+                    content = Variant.ofInstance((Long)object);
+                } else if (object instanceof String) {
+                    content = Variant.ofInstance((String)object);
+                } else if (object instanceof Variable) {
+                    content = Variant.ofInstance((Variable)object);
+                } else {
+                    throw new DatabaseException("");
+                }
+                variant.setValue(content);
+            }
+
+        };
+
     }
-    
+
     @SCLValue(type = "ReadGraph -> Resource -> Variable -> Variable")
     public static Variable spreadsheetInput(ReadGraph graph, Resource converter, Variable sheet) throws DatabaseException {
-               return ProxyVariables.inputVariable(graph, sheet);
+        return ProxyVariables.inputVariable(graph, sheet);
     }
 
     @SCLValue(type = "ReadGraph -> Resource -> Variable -> Variable")
     public static Variable spreadsheetSession(ReadGraph graph, Resource converter, Variable sheet) throws DatabaseException {
-               return ProxyVariables.proxySessionVariable(graph, sheet);
+        return ProxyVariables.proxySessionVariable(graph, sheet);
     }
 
     @SCLValue(type = "ReadGraph -> Resource -> Variable -> Variable")
     public static Variable spreadsheetRunInput(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {
-       Resource model = Variables.getModel(graph, property);
-       Variable activeRun = graph.syncRequest(new PossibleActiveRun(model));
-       if(activeRun != null) return activeRun;
-       return Variables.getConfigurationContext(graph, model);
+        Resource model = Variables.getModel(graph, property);
+        Variable activeRun = graph.syncRequest(new PossibleActiveRun(model));
+        if(activeRun != null) return activeRun;
+        return Variables.getConfigurationContext(graph, model);
     }
-    
-       @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
     public static Object sclValue(ReadGraph graph, Resource converter, Variable context) throws DatabaseException {
-           return CompileSCLValueRequest.compileAndEvaluate(graph, context);
+        return CompileSCLValueRequest.compileAndEvaluate(graph, context);
     }
 
 }
\ No newline at end of file