         node._cumulativeValue = 0
 
       # set the accumulator values
-      _.each @nodes, (node) ->
-        if node.isAccumulator
-          node.setAccumulatorValue nodeValues
+      collectorNodes = _.filter @nodes, (node) -> node.isAccumulator
+      _.each collectorNodes, (node) ->
+        node.setAccumulatorValue nodeValues
 
       time++
       @generateFrame(time)

  value

SetAccumulatorValueFunction = (nodeValues) ->
  # get add, subtract and transfer links
  links = @inLinks('accumulator').concat(@inLinks('transfer'))
  return unless links.length > 0

  value = 0
  for link in links
    {sourceNode, relation, transferNode} = link
    inV = nodeValues[sourceNode.key]
    switch relation.type
      when 'accumulator'
        # TODO: check if outV is really equal to inV here - I'm not clear what outV is in this case'
        value += relation.evaluate(inV, inV, sourceNode.max, @max)

      when 'transfer'
        # TODO: check with Dan if the transfer value really is meant to be a percentage
        transferValue = nodeValues[transferNode.key]
        transferPercentage = transferValue / Math.max(transferNode.max, transferValue)
        for modifierLink in transferNode.inLinks('transfer-modifier')
          transferPercentage *= modifierLink.relation.evaluate(inV, inV, sourceNode.max, transferNode.max)

        finalTransferValue = inV * transferPercentage
        value += finalTransferValue
        # TODO: check with Dan if we take 1/100th of the value or 1/Math.pow(100,links.length)
        sourceValue = sourceNode.currentValue - (finalTransferValue / 100)
        sourceNode.currentValue = sourceNode.filterFinalValue sourceValue

  delta = value / Math.pow(100, links.length)
  # accumulators hold their values in previousValue which is confusing
  # (this done because the accumulator values is only computed on the first of the 20 loops in RangeIntegrationFunction)
  # TODO: possibly change RangeIntegrationFunction function to make this more clear
  @currentValue = @filterFinalValue @previousValue + delta

module.exports = class Simulation


  else
    return val

combineInputs = (inValues, useScaledProduct) ->
  return null if not inValues?.length
  return inValues[0] if inValues.length is 1

  if useScaledProduct
    # scaled product is computed as (n1 * n2 * ...) / 100^(n-1)
    numerator = _.reduce(inValues, ((prod, value) -> prod * value), 1)
    denominator = Math.pow(100, inValues.length - 1)
  else
    # simple arithmetic mean
    numerator = _.reduce(inValues, ((sum, value) -> sum + value), 0)
    denominator = inValues.length

  numerator / denominator

RangeIntegrationFunction = (incrementAccumulators) ->

  # if we've already calculated a currentValue for ourselves this step, return it
  return @currentValue if @currentValue?
  return @previousValue if @isAccumulator and not incrementAccumulators

  # regular nodes and flow nodes only have 'range' and 'transfer-modifier' links
  links = @inLinks('range').concat(@inLinks('transfer-modifier'))
  count = links.length

  # if we have no incoming links, we always remain our previous or initial value
  # collectors aren't calculated in this phase, but they do capture initial/previous values
  startValue = if @previousValue? then @previousValue else @initialValue
  return startValue if @isAccumulator or count < 1

  value = 0
  inValues = []

  _.each links, (link) =>
    return unless link.relation.isDefined
    sourceNode = link.sourceNode
    inV = if sourceNode.previousValue? then sourceNode.previousValue else sourceNode.initialValue
    inV = scaleInput(inV, sourceNode, this)
    outV = startValue
    inValues.push link.relation.evaluate(inV, outV, link.sourceNode.max, @max)

  # for now, if any a node points to a collector, it should use the scaled product
  # ultimately this should be a default which can be overridden by the user, in
  # which case the setting would presumably become part of the node model
  useScaledProduct = !!(_.find @outLinks(), (link) -> link.targetNode.isAccumulator)
  value = combineInputs(inValues, useScaledProduct)

  # if we need to cap, do it at end of all calculations
  value = @filterFinalValue value
