     }
     
     // MARK: Attributes
-    
-    private func synchronizeTextStack() {
+
+    private func processLinks() {
+        var ranges = [LinkRange]()
         textStorage.setAttributedString(attributedText)
-        textContainer.size = CGSize(width: CGRectGetWidth(bounds), height: CGFloat.max)
-    }
-    
-    private func cacheLinkRanges() {
-        synchronizeTextStack()
-        
-        var ranges = [LinkRange]()
         textStorage.enumerateAttribute(NSLinkAttributeName, inRange: NSRange(location: 0, length: textStorage.length), options: nil) { (value, range, _) in
             // Because NSLinkAttributeName supports both NSURL and NSString
             // values. *sigh*

                    return URL
                }
                return nil
                }()
            if let URL = URL {
                self.layoutManager.ensureLayoutForCharacterRange(range)
                let glyphRange = self.layoutManager.glyphRangeForCharacterRange(range, actualCharacterRange: nil)
                ranges.append(LinkRange(URL: URL, glyphRange: glyphRange))
            }
        }
        linkRanges = ranges
    }
    
    // MARK: Drawing

    
    private func linkRangeAtPoint(point: CGPoint) -> LinkRange? {
        if let linkRanges = linkRanges {
            textContainer.size = CGSize(width: CGRectGetWidth(bounds), height: CGFloat.max)
            layoutManager.ensureLayoutForTextContainer(textContainer)
            
            let glyphIndex = layoutManager.glyphIndexForPoint(point, inTextContainer: textContainer)
