truncateWith (other) {
    if (other.isNull()) return this
    if (other.isInsideOf(this, 'strict')) {
      // the other selection should overlap only on one side
      throw new Error('Can not truncate with a contained selections')
    }
    if (!this.overlaps(other)) {
      return this
    }
    let otherStartOffset, otherEndOffset
    if (other.isPropertySelection()) {
      otherStartOffset = other.start.offset
      otherEndOffset = other.end.offset
    } else if (other.isContainerSelection()) {
      // either the startPath or the endPath must be the same
      if (isArrayEqual(other.start.path, this.start.path)) {
        otherStartOffset = other.start.offset
      } else {
        otherStartOffset = this.start.offset
      }
      if (isArrayEqual(other.end.path, this.start.path)) {
        otherEndOffset = other.end.offset
      } else {
        otherEndOffset = this.end.offset
      }
    } else {
      return this
    }

    let newStartOffset
    let newEndOffset
    if (this.start.offset > otherStartOffset && this.end.offset > otherEndOffset) {
      newStartOffset = otherEndOffset
      newEndOffset = this.end.offset
    } else if (this.start.offset < otherStartOffset && this.end.offset < otherEndOffset) {
      newStartOffset = this.start.offset
      newEndOffset = otherStartOffset
    } else if (this.start.offset === otherStartOffset) {
      if (this.end.offset <= otherEndOffset) {
        return Selection.nullSelection
      } else {
        newStartOffset = otherEndOffset
        newEndOffset = this.end.offset
      }
    } else if (this.end.offset === otherEndOffset) {
      if (this.start.offset >= otherStartOffset) {
        return Selection.nullSelection
      } else {
        newStartOffset = this.start.offset
        newEndOffset = otherStartOffset
      }
    } else if (other.contains(this)) {
      return Selection.nullSelection
    } else {
      // FIXME: if this happens, we have a bug somewhere above
      throw new Error('Illegal state.')
    }
    return this.createWithNewRange(newStartOffset, newEndOffset)
  }
Creates a new selection by truncating this one by another selection.

@param {Selection} other
@returns {Selection} a new selection