     internal func has<T>(subscriber: T, for eventType: T.Type) -> Bool {
         var result: Bool = false
         self.validateSubscriber(subscriber: subscriber)
-        self.validateEventType(type: eventType)
+        self.warnIfUnknown(eventType)
         self.serialQueue.sync {
             let identifier = ObjectIdentifier(eventType)
             guard let subscribed = self.subscribed[identifier] else {

            for (identifier, var subscribed) in self.subscribed {
                let weakBox = WeakBox(subscriber as AnyObject)
                let _ = subscribed.remove(weakBox)
                self.subscribed[identifier] = Set(subscribed.filter { $0.inner is T })
            }
        }
    }

    func notify<T>(_ eventType: T.Type, closure: @escaping (T) -> ())
}

public struct Options: OptionSet {

    public let rawValue: Int

    public init(rawValue: Int) {
        self.rawValue = rawValue
    }

    public static let warnUnknown = Options(rawValue: 1 << 0)

    public static let warnDropped = Options(rawValue: 1 << 1)

    public static let logEvents = Options(rawValue: 1 << 2)
}

public class EventBus {

    internal struct WeakBox: Hashable {
        internal weak var inner: AnyObject?

        internal init(_ inner: AnyObject) {
            self.inner = inner
        }

        internal static func == (lhs: WeakBox, rhs: WeakBox) -> Bool {
            return lhs.inner === rhs.inner
        }

        internal var hashValue: Int {
            guard let inner = self.inner else {
                return 0
            }
