     @addAttributeAtPositionRange(attributeName, value, positionRange)
 
   firstBlockInPositionRangeIsEntirelySelected: (positionRange) ->
-    locationRange = @locationRangeFromPositionRange(positionRange)
-    if locationRange.start.offset is 0 and locationRange.start.index < locationRange.end.index
+    positionRange = Trix.PositionRange.box(positionRange)
+    leftLocation = @locationFromPosition(positionRange.start)
+    rightLocation = @locationFromPosition(positionRange.end)
+
+    if leftLocation.offset is 0 and leftLocation.index < rightLocation.index
       true
-    else if locationRange.start.index is locationRange.end.index
-      length = @getBlockAtIndex(locationRange.start.index).getLength()
-      locationRange.start.offset is 0 and locationRange.end.offset is length
+    else if leftLocation.index is rightLocation.index
+      length = @getBlockAtIndex(leftLocation.index).getLength()
+      leftLocation.offset is 0 and rightLocation.offset is length
     else
       false
 
   expandPositionRangeToLineBreaksAndSplitBlocks: (positionRange) ->
-    locationRange = @locationRangeFromPositionRange(positionRange)
-    start = index: locationRange.start.index, offset: locationRange.start.offset
-    end = index: locationRange.end.index, offset: locationRange.end.offset
+    positionRange = Trix.PositionRange.box(positionRange)
+    startLocation = @locationFromPosition(positionRange.start)
+    endLocation = @locationFromPosition(positionRange.end)
 
     @edit =>
-      startBlock = @getBlockAtIndex(start.index)
-      if (start.offset = startBlock.findLineBreakInDirectionFromPosition("backward", start.offset))?
-        position = @positionFromLocation(start)
+      startBlock = @getBlockAtIndex(startLocation.index)
+      if (startLocation.offset = startBlock.findLineBreakInDirectionFromPosition("backward", startLocation.offset))?
+        position = @positionFromLocation(startLocation)
         @insertBlockBreakAtPositionRange([position, position + 1])
-        end.index += 1
-        end.offset -= @getBlockAtIndex(start.index).getLength()
-        start.index += 1
-      start.offset = 0
-
-      if end.offset is 0 and end.index > start.index
-        end.index -= 1
-        end.offset = @getBlockAtIndex(end.index).getBlockBreakPosition()
+        endLocation.index += 1
+        endLocation.offset -= @getBlockAtIndex(startLocation.index).getLength()
+        startLocation.index += 1
+      startLocation.offset = 0
+
+      if endLocation.offset is 0 and endLocation.index > startLocation.index
+        endLocation.index -= 1
+        endLocation.offset = @getBlockAtIndex(endLocation.index).getBlockBreakPosition()
       else
-        endBlock = @getBlockAtIndex(end.index)
-        if endBlock.text.getStringAtRange([end.offset - 1, end.offset]) is "\n"
-          end.offset -= 1
+        endBlock = @getBlockAtIndex(endLocation.index)
+        if endBlock.text.getStringAtRange([endLocation.offset - 1, endLocation.offset]) is "\n"
+          endLocation.offset -= 1
         else
-          end.offset = endBlock.findLineBreakInDirectionFromPosition("forward", end.offset)
-        unless end.offset is endBlock.getBlockBreakPosition()
-          position = @positionFromLocation(end)
+          endLocation.offset = endBlock.findLineBreakInDirectionFromPosition("forward", endLocation.offset)
+        unless endLocation.offset is endBlock.getBlockBreakPosition()
+          position = @positionFromLocation(endLocation)
           @insertBlockBreakAtPositionRange([position, position + 1])
 
-    @positionRangeFromLocationRange(new Trix.LocationRange start, end)
+    startPosition = @positionFromLocation(startLocation)
+    endPosition = @positionFromLocation(endLocation)
+    new Trix.PositionRange startPosition, endPosition
 
   convertLineBreaksToBlockBreaksInPositionRange: (positionRange) ->
     positionRange = Trix.PositionRange.box(positionRange)


  insertTextAtPositionRange: edit "insertTextAtPositionRange", (text, positionRange) ->
    positionRange = Trix.PositionRange.box(positionRange)
    locationRange = @locationRangeFromPositionRange(positionRange)

    @removeTextAtPositionRange(positionRange)
    @blockList = @blockList.editObjectAtIndex locationRange.index, (block) ->
      block.copyWithText(block.text.insertTextAtPosition(text, locationRange.offset))

  removeTextAtPositionRange: edit "removeTextAtPositionRange", (positionRange) ->
    locationRange = @locationRangeFromPositionRange(positionRange)
    return if locationRange.isCollapsed()

    leftIndex = locationRange.start.index
    leftBlock = @getBlockAtIndex(leftIndex)
    leftText = leftBlock.text.getTextAtRange([0, locationRange.start.offset])

    rightIndex = locationRange.end.index
    rightBlock = @getBlockAtIndex(rightIndex)
    rightText = rightBlock.text.getTextAtRange([locationRange.end.offset, rightBlock.getLength()])

    text = leftText.appendText(rightText)
    block = leftBlock.copyWithText(text)

  getPositionRangeOfCommonAttributeAtPosition: (attributeName, position) ->
    {index, offset} = @locationFromPosition(position)
    text = @getTextAtIndex(index)
    [startOffset, endOffset] = text.getExpandedRangeForAttributeAtOffset(attributeName, offset)

    start = @positionFromLocation {index, offset: startOffset}
    end = @positionFromLocation {index, offset: endOffset}
    new Trix.PositionRange start, end

  attributesForBlock = (block) ->
    attributes = {}
