     }
 }
 
-private struct TextViewCharacterFinder: CharacterFinder {
-    typealias ViewType = UITextView
-
+extension UITextView: CharacterFinder {
     /**
      Finds the character at a given location in a tapped view.
 
-     :param: view        The view that was tapped. Must be an instance of UITextView.
-     :param: tapLocation The location of the tap. Usually derived from a gesture recognizer.
-
-     :returns: The index of the tapped character.
+     - parameter tapLocation: The location of the tap. Usually derived from a gesture recognizer.
+
+     - returns: The index of the tapped character.
      */
-    static func indexOfTappedCharacter(inView view: ViewType, tapLocation: CGPoint) -> Int {
-
+    public func indexOfTappedCharacter(tapLocation: CGPoint) -> Int {
         // Location of the tap
 
         var location = tapLocation
-        let layoutManager = view.layoutManager
-        location.x -= view.textContainerInset.left
-        location.y -= view.textContainerInset.top
+        location.x -= textContainerInset.left
+        location.y -= textContainerInset.top
 
         // Find the tapped character
 
-        return layoutManager.characterIndexForPoint(location, inTextContainer: view.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
-    }
-}
-
-private struct TextFieldCharacterFinder: CharacterFinder {
-    typealias ViewType = UITextField
-
+        return layoutManager.characterIndexForPoint(location, inTextContainer: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
+    }
+}
+
+extension UITextField: CharacterFinder {
     /**
      Finds the character at a given location in a tapped view.
 
-     :param: view        The view that was tapped. Must be an instance of UITextField.
-     :param: tapLocation The location of the tap. Usually derived from a gesture recognizer.
-
-     :returns: The index of the tapped character.
+     - parameter tapLocation: The location of the tap. Usually derived from a gesture recognizer.
+
+     - returns: The index of the tapped character.
      */
-    static func indexOfTappedCharacter(inView view: ViewType, tapLocation: CGPoint) -> Int {
-
+    public func indexOfTappedCharacter(tapLocation: CGPoint) -> Int {
         // UITextField doesn't come with NSTextStorage, NSTextContainer, or NSLayoutManager, so
         // we have to create these manually.
 
         var charIndex = -1
 
-        if let attributedText = view.attributedText {
+        if let attributedText = m_attributedText {
             let textStorage = NSTextStorage(attributedString: attributedText)
             let layoutManager = NSLayoutManager()
             textStorage.addLayoutManager(layoutManager)
 
-            let textContainer = NSTextContainer(size: view.bounds.size)
+            let textContainer = NSTextContainer(size: bounds.size)
             textContainer.lineFragmentPadding = 0
             textContainer.layoutManager = layoutManager
-            
+
             layoutManager.addTextContainer(textContainer)
             layoutManager.textStorage = textStorage
-            
+
             // Find the tapped character
-            
+
             charIndex = layoutManager.characterIndexForPoint(tapLocation, inTextContainer: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
         }
-        
+
         return charIndex
     }
 }


    - returns: An instance of MentionController
    */
    public convenience init<T: UIView where T: AttributedTextContainingView>(view: T, delegate: MentionTapHandlerDelegate?) {
        let attributedString = view.m_attributedText ?? NSAttributedString(string: view.m_text, attributes: [NSFontAttributeName : view.m_font, NSForegroundColorAttributeName : view.m_textColor])
        self.init(view: view, inputString: attributedString, delegate: delegate)
    }

    private init<T: UIView where T: AttributedTextContainingView>(view: T, inputString: NSAttributedString, delegate: MentionTapHandlerDelegate?) {
        self.view = view
        self.delegate = delegate
        self.mentionDecoder = MentionDecoder(attributedString: inputString)

    func viewTapped(recognizer: UITapGestureRecognizer) {
        recognizer.cancelsTouchesInView = false

        guard let view = recognizer.view as? T else { return }

        let location = recognizer.locationInView(view)
        let charIndex = view.indexOfTappedCharacter(location)
        let attributedString = view.m_attributedText

        if let userId = attributedString?.attribute(MentionAttributes.UserId, atIndex: charIndex, effectiveRange: nil) as? String {
            delegate?.userTappedWithId(userId)
            recognizer.cancelsTouchesInView = true
        }
    }
}
