private void SysMsgInvokeAll(EarliestFirstSystemMessageList messages, int currentState)
        {
           
            var nextState = currentState;
            var todo = messages;
            while(true)
            {
                var m = todo.Head;
                todo = messages.Tail;
                m.Unlink();
                try
                {
                    // TODO: replace with direct cast
                    if (ShouldStash(m, nextState))
                    {
                        Stash(m);
                    }
                    if (m is ActorTaskSchedulerMessage) HandleActorTaskSchedulerMessage((ActorTaskSchedulerMessage)m);
                    else if (m is Failed) HandleFailed(m as Failed);
                    else if (m is DeathWatchNotification)
                    {
                        var msg = m as DeathWatchNotification;
                        WatchedActorTerminated(msg.Actor, msg.ExistenceConfirmed, msg.AddressTerminated);
                    }
                    else if (m is Create) Create((m as Create).Failure);
                    else if (m is Watch)
                    {
                        var watch = m as Watch;
                        AddWatcher(watch.Watchee, watch.Watcher);
                    }
                    else if (m is Unwatch)
                    {
                        var unwatch = m as Unwatch;
                        RemWatcher(unwatch.Watchee, unwatch.Watcher);
                    }
                    else if (m is Recreate) FaultRecreate((m as Recreate).Cause);
                    else if (m is Suspend) FaultSuspend();
                    else if (m is Resume) FaultResume((m as Resume).CausedByFailure);
                    else if (m is Terminate) Terminate();
                    else if (m is Supervise)
                    {
                        var supervise = m as Supervise;
                        Supervise(supervise.Child, supervise.Async);
                    }
                    else
                    {
                        throw new NotSupportedException($"Unknown message {m.GetType().Name}");
                    }
                }
                catch (Exception cause)
                {
                    HandleInvokeFailure(cause);
                }

                nextState = CalculateState();
                // As each state accepts a strict subset of another state, it is enough to unstash if we "walk up" the state
                // chain
                todo = nextState < currentState ? todo + UnstashAll() : todo;
                if (IsTerminated)
                {
                    SendAllToDeadLetters(todo);
                    return;
                }
                if (todo.IsEmpty) return; // keep running until the stash is empty
            }

        }
 private void SendAllToDeadLetters(EarliestFirstSystemMessageList messages)
 {
     if (messages.IsEmpty) return; // don't run any of this if there are no system messages
     do
     {
         var msg = messages.Head;
         messages = messages.Tail;
         msg.Unlink();
         SystemImpl.Provider.DeadLetters.Tell(msg, Self);
     } while (messages.NonEmpty);
 }