/// <summary> /// Pushes to currently active branch /// </summary> /// <param name="evt"></param> public void Push(EventBase evt) { var currentLayer = _layers.Peek(); var newLayer = new List <BeamNode>(); foreach (var pushNode in currentLayer) { var oldBeam = new HashSet <BeamNode>(_beam); var newNode = new BeamNode(pushNode, evt); _beam.Remove(pushNode); _beam.Add(newNode); try { _layers.Push(new List <BeamNode>() { newNode }); evt.Accept(this); } finally { newLayer.AddRange(_beam.Except(oldBeam)); //auto pop layers so Pops within accept works consistently //the popped layers are not interesting - we care only about the top ones while (_layers.Peek() != currentLayer) { _layers.Pop(); } } } _layers.Push(newLayer); }