 ///	1. don't need to implement `observeValue` yourself, you can instead handle changes in a closure
 ///	2. you get a `CallbackReason` for each change which includes `valueChanged`, `pathChanged`, `sourceDeleted`.
 ///	3. observation is automatically cancelled if you release the KeyValueObserver or the source is released
+///
+/// A majority of the complexity in this class comes from the fact that we turn key-value observing on keyPaths into a series of chained KeyValueObservers that we manage ourselves. This gives us more information when things change but we're re-implementing a number of things that Cococa key-value observing normally gives us for free. Generally in this class, anything involving the `tailPath` is managing observations of the path.
 ///
 /// THREAD SAFETY:
 /// This class is memory safe even when observations are triggered concurrently from different threads.

		cancel(.cancelled)
	}
	
	// Method is called *OUTSIDE* mutex
	private func cancel(_ reason: CallbackReason) {
		let cb = mutex.sync { () -> Callback? in
			guard let c = callback else { return nil }

		}
	}
	
	// If we're observing a key path, then we need to update our chain of KeyValueObservers when part of the path changes. This starts that process from the change point.
	//
	// Mutex notes: Method must be called from *INSIDE* mutex.
	private func updateTailObserverGivenChangeDictionary(change: [NSKeyValueChangeKey: Any]) {
		if let newValue = change[NSKeyValueChangeKey.newKey] as? NSObject {
			let value: NSObject? = newValue == NSNull() ? nil : newValue
