     @reset(Point.zero(), Point.zero())
 
   reset: (position, sourcePosition) ->
-    @sourceIterator.seek(sourcePosition)
     @position = position
     @sourcePosition = sourcePosition
+    @bufferedOutputs = []
     @bufferedSourceOutput = null
-    @bufferedOutputs = []
-    @bufferedPositions = []
-    @bufferedSourcePositions = []
+    @sourceIterator.seek(sourcePosition)
 
   read: =>
-    @bufferedSourceOutput ?= @sourceIterator.next().value
+    @bufferedSourceOutput or= @sourceIterator.next().value
 
   consume: (count) =>
     @sourcePosition.column += count
-    @bufferedSourceOutput = @bufferedSourceOutput.slice(count)
-    @bufferedSourceOutput = null if @bufferedSourceOutput is ""
+    @bufferedSourceOutput = @bufferedSourceOutput.substring(count)
 
   produce: (output) =>
     switch output

      else
        @position.column += output.length

    @bufferedSourcePositions.push(@sourcePosition.copy())
    @bufferedPositions.push(@position.copy())
    @bufferedOutputs.push(output)

    return if position.isZero()

    until @position.compare(position) >= 0
      lastPosition = @position
      lastSourcePosition = @sourcePosition
      {done} = @next()
      return if done

    unless @position.compare(position) is 0
      overshoot = position.column - lastPosition.column
      lastSourcePosition.column += overshoot
      @position = position
      @sourcePosition = lastSourcePosition
    @transformDelegate.reset(@position, @sourcePosition)

  seekToSourcePosition: (position) ->
