     v = @cm.getSelection() || @cword(); if v && '\n' !in v then @cmSC.setValue v; @cmRP.setValue v
     @cmRP.focus(); @cmRP.execCommand 'selectAll'; @highlightSearch(); return
   EP: ->
-    v = @cm.getValue()
-    if v != @otext || @bp.join() != @obp
-      for l in @bp then @cm.setGutterMarker l, 'breakpoints', null
-      @emit 'SaveChanges', win: @id, text: @cm.getValue(), attributes: stop: @bp[..].sort (x, y) -> x - y
+    v = @cm.getValue(); bp = @getBreakpoints()
+    if v != @otext || '' + bp != '' + @obp
+      for l in bp then @cm.setGutterMarker l, 'breakpoints', null
+      @emit 'SaveChanges', win: @id, text: @cm.getValue(), attributes: stop: bp
     else
       @emit 'CloseWindow', win: @id
     return

    @$e = $(e).html EDITOR_HTML
    {@id, @name, @emit} = @opts = opts; @isTracer = opts.tracer
    @xline = null # the line number of the empty line inserted when cursor is at eof and you press <down>
    @bp = [] # breakpoints, an array of line numbers
    @otext = @obp = '' # remember original text and bp to avoid pointless saving on EP; obp is comma-separated line numbers
    @hll = null # highlighted line -- currently executed line in tracer
    @lastQuery = @lastIC = @overlay = @annotation = null # search-related state
    @focusTimestamp = 0

    @cm.setOption 'readOnly', ee.readOnly || ee.debugger
    line = ee.currentRow; col = ee.currentColumn || 0; if line == col == 0 && ee.text.indexOf('\n') < 0 then col = ee.text.length
    @cm.setCursor line, col; @cm.scrollIntoView null, @$e.height() / 2
    @obp = ee.lineAttributes.stop[..].sort (x, y) -> x - y
    for l in @obp then @cm.setGutterMarker l, 'breakpoints', @createBreakpointElement()
    if D.floating then $('title', @$e[0].ownerDocument).text ee.name
    return
  hasFocus: -> window.focused && @cm.hasFocus()
