     /// Initializes an allocated gesture-recognizer object with a target and an action selector.
     public init(targetAction: TargetAction) {
         
-        
+        addTarget(targetAction)
     }
     
     // MARK: - Adding and Removing Targets and Actions
     
     // add a target/action pair. you can call this multiple times to specify multiple target/actions
-    open func addTarget(_ target: AnyHashable, action: Selector) {
-        
-        
+    public func addTarget(_ target: TargetAction) {
+        
+        targetActions.append(target)
     }
     
     // remove the specified target/action pair. passing nil for target matches all targets, and the same for actions
-    open func removeTarget(_ target: Any?, action: Selector?) {
-        
-        
+    public func removeTarget(_ target: TargetAction) {
+        
+        guard let index = targetActions.index(where: { $0.name == target.name })
+            else { return }
+        
+        targetActions.remove(at: index)
     }
     
     // MARK: - Getting the Touches and Location of a Gesture
     
     // individual UIGestureRecognizer subclasses may provide subclass-specific location information. see individual subclasses for details
     // a generic single-point location for the gesture. usually the centroid of the touches involved
+    
+    /// Returns the point computed as the location of the gesture.
+    ///
+    /// - Parameter view: The view whose coordinate system you want to use for determining the location of the gesture.
+    /// Specify nil to return the point in the coordinate system of the window.
+    ///
+    /// - Returns: The point at which the gesture occurred.
+    /// The returned point is in the coordinate system of the specified view,
+    /// or in the coordinate system of the window if you specified nil for the view parameter.
     open func location(in view: UIView?) -> CGPoint {
         
-        
+        guard touches.isEmpty == false
+            else { return .zero }
+        
+        let combinedPoint = touches
+            .map({ $0.location(in: view) })
+            .reduce(CGPoint(), { CGPoint(x: $0.x + $1.x, y: $0.y + $1.y) })
+        
+        return CGPoint(x: combinedPoint.x / CGFloat(touches.count),
+                       y: combinedPoint.y / CGFloat(touches.count))
     }
     
     // number of touches involved for which locations can be queried
     // the location of a particular touch
     open func location(ofTouch touchIndex: Int, in view: UIView?) -> CGPoint {
         
-        
+        return touches[touchIndex].location(in: view)
     }
     
     // number of touches involved for which locations can be queried
     open var numberOfTouches: Int {
-        return 1
+        
+        return touches.count
     }
     
     // MARK: - Getting the Recognizer’s State and View
     
     // the current state of the gesture recognizer
-    open var state: UIGestureRecognizerState
+    open var state = UIGestureRecognizerState()
     
     // a UIGestureRecognizer receives touches hit-tested to its view and any of that view's subviews
-    // the view the gesture is attached to. set by adding the recognizer to a UIView using the addGestureRecognizer: method
-    open var view: UIView?
+    // the view the gesture is attached to. set by adding the recognizer to a UIView using the `addGestureRecognizer()` method
+    public internal(set) weak var view: UIView?
     
     // default is YES. disabled gesture recognizers will not receive touches. when changed to NO the gesture recognizer will be cancelled if it's currently recognizing a gesture
-    open var isEnabled: Bool
+    open var isEnabled: Bool = true
     
     // MARK: - Canceling and Delaying Touches
     
     // default is YES. causes touchesCancelled:withEvent: or pressesCancelled:withEvent: to be sent to the view for all touches or presses recognized as part of this gesture immediately before the action method is called.
-    open var cancelsTouchesInView: Bool
+    public var cancelsTouchesInView: Bool = true
     
     // default is NO.  causes all touch or press events to be delivered to the target view only after this gesture has failed recognition. set to YES to prevent views from processing any touches or presses that may be recognized as part of this gesture
-    open var delaysTouchesBegan: Bool
+    public var delaysTouchesBegan: Bool = false
     
     // default is YES. causes touchesEnded or pressesEnded events to be delivered to the target view only after this gesture has failed recognition. this ensures that a touch or press that is part of the gesture can be cancelled if the gesture is recognized
-    open var delaysTouchesEnded: Bool
+    public var delaysTouchesEnded: Bool = true
     
     // MARK: - Specifying Dependencies Between Gesture Recognizers
     

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive press: UIPress) -> Bool
}

public enum UIGestureRecognizerState : Int {
    
    public init() { self = .possible }
    

//  Created by Alsey Coleman Miller on 6/8/17.
//

import struct Foundation.CGFloat
import struct Foundation.CGPoint

/// The base class for concrete gesture recognizers.
