         self.context = context
         self.frequency = frequency
         self.filterPredicate = filterPredicate
-        guard let entity = NSEntityDescription.entityForName(T.entityName, inManagedObjectContext: context) else {
-            entityPredicate = NSPredicate()
-            return nil
-        }
-
-        entityPredicate = NSPredicate(format: "entity == %@", entity)
-        setupObservers()
+        self.entityPredicate = NSPredicate(format: "entity == %@", T.entityInContext(context))
     }
 
     deinit {
-        removeObservers()
+        delegateHost?.removeObservers()
+    }
+}
+
+private let ChangeObserverSelectorName: Selector = "evaluateChangeNotification:"
+
+private class BaseEntityMonitorDelegate<T: NSManagedObject where T: CoreDataModelable>: NSObject {
+
+    typealias Owner = EntityMonitor<T>
+    typealias EntitySet = Owner.EntitySet
+
+    unowned let owner: Owner
+
+    init(owner: Owner) {
+        self.owner = owner
     }
 
-    // MARK: - Private
-
-    private func setupObservers() {
+    final func setupObservers() {
         let notificationName: String
-        switch frequency {
+        switch owner.frequency {
         case .OnChange:
             notificationName = NSManagedObjectContextObjectsDidChangeNotification
         case .OnSave:

        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: ChangeObserverSelectorName,
            name: notificationName,
            object: context)
    }

    private func removeObservers() {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

    // MARK: - Notifications

    @objc private func evaluateChangeNotification(notification: NSNotification) {
        guard let changeSet = notification.userInfo else {
            return
        }

        context.performBlockAndWait() {
            if let inserted = changeSet[NSInsertedObjectsKey],
                filtered = inserted.filteredSetUsingPredicate(self.combinedPredicate)
                    as? EntitySet where filtered.count > 0 {
                        self.delegate?.objectsInserted(self, filtered)
            }

            if let deleted = changeSet[NSDeletedObjectsKey],
                filtered = deleted.filteredSetUsingPredicate(self.combinedPredicate)
                    as? EntitySet where filtered.count > 0 {
                       self.delegate?.objectsRemoved(self, filtered)
            }

            if let updated = changeSet[NSUpdatedObjectsKey],
                filtered = updated.filteredSetUsingPredicate(self.combinedPredicate)
                    as? EntitySet where filtered.count > 0 {
                        self.delegate?.objectsUpdated(self, filtered)
            }
        }
    }
}

private let ChangeObserverSelectorName: Selector = "evaluateChangeNotification:"

private struct InternalEntityMonitorDelegate<T: NSManagedObject where T: CoreDataModelable> {
    let objectsInserted: (EntityMonitor<T>, Set<T>) -> Void
    let objectsRemoved: (EntityMonitor<T>, Set<T>) -> Void
    let objectsUpdated: (EntityMonitor<T>, Set<T>) -> Void

    init<U: EntityMonitorDelegate where U.T == T>(_ delegate: U) {
        objectsInserted = { [weak delegate] in
            delegate?.entityMonitorObservedInserts($0, entities: $1)
        }
        objectsRemoved = { [weak delegate] in
            delegate?.entityMonitorObservedDeletions($0, entities: $1)
        }
        objectsUpdated = { [weak delegate] in
            delegate?.entityMonitorObservedModifications($0, entities: $1)
        }
    }
}

     - parameter U: Your delegate must implement the methods in `EntityMonitorDelegate` with the matching `CoreDataModelable` type being monitored.
     */
    public func setDelegate<U: EntityMonitorDelegate where U.T == T>(delegate: U) {
        self.delegateHost = ForwardingEntityMonitorDelegate(owner: self, delegate: delegate)
    }

    // MARK: - Private Properties

    private var delegateHost: BaseEntityMonitorDelegate<T>? {
        willSet {
            delegateHost?.removeObservers()
        }
        didSet {
            delegateHost?.setupObservers()
        }
    }

    private typealias EntitySet = Set<T>

