       followSet.push(elemB) if JetDelta.isInsert(elemB) # insert elemB
       if JetDelta.isInsert(elemB) then indexB += elemB.length else indexB += elemB.end - elemB.start
       elemIndexB++
- 
+
     followEndLength = 0
     for elem in followSet
       if JetDelta.isInsert(elem)
         followEndLength += elem.length
       else
         followEndLength += elem.end - elem.start
- 
+
     follow = new JetDelta(followStartLength, followEndLength, followSet, true)
     follow.compact()
     console.assert(JetDelta.isDelta(follow), "Follows returning invalid JetDelta", follow)

  composeAttributes: (attributes) ->
    return if !attributes?
    for key, value of attributes
      @attributes[key] = if value? then value else undefined

  toString: ->
    attr_str = ""

  toString: ->
    return "{(#{@startLength}->#{@endLength})[#{@deltas.join(', ')}]}"

JetSync =
  # Inserts in deltaB are given priority. Retains in deltaB are indexes into A,
  # and we take whatever is there (insert or retain).
  compose: (deltaA, deltaB) ->
    console.assert(JetDelta.isDelta(deltaA), "Compose called when deltaA is not a JetDelta, type: " + typeof deltaA)
    console.assert(JetDelta.isDelta(deltaB), "Compose called when deltaB is not a JetDelta, type: " + typeof deltaB)
    console.assert(deltaA.endLength == deltaB.startLength, "startLength #{deltaB.startLength} / endlength #{deltaA.endLength} mismatch")

    deltaA = JetDelta.copy(deltaA)
    deltaB = JetDelta.copy(deltaB)
    deltaA.normalizeChanges()
