           oldMarkers = @markers.splice(spliceIndex, markerIndex - spliceIndex + 1, newMarkers...)
           oldMarker.destroy() for oldMarker in oldMarkers
           markerIndex += newMarkers.length - oldMarkers.length
-          lastValidMarkerIndex = markerIndex
+          markerIndexBeforeChange = markerIndex
           change = null
+
+      else if change? and markerRange.end.isGreaterThanOrEqual(changeStart)
+        withinChange = true
+      else if marker.isValid()
+        markerIndexBeforeChange = markerIndex
+
+      # A marker that is invalid but is outside of any change can simply be
+      # recreated. It must have been temporarily changed but then restored.
       else
-        if change? and markerRange.end.isGreaterThanOrEqual(change.position)
-          withinChange = true
-        else
-          if marker.isValid()
-            lastValidMarkerIndex = markerIndex
-          else
-            @markers[markerIndex] = @recreateMarker(marker)
+        @markers[markerIndex] = @recreateMarker(marker)
 
       markerIndex++
 

          scanEnd = Point.INFINITY

        if not withinChange
          if lastValidMarkerIndex >= 0
            scanStart = @markers[lastValidMarkerIndex].getBufferRange().start
            spliceIndex = lastValidMarkerIndex
          else
            scanStart = Point.ZERO
            spliceIndex = 0


    changes = @patch.changes()
    change = null
    withinChange = false
    scanEnd = Point.ZERO
    markerIndex = 0
    markerIndexBeforeChange = -1

    while (marker = @markers[markerIndex])? or change?
      markerRange = marker?.getBufferRange()

      # If we have already re-scanned the region affected by this change, find
      # the next change that extends beyond what we've scanned.
      until change? or (next = changes.next()).done
        change = next.value
        changeStart = change.position
        changeEnd = changeStart.traverse(change.newExtent)
        break if changeEnd.isGreaterThanOrEqual(scanEnd)
        change = null

      # If this marker is untouched and follows the change, or there are no more
      # markers, then it is time to re-scan.
      if withinChange
        if marker?
          if marker.isValid() and markerRange.start.isGreaterThan(changeEnd)
