private void notifyRecurse(T sender, int arg, A arg2) {
        final int callbackCount = mCallbacks.size();
        final int remainderIndex = mRemainderRemoved == null ? -1 : mRemainderRemoved.length - 1;

        // Now we've got all callbakcs that have no mRemainderRemoved value, so notify the
        // others.
        notifyRemainder(sender, arg, arg2, remainderIndex);

        // notifyRemainder notifies all at maxIndex, so we'd normally start at maxIndex + 1
        // However, we must also keep track of those in mFirst64Removed, so we add 2 instead:
        final int startCallbackIndex = (remainderIndex + 2) * Long.SIZE;

        // The remaining have no bit set
        notifyCallbacks(sender, arg, arg2, startCallbackIndex, callbackCount, 0);
    }
Notify all callbacks using a recursive algorithm to avoid allocating on the heap.
This part captures the callbacks beyond Long.SIZE that have no bits allocated for
removal before it recurses into {@link #notifyRemainder(Object, int, A, int)}.

<p>Recursion is used to avoid allocating temporary state on the heap.</p>

@param sender The originator. This is an opaque parameter passed to
              {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
@param arg    An opaque parameter passed to
              {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
@param arg2   An opaque parameter passed to
              {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/util/obs/CallbackRegistry.java