         textNode = @domElementPool.buildText(lineText.substr(startIndex, tagCode))
         startIndex += tagCode
         openScopeNode.appendChild(textNode)
-        @currentLineTextNodes.push(textNode)
+        textNodes.push(textNode)
 
     if startIndex is 0
       textNode = @domElementPool.buildText(' ')
       lineNode.appendChild(textNode)
-      @currentLineTextNodes.push(textNode)
-
-  appendTokenNodes: (tokenText, isHardTab, firstNonWhitespaceIndex, firstTrailingWhitespaceIndex, hasIndentGuide, hasInvisibleCharacters, scopeNode) ->
-    if isHardTab
-      textNode = @domElementPool.buildText(tokenText)
-      hardTabNode = @domElementPool.buildElement("span", "hard-tab")
-      hardTabNode.classList.add("leading-whitespace") if firstNonWhitespaceIndex?
-      hardTabNode.classList.add("trailing-whitespace") if firstTrailingWhitespaceIndex?
-      hardTabNode.classList.add("indent-guide") if hasIndentGuide
-      hardTabNode.classList.add("invisible-character") if hasInvisibleCharacters
-      hardTabNode.appendChild(textNode)
-
-      scopeNode.appendChild(hardTabNode)
-      @currentLineTextNodes.push(textNode)
-    else
-      startIndex = 0
-      endIndex = tokenText.length
-
-      leadingWhitespaceNode = null
-      leadingWhitespaceTextNode = null
-      trailingWhitespaceNode = null
-      trailingWhitespaceTextNode = null
-
-      if firstNonWhitespaceIndex?
-        leadingWhitespaceTextNode =
-          @domElementPool.buildText(tokenText.substring(0, firstNonWhitespaceIndex))
-        leadingWhitespaceNode = @domElementPool.buildElement("span", "leading-whitespace")
-        leadingWhitespaceNode.classList.add("indent-guide") if hasIndentGuide
-        leadingWhitespaceNode.classList.add("invisible-character") if hasInvisibleCharacters
-        leadingWhitespaceNode.appendChild(leadingWhitespaceTextNode)
-
-        startIndex = firstNonWhitespaceIndex
-
-      if firstTrailingWhitespaceIndex?
-        tokenIsOnlyWhitespace = firstTrailingWhitespaceIndex is 0
-
-        trailingWhitespaceTextNode =
-          @domElementPool.buildText(tokenText.substring(firstTrailingWhitespaceIndex))
-        trailingWhitespaceNode = @domElementPool.buildElement("span", "trailing-whitespace")
-        trailingWhitespaceNode.classList.add("indent-guide") if hasIndentGuide and not firstNonWhitespaceIndex? and tokenIsOnlyWhitespace
-        trailingWhitespaceNode.classList.add("invisible-character") if hasInvisibleCharacters
-        trailingWhitespaceNode.appendChild(trailingWhitespaceTextNode)
-
-        endIndex = firstTrailingWhitespaceIndex
-
-      if leadingWhitespaceNode?
-        scopeNode.appendChild(leadingWhitespaceNode)
-        @currentLineTextNodes.push(leadingWhitespaceTextNode)
-
-      if tokenText.length > MaxTokenLength
-        while startIndex < endIndex
-          textNode = @domElementPool.buildText(
-            @sliceText(tokenText, startIndex, startIndex + MaxTokenLength)
-          )
-          textSpan = @domElementPool.buildElement("span")
-
-          textSpan.appendChild(textNode)
-          scopeNode.appendChild(textSpan)
-          startIndex += MaxTokenLength
-          @currentLineTextNodes.push(textNode)
-      else
-        textNode = @domElementPool.buildText(@sliceText(tokenText, startIndex, endIndex))
-        scopeNode.appendChild(textNode)
-        @currentLineTextNodes.push(textNode)
-
-      if trailingWhitespaceNode?
-        scopeNode.appendChild(trailingWhitespaceNode)
-        @currentLineTextNodes.push(trailingWhitespaceTextNode)
-
-  sliceText: (tokenText, startIndex, endIndex) ->
-    if startIndex? and endIndex? and startIndex > 0 or endIndex < tokenText.length
-      tokenText = tokenText.slice(startIndex, endIndex)
-    tokenText
-
-  appendEndOfLineNodes: (id, lineNode) ->
-    {endOfLineInvisibles} = @newTileState.lines[id]
-
-    hasInvisibles = false
-    if endOfLineInvisibles?
-      for invisible in endOfLineInvisibles
-        hasInvisibles = true
-        invisibleSpan = @domElementPool.buildElement("span", "invisible-character")
-        textNode = @domElementPool.buildText(invisible)
-        invisibleSpan.appendChild(textNode)
-        lineNode.appendChild(invisibleSpan)
-
-        @currentLineTextNodes.push(textNode)
-
-    hasInvisibles
+      textNodes.push(textNode)
+
+    @textNodesByLineId[id] = textNodes
+    lineNode
 
   updateLineNode: (id) ->
     oldLineState = @oldTileState.lines[id]

  screenRowForNode: (node) -> parseInt(node.dataset.screenRow)

  buildLineNode: (id) ->
    {screenRow, decorationClasses} = @newTileState.lines[id]

    lineNode = @domElementPool.buildElement("div", "line")
    lineNode.dataset.screenRow = screenRow

      for decorationClass in decorationClasses
        lineNode.classList.add(decorationClass)

    textNodes = []
    lineLength = 0
    startIndex = 0
    openScopeNode = lineNode
