     }
 
 
-    /// Adds or removes a bold style from the specified range.
+    /// Adds or removes a blockquote style from the specified range.
+    /// Blockquotes are applied to an entire paragrah regardless of the range.
+    /// If the range spans multiple paragraphs, the style is applied to all
+    /// affected paragraphs.
     ///
     /// - Paramters:
     ///     - range: The NSRange to edit.
     ///
     public func toggleBlockquote(range range: NSRange) {
-        print("quote")
+        let storage = textView.textStorage
+
+        // Check if the start of the selection is already in a blockquote.
+        let addingStyle = !formattingAtIndexContainsBlockquote(range.location)
+
+        // Get the affected paragraphs
+        var paragraphRanges = rangesOfParagraphsEnclosingRange(range)
+        guard let firstRange = paragraphRanges.first else {
+            return
+        }
+
+        // Compose the range for the blockquote.
+        var length = 0
+        for range in paragraphRanges {
+            length += range.length
+        }
+        let blockquoteRange = NSRange(location: firstRange.location, length: length)
+
+        // TODO: Assign or remove the blockquote custom attribute.
+
+
+        // Add or remove indentation as needed.
+        // First get the list of pristine ranges to edit. We do this so
+        // a modification doesn't impact the next returned range as paragraph
+        // styles can be apparently merged to a single range in some cases.
+        var rangesToStyle = [NSRange]()
+        storage.enumerateAttribute(NSParagraphStyleAttributeName,
+                                   inRange: blockquoteRange,
+                                   options: [],
+                                   usingBlock: { (value, range, stop) in
+                                    rangesToStyle.append(range)
+        })
+        // Now loop over our pristine ranges knowing that any edits won't impact
+        // subsquent ranges.
+        for range in rangesToStyle {
+            let value = storage.attribute(NSParagraphStyleAttributeName, atIndex: range.location, effectiveRange: nil)
+            let style = value as? NSParagraphStyle ?? defaultParagraphStyle()
+
+            var tab: CGFloat = 0
+            if addingStyle {
+                // TODO: probably need to define an upper limit that we'll support.
+                tab = style.headIndent + AztecVisualEditor.standardIndentation
+            } else {
+                tab = max(0, style.headIndent - AztecVisualEditor.standardIndentation)
+            }
+
+            let newStyle = NSMutableParagraphStyle()
+            newStyle.setParagraphStyle(style)
+            newStyle.headIndent = tab
+            newStyle.firstLineHeadIndent = tab
+
+            storage.addAttribute(NSParagraphStyleAttributeName, value: newStyle, range: range)
+        }
     }
 
 

        }
        return false
    }

}


///
public class AztecVisualEditor : NSObject
{
    static let standardIndentation = CGFloat(20)

    let textView: UITextView
    var attachmentManager: AztecAttachmentManager!
