       paramValue.set(evaluatedParams[paramName])
 
     # return result and patches, if any
-    return [result, model.makePatches(modelData)]
-
-  calculateBindingSet: (modelData, assets, oldBindings, bindingLayout) ->
+    return new NodeVisitorResult(result, GE.makePatches(constants.modelData, modelData), GE.makePatches(constants.serviceData, serviceData))
+
+  calculateBindingSet: (node, constants, oldBindings) ->
     bindingSet = []
 
     # TODO: multiply from values together in order to make every combination
-    if "from" of bindingLayout
-      for bindingName, bindingExpression of bindingLayout.from
+    if "from" of node
+      for bindingName, bindingExpression of node.from
         # Evaluate values of the "from" clauses
         # TODO: in the case of models, get reference to model rather than evaluate the data here
-        bindingValues = GE.compileParameter(modelData, assets, oldBindings, bindingExpression).get()
+        bindingValues = GE.compileParameter(bindingExpression, constants, oldBindings).get()
         for bindingIndex in [0..bindingValues.length - 1]
           # Avoid polluting old object, and avoid creating new properties
           newBindings = Object.create(oldBindings)

      if key of affectedKeys then return true
      affectedKeys[key] = true

  # Catches all errors in the function 
  sandboxFunctionCall: (model, assets, bindings, functionName, parameters) ->
    modelData = model.clonedData()
    compiledParams = (GE.compileParameter(modelData, assets, bindings, parameter) for parameter in parameters)
    evaluatedParams = (param.get() for param in compiledParams)

    try
      globals[functionName].apply({}, evaluatedParams)
    catch e
      GE.logWarning("Calling function #{functionName} raised an exception #{e}")
    
  # Catches all errors in the function 
  sandboxActionCall: (model, assets, bindings, actions, actionName, methodName, layoutParameters, childNames, signals) ->
    action = actions[actionName]

    # TODO: insure that all params values are POD
    # TODO: allow paramDefs to be missing

    modelData = model.clonedData()
    compiledParams = {}
    evaluatedParams = {}
    for paramName, defaultValue of action.paramDefs
      # Resolve parameter value. In order, try layout, bindings, and finally default
      if layoutParameters and paramName of layoutParameters
        paramValue = layoutParameters[paramName]
      else if paramName of bindings
        paramValue = bindings[paramName]
      else 
        paramValue = defaultValue

      compiledParams[paramName] = GE.compileParameter(modelData, assets, bindings, paramValue)
      evaluatedParams[paramName] = compiledParams[paramName].get()
    locals = 
      params: evaluatedParams


# Install the GE namespace in the global scope
globals.GE = GE
