       throw GE.makeExecutionError("Missing input pin expression function for pin '#{pinName}'", path)
     
     try
-      evaluatedPins[pinName] = evaluationContext.evaluateExpressionFunction(pinFunction)
+      # Get the value
+      evaluatedPins[pinName] = GE.evaluateExpressionFunction(constants, evaluationContext, pinFunction)
+      
+      # Protect inout pins from changing buffer values directly by cloning the data
+      if pinOptions.direction is "inout"
+        evaluatedPins[pinName] = GE.cloneData(evaluatedPins[pinName]) 
     catch error
       throw GE.makeExecutionError("Error evaluating the input pin expression expression '#{pinFunction}' for pin '#{pinName}': #{error.stack}", path)
   return evaluatedPins
 
 # Updates the evaluation context by evaluating the output pin expressions
 # pinFunctions is an object that contains 'in' and 'out' attributes
-GE.evaluateOutputPinExpressions = (path, evaluationContext, pinDefs, pinFunctions, evaluatedPins) ->
-  # Only output pins should be accessible
-  outPins = _.pick(evaluatedPins, (pinName for pinName, pinOptions of pinDefs when pinOptions.direction in ["out", "inout"]))
-
+GE.evaluateOutputPinExpressions = (path, bindings, evaluationContext, memoryPatches, ioPatches, pinDefs, pinFunctions, evaluatedPins) ->
   for pinName, pinFunction of pinFunctions?.out
     try
-      outputValue = evaluationContext.evaluateExpressionFunction(pinFunction, outPins)
+      outputValue = evaluationContext.evaluateExpressionFunction(pinFunction, evaluatedPins)
     catch error
       throw GE.makeExecutionError("Error evaluating the output pin expression '#{pinFunction}' for pin '#{pinName}': #{error.stack}\nOutput pins were #{JSON.stringify(outPins)}.", path)
 
-    [parent, key] = GE.getParentAndKey(evaluationContext, GE.splitAddress(pinName))
-    parent[key] = outputValue
+    GE.derivePatches(bindings, path, evaluationContext, memoryPatches, ioPatches, pinName, outputValue)
 
 GE.calculateBindingSet = (path, chip, constants, oldBindings) ->
   bindingSet = []

  # TODO: compile expressions ahead of time
  evaluationContext = new GE.EvaluationContext(constants, bindings)
  GE.fillPinDefDefaults(switchChip.pinDefs)
  evaluatedPins = GE.evaluateInputPinExpressions(path, evaluationContext, switchChip.pinDefs, chip.pins)

  # check which children should be activated
  activeChildren = null


  return detectConflicts(affectedKeys)

# Creates a patch to the outputAddress of the given outputValue and appends it to either memoryPatches or ioPatches
# TODO: what an unweildy function, with more parameters than lines! Need to refactor it somehow
GE.derivePatches = (bindings, path, evaluationContext, memoryPatches, ioPatches, outputAddress, outputValue) -> 
  pathParts = GE.resolveBindingAddresses(bindings, GE.splitAddress(outputAddress))
  # Get the original value to compare the output against
  [parent, key] = GE.getParentAndKey(evaluationContext, pathParts)
  # Find which list to apply patches to (memory or io)
  destinationList = if pathParts[0] is "memory" then memoryPatches else ioPatches
  # Drop "memory" or "io" off the prefix for patches
  prefix = GE.joinPathParts(pathParts[1..])
  # Obtain patches and append them to the destination list
  GE.makePatches(parent[key], outputValue, path, prefix, destinationList)

# Set default values in pinDefs
GE.fillPinDefDefaults = (pinDefs) ->
  # Cannot use normal "for key, value of" loop because cannot handle replace null values
