         self.threshold = threshold
         self.atBegin = atBegin
         self.closure = closure
-        super.init()
+    }
+}
+
+class DebounceExecutionInfo {
+    let timer: NSTimer?
+    let debounceInfo: DebounceInfo
+
+    init(timer: NSTimer? = nil, debounceInfo: DebounceInfo)
+    {
+        self.timer = timer
+        self.debounceInfo = debounceInfo
     }
 }
 
 /**
-*    Provide debounce and throttle functionality.
+    Provide debounce and throttle functionality.
 */
 public class RateLimit
 {
-    // TODO: Rename queue with a generic name
-    private static let debounceQueue = dispatch_queue_create("org.orru.RateLimit", DISPATCH_QUEUE_SERIAL)
-
-    // TODO: merge rateLimitDictionary with rateLimitDictionary2
-    private static var rateLimitDictionary = [String : RateLimitInfo]()
-    private static var rateLimitDictionary2 = [String : RateLimitInfo2]()
+    private static let queue = dispatch_queue_create("org.orru.RateLimit", DISPATCH_QUEUE_SERIAL)
+
+    private static var throttleExecutionDictionary = [String : ThrottleExecutionInfo]()
+    private static var debounceExecutionDictionary = [String : DebounceExecutionInfo]()
 
     /**
     Throttle call to a closure using a given threshold

                canExecuteClosure = true
            } else {
                let debounceInfo = DebounceInfo(key: key, threshold: threshold, atBegin: atBegin, closure: closure)
                // TODO: use constant for "rateLimitInfo"
                let timer = NSTimer.scheduledTimerWithTimeInterval(threshold, target: self, selector: #selector(RateLimit.throttleTimerFired2(_:)), userInfo: ["rateLimitInfo" : debounceInfo], repeats: false)
                self.setRateLimitInfoForKey2(RateLimitInfo2(timer: timer, debounceInfo: debounceInfo), forKey: key)
            }
        }
        if canExecuteClosure {
            let debounceInfo = DebounceInfo(key: key, threshold: threshold, atBegin: atBegin, closure: closure)
            // TODO: use constant for "rateLimitInfo"
            let timer = NSTimer.scheduledTimerWithTimeInterval(threshold, target: self, selector: #selector(RateLimit.throttleTimerFired2(_:)), userInfo: ["rateLimitInfo" : debounceInfo], repeats: false)
            self.setRateLimitInfoForKey2(RateLimitInfo2(timer: timer, debounceInfo: debounceInfo), forKey: key)
            closure()
        }
    }

    // TODO: Rename method
    @objc private static func throttleTimerFired2(timer: NSTimer)
    {
        // TODO: use constant for "rateLimitInfo"
        if let userInfo = timer.userInfo as? [String : AnyObject], debounceInfo = userInfo["rateLimitInfo"] as? DebounceInfo where !debounceInfo.atBegin  {
            debounceInfo.closure()
        }
    }

    public static func resetAllRateLimit()
    {
        dispatch_sync(debounceQueue) {
            for key in self.rateLimitDictionary.keys {
                if let rateLimitInfo = self.rateLimitDictionary[key], let timer = rateLimitInfo.timer where timer.valid {
                    timer.invalidate()
                }
                self.rateLimitDictionary[key] = nil
            }
            for key in self.rateLimitDictionary2.keys {
                if let rateLimitInfo = self.rateLimitDictionary2[key], let timer = rateLimitInfo.timer where timer.valid {
                    timer.invalidate()
                }
                self.rateLimitDictionary2[key] = nil
            }
        }
    }

    public static func resetRateLimitForKey(key: String)
    {
        dispatch_sync(debounceQueue) {
            if let rateLimitInfo = self.rateLimitDictionary[key], let timer = rateLimitInfo.timer where timer.valid {
                timer.invalidate()
            }
            self.rateLimitDictionary[key] = nil
            if let rateLimitInfo = self.rateLimitDictionary2[key], let timer = rateLimitInfo.timer where timer.valid {
                timer.invalidate()
            }
            self.rateLimitDictionary2[key] = nil
        }
    }

    // TODO: merge rateLimitInfoForKey with rateLimitInfoForKey2
    private static func rateLimitInfoForKey(key: String) -> RateLimitInfo?
    {
        var rateLimitInfo: RateLimitInfo?
        dispatch_sync(debounceQueue) {
            rateLimitInfo = self.rateLimitDictionary[key]
        }
        return rateLimitInfo
    }

    // TODO: merge rateLimitInfoForKey with rateLimitInfoForKey2
    private static func rateLimitInfoForKey2(key: String) -> RateLimitInfo2?
    {
        var rateLimitInfo: RateLimitInfo2?
        dispatch_sync(debounceQueue) {
            rateLimitInfo = self.rateLimitDictionary2[key]
        }
        return rateLimitInfo
    }

    // TODO: merge setRateLimitInfoForKey with setRateLimitInfoForKey2
    private static func setRateLimitInfoForKey(rateLimitInfo: RateLimitInfo, forKey key: String)
    {
        dispatch_sync(debounceQueue) {
            self.rateLimitDictionary[key] = rateLimitInfo
        }
    }

    // TODO: merge setRateLimitInfoForKey with setRateLimitInfoForKey2
    private static func setRateLimitInfoForKey2(rateLimitInfo: RateLimitInfo2, forKey key: String)
    {
        dispatch_sync(debounceQueue) {
            self.rateLimitDictionary2[key] = rateLimitInfo
        }
    }
}

        self.threshold = threshold
        self.trailing = trailing
        self.closure = closure
    }
}

class ThrottleExecutionInfo {
    let lastExecutionDate: NSDate
    let timer: NSTimer?
    let throttleInfo: ThrottleInfo

    init(lastExecutionDate: NSDate, timer: NSTimer? = nil, throttleInfo: ThrottleInfo)
    {
        self.lastExecutionDate = lastExecutionDate
        self.timer = timer
        self.throttleInfo = throttleInfo
    }
}

class DebounceInfo {
    let key: String
    let threshold: NSTimeInterval
    let atBegin: Bool
