     if @getSelectedRange()
       @deleteBackward()
     else
-      position = @getLocation()
-      stringBeforePosition = @text.getStringAtRange([0, position])
+      location = @getLocation()
+      text = @getTextAtIndex(location.index)
+      # TODO: delete across blocks
+      stringBeforePosition = text.getStringAtRange([0, location.position])
+      # TODO: \b is not unicode compatible
       positionBeforeLastWord = stringBeforePosition.search(/(\b\w+)\W*$/)
       @deleteFromCurrentPosition(positionBeforeLastWord - position)
 
   moveTextFromRange: (range) ->
-    position = @getLocation()
-    @text.moveTextFromRangeToPosition(range, position)
+    location = @getLocation()
+    # TODO: move selection spanning blocks
+    text = @getTextAtIndex(index)
+    text.moveTextFromRangeToPosition(range, position)
     @requestPosition(position)
 
   getTextFromSelection: ->
-    selectedRange = @getSelectedRange() ? [0, 0]
-    @text.getTextAtRange(selectedRange)
+    # TODO: get text(s) spanning blocks
+    if locationRange = @getSelectedRange()
+      if locationRange[0].index is locationRange[1].index
+        text = @getTextAtIndex(locationRange[0].index)
+        text.getTextAtRange([locationRange[0].position, locationRange[1].position])
 
   # Attachment owner protocol
 


  # Private

  getText: ->
    @text.copy()

  getInternalSelectedRange: ->
    @selectionDelegate?.getSelectedRangeOfComposition?(this)

  # Snapshots

  createSnapshot: ->
    text: @getDocument()
    selectedRange: @getInternalSelectedRange()

  restoreSnapshot: ({document, selectedRange}) ->
    # TODO
    @document.replaceDocument(document)
    @requestSelectedRange(selectedRange)

  # Document delegate
