     override open func setAttributes(_ attrs: [String : Any]?, range: NSRange) {
         beginEditing()
 
-        if mustUpdateDOM() && allowFixingDOMAttributes && range.length > 0, let attributes = attrs {
-            applyStylesToDom(attributes: attributes, in: range)
-        }
-
         textStore.setAttributes(attrs, range: range)
         edited(.editedAttributes, range: range, changeInLength: 0)
         
         endEditing()
-
-        print("Style: \(dom.getHTML())")
-    }
-
-    /// This override exists to prevent text replacement from propagating style-changes to the DOM
-    /// This should not be a problem in our logic because the DOM is smart enough to update its
-    /// style after text modifications.
-    ///
-    /// This was causing issues specifically with lists.  To understand why, just comment this
-    /// method and run the unit tests.
-    ///
-    override open func endEditing() {
-        allowFixingDOMAttributes = false
-        super.endEditing()
-        allowFixingDOMAttributes = true
-    }
-
-    // MARK: - DOM: Replacing Characters
-
-    private func replaceCharactersInDOM(in range: NSRange, with str: String) {
-
-        guard let swiftRange = string.nsRange(fromUTF16NSRange: range) else {
-            fatalError()
-        }
-
-        let targetDomRange = string.map(visualUTF16Range: swiftRange)
-
-        if targetDomRange.length > 0 || str.characters.count > 0 {
-            dom.replaceCharacters(inRange: targetDomRange, withString: str)
-        }
-    }
-
-    private func replaceCharactersInDOM(in range: NSRange, with attrString: NSAttributedString) {
-
-        let targetDomRange = string.map(visualUTF16Range: range)
-
-        guard let swiftRange = string.nsRange(fromUTF16NSRange: range) else {
-            fatalError()
-        }
-
-        let domString = NSAttributedString(with: attrString, replacingOcurrencesOf: String(.paragraphSeparator), with: "")
-
-        if targetDomRange.length > 0 || domString.length > 0 {
-            dom.replaceCharacters(inRange: targetDomRange, withString: domString.string)
-        }
-
-        if attrString.string == String(.paragraphSeparator) {
-            dom.addBlockSeparator(at: targetDomRange.location)
-        }
-
-        if targetDomRange.length != swiftRange.length {
-            dom.deleteBlockSeparator(at: targetDomRange.location)
-        }
-
-        print("Pre: \(dom.getHTML())")
-        if domString.length > 0 {
-            applyStylesToDom(from: domString, startingAt: range.location)
-        }
-        print("Pos: \(dom.getHTML())")
-    }
-
-    // MARK: - DOM: Applying Styles
-
-    /// This method applies the styles in the specified attributes dictionary, to the DOM in the
-    /// specified range.  To do so, it calculates the differences and applies them.
-    ///
-    /// - Parameters:
-    ///     - attributes: the attributes to apply.
-    ///     - range: the range to apply the styles to.
-    ///
-    private func applyStylesToDom(attributes: [String : Any], in range: NSRange) {
-
-        let canMergeLeft = range.location > 0 ? !textStore.string.isStartOfNewLine(atUTF16Offset: range.location) : false
-        let canMergeRight = range.location + range.length < textStore.length - 1 ? !textStore.string.isEndOfLine(atUTF16Offset: range.location + range.length) : false
-
-        textStore.enumerateAttributeDifferences(in: range, against: attributes, do: { (subRange, key, sourceValue, targetValue) in
-
-            let domRange = textStore.string.map(visualUTF16Range: subRange)
-
-            guard domRange.length > 0 else {
-                return
-            }
-
-            processAttributesDifference(in: domRange, key: key, sourceValue: sourceValue, targetValue: targetValue, canMergeLeft: canMergeLeft, canMergeRight: canMergeRight)
-        })
-    }
-
-    /// This method applies the styles from the specified attributed string, to the DOM, starting
-    /// at the specified location, and moving ahead for the length of the attributed string.
-    ///
-    /// This makes sense only if the attributed string has already been added to the DOM, as a way
-    /// to apply the styles for that string.
-    ///
-    /// - Parameters:
-    ///     - attributedString: the attributed string containing the styles we want to apply.
-    ///     - location: the starting location where the styles should be applied in the DOM.
-    ///         It's the offset this method will use to apply the styles found in the source string.
-    ///
-    private func applyStylesToDom(from attributedString: NSAttributedString, startingAt location: Int) {
-        let originalAttributes = [String:Any]()
-        let fullRange = NSRange(location: 0, length: attributedString.length)
-
-        let domLocation = textStore.string.map(visualRange: NSRange(location: location, length: 0)).location
-
-        let canMergeLeft = location > 0 ? !textStore.string.isStartOfNewLine(atUTF16Offset: location) : false
-        let canMergeRight = location < textStore.length - 1 ? !textStore.string.isEndOfLine(atUTF16Offset: location) : false
-
-        attributedString.enumerateAttributeDifferences(in: fullRange, against: originalAttributes, do: { (subRange, key, sourceValue, targetValue) in
-            // The source and target values are inverted since we're enumerating on the new string.
-
-            let domRange = NSRange(location: domLocation + subRange.location, length: subRange.length)
-
-            guard let swiftDomRange = dom.string().nsRange(fromUTF16NSRange: domRange) else {
-                // This should not be possible, but if this ever happens in production it's better to lose
-                // the style than it is to crash the editor.
-                //
-                assertionFailure("Unexpected range conversion problem.")
-                return
-            }
-
-            processAttributesDifference(in: swiftDomRange, key: key, sourceValue: targetValue, targetValue: sourceValue, canMergeLeft: canMergeLeft, canMergeRight: canMergeRight)
-        })
-    }
-
-    // MARK: - DOM: Calculating and Applying Style Differences
-
-    /// Check the difference in styles and applies the necessary changes to the DOM string.
-    ///
-    /// - Parameters:
-    ///   - domRange: the range to check
-    ///   - key: the attribute style key
-    ///   - sourceValue: the original value of the attribute
-    ///   - targetValue: the new value of the attribute
-    ///
-    private func processAttributesDifference(
-        in domRange: NSRange,
-        key: String,
-        sourceValue: Any?,
-        targetValue: Any?,
-        canMergeLeft: Bool = true,
-        canMergeRight: Bool = true) {
-
-        let isCommentAttachment = sourceValue is CommentAttachment || targetValue is CommentAttachment
-        let isHtmlAttachment = sourceValue is HTMLAttachment || targetValue is HTMLAttachment
-        let isLineAttachment = sourceValue is LineAttachment || targetValue is LineAttachment
-        let isImageAttachment = sourceValue is ImageAttachment || targetValue is ImageAttachment
-        let isVideoAttachment = sourceValue is VideoAttachment || targetValue is VideoAttachment
-
-        switch(key) {
-        case NSFontAttributeName:
-            let sourceFont = sourceValue as? UIFont
-            let targetFont = targetValue as? UIFont
-
-            processFontDifferences(in: domRange, betweenOriginal: sourceFont, andNew: targetFont)
-        case NSStrikethroughStyleAttributeName:
-            let sourceStyle = sourceValue as? NSNumber
-            let targetStyle = targetValue as? NSNumber
-
-            processStrikethroughDifferences(in: domRange, betweenOriginal: sourceStyle, andNew: targetStyle)
-        case NSUnderlineStyleAttributeName:
-            let sourceStyle = sourceValue as? NSNumber
-            let targetStyle = targetValue as? NSNumber
-
-            processUnderlineDifferences(in: domRange, betweenOriginal: sourceStyle, andNew: targetStyle)
-        case NSAttachmentAttributeName where isLineAttachment:
-            let sourceAttachment = sourceValue as? LineAttachment
-            let targetAttachment = targetValue as? LineAttachment
-
-            processLineAttachmentDifferences(in: domRange, betweenOriginal: sourceAttachment, andNew: targetAttachment)
-        case NSAttachmentAttributeName where isCommentAttachment:
-            let sourceAttachment = sourceValue as? CommentAttachment
-            let targetAttachment = targetValue as? CommentAttachment
-
-            processCommentAttachmentDifferences(in: domRange, betweenOriginal: sourceAttachment, andNew: targetAttachment)
-        case NSAttachmentAttributeName where isHtmlAttachment:
-            let sourceAttachment = sourceValue as? HTMLAttachment
-            let targetAttachment = targetValue as? HTMLAttachment
-
-            processHtmlAttachmentDifferences(in: domRange, betweenOriginal: sourceAttachment, andNew: targetAttachment)
-        case NSAttachmentAttributeName where isImageAttachment:
-            let sourceAttachment = sourceValue as? ImageAttachment
-            let targetAttachment = targetValue as? ImageAttachment
-
-            processImageAttachmentDifferences(in: domRange, betweenOriginal: sourceAttachment, andNew: targetAttachment)
-        case NSAttachmentAttributeName where isVideoAttachment:
-            let sourceAttachment = sourceValue as? VideoAttachment
-            let targetAttachment = targetValue as? VideoAttachment
-
-            processVideoAttachmentDifferences(in: domRange, betweenOriginal: sourceAttachment, andNew: targetAttachment)
-        case NSParagraphStyleAttributeName:
-            let sourceStyle = sourceValue as? ParagraphStyle
-            let targetStyle = targetValue as? ParagraphStyle
-
-            processBlockquoteDifferences(in: domRange, betweenOriginal: sourceStyle?.blockquote, andNew: targetStyle?.blockquote)
-            processListDifferences(in: domRange, betweenOriginal: sourceStyle?.textLists.last, andNew: targetStyle?.textLists.last, canMergeLeft: canMergeLeft, canMergeRight: canMergeRight)
-            processHeaderDifferences(in: domRange, betweenOriginal: sourceStyle?.headerLevel, andNew: targetStyle?.headerLevel)
-            processHTMLParagraphDifferences(in: domRange, betweenOriginal: sourceStyle?.htmlParagraph, andNew: targetStyle?.htmlParagraph)
-        case NSLinkAttributeName:
-            let sourceStyle = sourceValue as? URL
-            let targetStyle = targetValue as? URL
-            processLinkDifferences(in: domRange, betweenOriginal: sourceStyle, andNew: targetStyle)
-        default:
-            break
-        }
-    }
-
-    /// Processes differences in a font object, and applies them to the DOM in the specified range.
-    ///
-    /// - Parameters:
-    ///     - range: the range in the DOM where the differences must be applied.
-    ///     - originalFont: the original font object.
-    ///     - newFont: the new font object.
-    ///
-    private func processFontDifferences(in range: NSRange, betweenOriginal originalFont: UIFont?, andNew newFont: UIFont?) {
-        processBoldDifferences(in: range, betweenOriginal: originalFont, andNew: newFont)
-        processItalicDifferences(in: range, betweenOriginal: originalFont, andNew: newFont)
-    }
-
-    /// Processes differences in the bold trait of two font objects, and applies them to the DOM in
-    /// the specified range.
-    ///
-    /// - Parameters:
-    ///     - range: the range in the DOM where the differences must be applied.
-    ///     - originalFont: the original font object.
-    ///     - newFont: the new font object.
-    ///
-    private func processBoldDifferences(in range: NSRange, betweenOriginal originalFont: UIFont?, andNew newFont: UIFont?) {
-        let oldIsBold = originalFont?.containsTraits(.traitBold) ?? false
-        let newIsBold = newFont?.containsTraits(.traitBold) ?? false
-
-        let addBold = !oldIsBold && newIsBold
-        let removeBold = oldIsBold && !newIsBold
-
-        if addBold {
-            dom.applyBold(spanning: range)
-        } else if removeBold {
-            dom.removeBold(spanning: range)
-        }
-    }
-
-    /// Process difference in attachmente properties, and applies them to the DOM in the specified range
-    ///
-    /// - Parameters:
-    ///   - range: the range in the DOM where the differences must be applied.
-    ///   - original: the original attachment existing in the range if any.
-    ///   - new: the new attachment to apply to the range if any.
-    ///
-    private func processImageAttachmentDifferences(in range: NSRange, betweenOriginal original: ImageAttachment?, andNew new: ImageAttachment?) {
-
-        let originalUrl = original?.url
-        let newUrl = new?.url
-
-        let addImageUrl = originalUrl == nil && newUrl != nil
-        let removeImageUrl = originalUrl != nil && newUrl == nil
-
-        if addImageUrl {
-            guard let urlToAdd = newUrl else {
-                assertionFailure("This should not be possible.  Review your logic.")
-                return
-            }
-
-            dom.replace(range, with: urlToAdd)
-        } else if removeImageUrl {
-            dom.removeImage(spanning: range)
-        }
-    }
-
-    /// Process difference in attachmente properties, and applies them to the DOM in the specified range
-    ///
-    /// - Parameters:
-    ///   - range: the range in the DOM where the differences must be applied.
-    ///   - original: the original attachment existing in the range if any.
-    ///   - new: the new attachment to apply to the range if any.
-    ///
-    private func processVideoAttachmentDifferences(in range: NSRange, betweenOriginal original: VideoAttachment?, andNew new: VideoAttachment?) {
-
-        let originalUrl = original?.srcURL
-        let newUrl = new?.srcURL
-
-        let addVideoUrl = originalUrl == nil && newUrl != nil
-        let removeVideoUrl = originalUrl != nil && newUrl == nil
-
-        if addVideoUrl {
-            guard let urlToAdd = newUrl else {
-                assertionFailure("This should not be possible.  Review your logic.")
-                return
-            }
-
-            dom.replace(range, withVideoURL: urlToAdd, posterURL: new?.posterURL)
-        } else if removeVideoUrl {
-            dom.removeVideo(spanning: range)
-        }
-    }
-
-    private func processLineAttachmentDifferences(in range: NSRange, betweenOriginal original: LineAttachment?, andNew new: LineAttachment?) {
-
-        dom.replaceWithHorizontalRuler(range)
-    }
-
-    private func processCommentAttachmentDifferences(in range: NSRange, betweenOriginal original: CommentAttachment?, andNew new: CommentAttachment?) {
-        guard let newAttachment = new else {
-            return
-        }
-
-        dom.replace(range, withComment: newAttachment.text)
-    }
-
-    private func processHtmlAttachmentDifferences(in range: NSRange, betweenOriginal original: HTMLAttachment?, andNew new: HTMLAttachment?) {
-        guard let html = new?.rawHTML, original?.rawHTML != new?.rawHTML else {
-            return
-        }
-
-        dom.replace(range, withRawHTML: html)
-    }
-
-    /// Processes differences in blockquote styles, and applies them to the DOM in the specified
-    /// range.
-    ///
-    /// - Parameters:
-    ///     - range: the range in the DOM where the differences must be applied.
-    ///     - originalStyle: the original Blockquote object if any.
-    ///     - newStyle: the new Blockquote object.
-    ///
-    private func processHTMLParagraphDifferences(in range: NSRange, betweenOriginal originalStyle: HTMLParagraph?, andNew newStyle: HTMLParagraph?) {
-
-        let addStyle = originalStyle == nil && newStyle != nil
-        let removeStyle = originalStyle != nil && newStyle == nil
-
-        if addStyle {
-            dom.applyHTMLParagraph(spanning: range)
-        } else if removeStyle {
-            dom.removeHTMLParagraph(spanning: range)
-        }
-    }
-
-
-    /// Processes differences in the italic trait of two font objects, and applies them to the DOM
-    /// in the specified range.
-    ///
-    /// - Parameters:
-    ///     - range: the range in the DOM where the differences must be applied.
-    ///     - originalFont: the original font object.
-    ///     - newFont: the new font object.
-    ///
-    private func processItalicDifferences(in range: NSRange, betweenOriginal originalFont: UIFont?, andNew newFont: UIFont?) {
-        let oldIsItalic = originalFont?.containsTraits(.traitItalic) ?? false
-        let newIsItalic = newFont?.containsTraits(.traitItalic) ?? false
-
-        let addItalic = !oldIsItalic && newIsItalic
-        let removeItalic = oldIsItalic && !newIsItalic
-
-        if addItalic {
-            dom.applyItalic(spanning: range)
-        } else if removeItalic {
-            dom.removeItalic(spanning: range)
-        }
-    }
-
-    /// Processes differences in two strikethrough styles, and applies them to the DOM in the
-    /// specified range.
-    ///
-    /// - Parameters:
-    ///     - range: the range in the DOM where the differences must be applied.
-    ///     - originalFont: the original font object.
-    ///     - newFont: the new font object.
-    ///
-    private func processStrikethroughDifferences(in range: NSRange, betweenOriginal originalStyle: NSNumber?, andNew newStyle: NSNumber?) {
-
-        let sourceStyle = originalStyle ?? 0
-        let targetStyle = newStyle ?? 0
-
-        // At some point we'll support different styles.  For now we only check if ANY style is
-        // set.
-        //
-        let addStyle = sourceStyle == 0 && targetStyle == 1
-        let removeStyle = sourceStyle == 1 && targetStyle == 0
-
-        if addStyle {
-            dom.applyStrikethrough(spanning: range)
-        } else if removeStyle {
-            dom.removeStrikethrough(spanning: range)
-        }
-    }
-
-    /// Processes differences in two underline styles, and applies them to the DOM in the specified
-    /// range.
-    ///
-    /// - Parameters:
-    ///     - range: the range in the DOM where the differences must be applied.
-    ///     - originalFont: the original font object.
-    ///     - newFont: the new font object.
-    ///
-    private func processUnderlineDifferences(in range: NSRange, betweenOriginal originalStyle: NSNumber?, andNew newStyle: NSNumber?) {
-
-        let sourceStyle = originalStyle ?? 0
-        let targetStyle = newStyle ?? 0
-
-        // At some point we'll support different styles.  For now we only check if ANY style is
-        // set.
-        //
-        let addStyle = sourceStyle == 0 && targetStyle == 1
-        let removeStyle = sourceStyle == 1 && targetStyle == 0
-
-        if addStyle {
-            dom.applyUnderline(spanning: range)
-        } else if removeStyle {
-            dom.removeUnderline(spanning: range)
-        }
-    }
-
-    /// Processes differences in blockquote styles, and applies them to the DOM in the specified
-    /// range.
-    ///
-    /// - Parameters:
-    ///     - range: the range in the DOM where the differences must be applied.
-    ///     - originalStyle: the original Blockquote object if any.
-    ///     - newStyle: the new Blockquote object.
-    ///
-    private func processBlockquoteDifferences(in range: NSRange, betweenOriginal originalStyle: Blockquote?, andNew newStyle: Blockquote?) {
-
-        let addStyle = originalStyle == nil && newStyle != nil
-        let removeStyle = originalStyle != nil && newStyle == nil
-
-        if addStyle {
-            dom.applyBlockquote(spanning: range)
-        } else if removeStyle {
-            dom.removeBlockquote(spanning: range)
-        }
-    }
-
-    /// Processes differences in list styles, and applies them to the DOM in the specified
-    /// range.
-    ///
-    /// - Parameters:
-    ///     - range: the range in the DOM where the differences must be applied.
-    ///     - originalStyle: the original TextList object if any.
-    ///     - newStyle: the new Blockquote object.
-    ///
-    private func processListDifferences(in range: NSRange, betweenOriginal originalStyle: TextList?, andNew newStyle: TextList?, canMergeLeft: Bool = false, canMergeRight: Bool = false) {
-
-        let original = originalStyle?.style
-        let new = newStyle?.style
-
-        guard original != new else {
-            return
-        }
-
-        let removeOrdered = original == .ordered
-        let removeUnordered = original == .unordered
-        let addOrdered = new == .ordered
-        let addUnordered = new == .unordered
-
-        var rangeForAddingStyle = range
-
-        if removeOrdered {
-            rangeForAddingStyle = dom.removeOrderedList(spanning: range)
-        } else if removeUnordered {
-            rangeForAddingStyle = dom.removeUnorderedList(spanning: range)
-        }
-
-        if addOrdered {
-            dom.applyOrderedList(spanning: rangeForAddingStyle, canMergeLeft: canMergeLeft, canMergeRight: canMergeRight)
-        } else if addUnordered {
-            dom.applyUnorderedList(spanning: rangeForAddingStyle, canMergeLeft: canMergeLeft, canMergeRight: canMergeRight)
-        }
-    }
-
-    /// Processes differences in header styles, and applies them to the DOM in the specified
-    /// range.
-    ///
-    /// - Parameters:
-    ///     - range: the range in the DOM where the differences must be applied.
-    ///     - originalHeaderLevel: the original font object.
-    ///     - newHeaderLevel: the new font object.
-    ///
-    private func processHeaderDifferences(in range: NSRange, betweenOriginal originalHeaderLevel: Int?, andNew newHeaderLevel: Int?) {
-
-        let sourceHeader = originalHeaderLevel ?? 0
-        let targetHeader = newHeaderLevel ?? 0
-
-        let addStyle = sourceHeader >= 0 && targetHeader > 0 && sourceHeader != targetHeader
-        let removeStyle = sourceHeader > 0 && targetHeader >= 0 && sourceHeader != targetHeader
-
-        if addStyle {
-            dom.applyHeader(targetHeader, spanning: range)
-        }
-        if removeStyle {
-            dom.removeHeader(sourceHeader, spanning: range)
-        }
-    }
-
-    /// Processes differences in link styles, and applies them to the DOM in the specified
-    /// range.
-    ///
-    /// - Parameters:
-    ///     - range: the range in the DOM where the differences must be applied.
-    ///     - originalURL: the original link URL object if any.
-    ///     - newURL: the new link URL object if any.
-    ///
-    private func processLinkDifferences(in range: NSRange, betweenOriginal originalURL: URL?, andNew newURL: URL?) {
-
-        let addStyle = originalURL == nil && newURL != nil
-        let removeStyle = originalURL != nil && newURL == nil
-
-        if addStyle {            
-            dom.applyLink(newURL, spanning: range)
-        } else if removeStyle {
-            dom.removeLink(spanning: range)
-        }
-    }
-    
+    }
+
     // MARK: - Styles: Toggling
 
     @discardableResult


        beginEditing()

        if mustUpdateDOM() {
            replaceCharactersInDOM(in: range, with: str)
        }

        detectAttachmentRemoved(in: range)
        textStore.replaceCharacters(in: range, with: str)


        let preprocessedString = preprocessAttributesForInsertion(attrString)

        beginEditing()

        detectAttachmentRemoved(in: range)
        textStore.replaceCharacters(in: range, with: preprocessedString)
