             #if DEBUG
                 fatalError(message)
             #else
-                print("Warning:", message)
+                print(message)
             #endif
         }
     }
 
-    fileprivate func validateEventType<T>(type eventType: T.Type) {
+    fileprivate func warnIfUnknown<T>(_ eventType: T.Type) {
         let identifier = ObjectIdentifier(eventType)
-        guard let registered = self.registered else {
-            return
-        }
-        if registered[identifier] == nil {
-            let names = Array(registered.values).joined(separator: ", ")
-            let message = "Expected registered event type (e.g. \(names)), found: \(eventType)"
-            #if DEBUG
-                fatalError(message)
-            #else
-                print("Warning:", message)
-            #endif
-        }
+        guard self.options.contains(.warnUnknown) else {
+            return
+        }
+        guard self.registered[identifier] != nil else {
+            return
+        }
+        let names = Array(self.registered.values).joined(separator: ", ")
+        let message = "\(self.nameAndAddress): Expected event of registered type (e.g. \(names)), found: \(eventType)"
+        #if DEBUG
+            fatalError(message)
+        #else
+            print(message)
+        #endif
+    }
+
+    fileprivate func warnIfDropped<T>(_ eventType: T.Type) {
+        let identifier = ObjectIdentifier(eventType)
+        guard self.options.contains(.warnDropped) else {
+            return
+        }
+        guard self.subscribed[identifier] == nil else {
+            return
+        }
+        let message = "\(self.nameAndAddress): Event of type '\(eventType)' was not handled."
+        #if DEBUG
+            fatalError(message)
+        #else
+            print(message)
+        #endif
+    }
+
+    fileprivate func logEvent<T>(_ eventType: T.Type) {
+        #if DEBUG
+            if self.options.contains(.logEvents) {
+                print("\(self.nameAndAddress): Received event '\(eventType)'")
+            }
+        #endif
+    }
+
+    fileprivate func pruned<T>(subscribed: Set<WeakBox>, for eventType: T.Type) -> Set<WeakBox>? {
+        let filtered = subscribed.filter { $0.inner is T }
+        return filtered.isEmpty ? nil : Set(filtered)
     }
 }
 
 extension EventBus: EventRegistrable {
     public func register<T>(forEvent eventType: T.Type) {
         let identifier = ObjectIdentifier(eventType)
-        if self.registered == nil {
-            self.registered = [:]
-        }
-        self.registered![identifier] = String(describing: eventType)
+        self.registered[identifier] = String(describing: eventType)
     }
 }
 
 extension EventBus: EventSubscribable {
     public func add<T>(subscriber: T, for eventType: T.Type) {
         self.validateSubscriber(subscriber: subscriber)
-        self.validateEventType(type: eventType)
+        self.warnIfUnknown(eventType)
         self.serialQueue.sync {
             let identifier = ObjectIdentifier(eventType)
             var subscribed = self.subscribed[identifier] ?? []
             let weakBox = WeakBox(subscriber as AnyObject)
             subscribed.insert(weakBox)
-            self.subscribed[identifier] = Set(subscribed.filter { $0.inner is T })
+            self.subscribed[identifier] = self.pruned(subscribed: subscribed, for: eventType)
         }
     }
 
     public func remove<T>(subscriber: T, for eventType: T.Type) {
         self.validateSubscriber(subscriber: subscriber)
-        self.validateEventType(type: eventType)
+        self.warnIfUnknown(eventType)
         self.serialQueue.sync {
             let identifier = ObjectIdentifier(eventType)
             var subscribed = self.subscribed[identifier] ?? []
             let weakBox = WeakBox(subscriber as AnyObject)
             let _ = subscribed.remove(weakBox)
-            self.subscribed[identifier] = Set(subscribed.filter { $0.inner is T })
+            self.subscribed[identifier] = self.pruned(subscribed: subscribed, for: eventType)
         }
     }
 


    public static let shared: EventBus = EventBus()

    fileprivate var registered: [ObjectIdentifier: String]?
    fileprivate var subscribed: [ObjectIdentifier: Set<WeakBox>] = [:]
    fileprivate var chained: Set<WeakBox> = []

    fileprivate let serialQueue: DispatchQueue = DispatchQueue(label: "com.regexident.eventbus")
    fileprivate let queue: DispatchQueue

    public init(strict: Bool = false, queue: DispatchQueue = .global()) {
        self.registered = strict ? [:] : nil
        self.queue = queue
    }

    fileprivate func validateSubscriber<T>(subscriber: T) {

            for (identifier, var subscribed) in self.subscribed {
                let weakBox = WeakBox(subscriber as AnyObject)
                let _ = subscribed.remove(weakBox)
                self.subscribed[identifier] = subscribed
            }
        }
    }
