         
         targetView?.removeGestureRecognizer(panGesture)
         
-        let info = Info(notification.userInfo)
+        let info = Keynode.Info(notification.userInfo)
         
         if let rect = info.frame {
             willShowAnimation(false, rect: rect, duration: info.duration, options: info.curve | .BeginFromCurrentState)

    /**
     * return false if need be not gesture.
     */
    optional func controller(controller: Controller, shouldHandlePanningKeyboardAtResponder responder: UIResponder) -> Bool
}

class Keyboard {
    weak var view: UIView?
    struct Singleton {
        static let instance = Keyboard()
    }
    
    class func sharedKeyboard() -> UIView? {
        return Singleton.instance.view
    }
    
    class func setKeyboard(newValue: UIView?) {
        if let view = newValue {
            if Singleton.instance.view != view {
                Singleton.instance.view = view
            }
        }
    }
}

class Responder {
    weak var responder: UIResponder?
    var blankAccessoryView = UIView()
    var inputAccessoryView: UIView? {
        set {
            if let textView = responder as? UITextView {
                textView.inputAccessoryView = newValue
            } else if let textField = responder as? UITextField {
                textField.inputAccessoryView = newValue
            }
        }
        get {
            return responder?.inputAccessoryView
        }
    }
    var keyboard: UIView? {
        Keyboard.setKeyboard(inputAccessoryView?.superview)
        
        return Keyboard.sharedKeyboard()
    }
    init(_ responder: UIResponder) {
        self.responder = responder
        
        if inputAccessoryView == nil {
            inputAccessoryView = blankAccessoryView
        } else {
            Keyboard.setKeyboard(inputAccessoryView?.superview)
        }
    }
    deinit {
        if inputAccessoryView == blankAccessoryView {
            inputAccessoryView = nil
        }
        keyboard?.hidden = false
    }
}

class Info {
    let AnimationDuration: NSTimeInterval = 0.25
    let AnimationCurve: UInt = 7
    
    var userInfo: [NSObject : AnyObject]?
    var duration: NSTimeInterval {
        if let duration = userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSTimeInterval {
            return duration
        }
        return AnimationDuration
    }
    
    var curve: UIViewAnimationOptions {
        if let curve = userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? UInt {
            return animationOptionsForAnimationCurve(curve)
        }
        return animationOptionsForAnimationCurve(AnimationCurve)
    }
    
    var frame: CGRect? {
        let frame = userInfo?[UIKeyboardFrameEndUserInfoKey]?.CGRectValue()
        if let rect = frame {
            if rect.origin.x.isInfinite || rect.origin.y.isInfinite {
                return nil
            }
        }
        return frame
    }
    
    init(_ userInfo: [NSObject : AnyObject]? = nil) {
        self.userInfo = userInfo
    }
    
    func animationOptionsForAnimationCurve(curve: UInt) -> UIViewAnimationOptions {
        return UIViewAnimationOptions(curve << 16)
    }
}

public class Controller: NSObject {
    struct Singleton {
        static var instance: UITextField? {
            didSet {
                if let textField = instance {
                    
                    textField.inputAccessoryView = UIView()
                    textField.inputView = UIView()
                    
                    if let window = UIApplication.sharedApplication().windows.first as? UIWindow {
                        window.addSubview(textField)
                    }
                }
            }
        }
    }
    
    var workingInstance: Controller?
    var workingTextField: UITextField? {
        set {
            Singleton.instance = newValue
        }
        get {
            return Singleton.instance
        }
    }
    
    override public class func initialize() {
        super.initialize()
        
        if self.isEqual(Controller.self) {
            let controller = Controller()
            controller.workingInstance = controller
            
            controller.workingTextField = UITextField()
            
            dispatch_async(dispatch_get_main_queue()) {
                controller.workingTextField?.becomeFirstResponder()
                return
            }
        }
    }
    
    public var willAnimationHandler: ((show: Bool, rect: CGRect) -> Void)?
    public var animationsHandler: ((show: Bool, rect: CGRect) -> Void)?
    public var completionHandler: ((show: Bool, responder: UIResponder?, keyboard: UIView?) -> Void)?
    
    var firstResponder: Responder?
    weak var targetView: UIView?
    lazy var panGesture: UIPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: "panGestureAction:")
    
    public weak var delegate: ControllerDelegate?
    public var gesturePanning: Bool = true
    public var autoScrollInset: Bool = true
    public var defaultInsetBottom: CGFloat = 0 {
        didSet {
            if let scrollView = targetView as? UIScrollView {
                scrollView.contentInset.bottom = defaultInsetBottom
            }
        }
    }
    var gestureHandle: Bool = true
    
    var _gestureOffset: CGFloat?
    public var gestureOffset: CGFloat {
        set {
            _gestureOffset = newValue
        }
        get {
            if let offset = _gestureOffset {
                return offset
            }
            return defaultInsetBottom
        }
    }
    public init(view: UIView? = nil) {
        self.targetView = view
        super.init()
        
        let center = NSNotificationCenter.defaultCenter()
        
        if view != nil {
            panGesture.delegate = self
            
            center.addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
            center.addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
            
            center.addObserver(self, selector: "textDidBeginEditing:", name: UITextFieldTextDidBeginEditingNotification, object: nil)
            center.addObserver(self, selector: "textDidBeginEditing:", name: UITextViewTextDidBeginEditingNotification, object: nil)
        }
        
        center.addObserver(self, selector: "keyboardDidShow:", name: UIKeyboardDidShowNotification, object: nil)
        center.addObserver(self, selector: "keyboardDidHide:", name: UIKeyboardDidHideNotification, object: nil)
    }
    
    deinit {
        workingTextField = nil
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    func willShowAnimation(show: Bool, rect: CGRect, duration: NSTimeInterval, options: UIViewAnimationOptions) {
        var keyboardRect = convertKeyboardRect(rect)
        willAnimationHandler?(show: show, rect: keyboardRect)

}

// MARK: - UIGestureRecognizerDelegate Methods
extension Keynode.Controller: UIGestureRecognizerDelegate {
    public func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return gestureRecognizer == panGesture || otherGestureRecognizer == panGesture
    }
}

// MARK: - NSNotificationCenter Methods
extension Keynode.Controller {
    func textDidBeginEditing(notification: NSNotification) {
        if let responder = notification.object as? UIResponder {
            setResponder(responder)
