private static void SubscribeProgressToChain(Promise promise, Internal.IProgressListener progressListener, ref ValueLinkedStack <Internal.PromisePassThrough> passThroughs)
        {
            Promise next;

            // If the promise is not waiting on another promise (is the root), it sets next to null, does not add the listener, and returns false.
            // If the promise is waiting on another promise that is not its previous, it adds the listener, transforms progresslistener, sets next to the one it's waiting on, and returns true.
            // Otherwise, it sets next to its previous, adds the listener only if it is a WaitPromise, and returns true.
            while (promise.SubscribeProgressIfWaiterAndContinueLoop(ref progressListener, out next, ref passThroughs))
            {
                promise = next;
            }

            // promise is the root of the promise tree.
            switch (promise._state)
            {
            case State.Pending:
            {
                progressListener.SetInitialAmount(promise._waitDepthAndProgress);
                break;
            }

            case State.Resolved:
            {
                progressListener.SetInitialAmount(promise._waitDepthAndProgress.GetIncrementedWholeTruncated());
                break;
            }

            default:     // Rejected or Canceled:
            {
                progressListener.Retain();
                progressListener.CancelOrIncrementProgress(promise, promise._waitDepthAndProgress.GetIncrementedWholeTruncated().ToUInt32());
                break;
            }
            }
        }
 protected virtual bool SubscribeProgressAndContinueLoop(ref Internal.IProgressListener progressListener, out Promise previous)
 {
     progressListener.Retain();
     _progressListeners.Push(progressListener);
     return((previous = _valueOrPrevious as Promise) != null);
 }