EventUtil { public static List<BeforeEnterObserver> collectBeforeEnterObservers( Collection<? extends HasElement> oldChain, Collection<? extends HasElement> newChain) { Set<Element> chainRootElements = Stream .concat(oldChain.stream(), newChain.stream()) .map(HasElement::getElement).collect(Collectors.toSet()); return newChain.stream().flatMap(chainRoot -> { Element chainRootElement = chainRoot.getElement(); Predicate<Element> currentRootAndNonRoots = element -> { return element.equals(chainRootElement) || !chainRootElements.contains(element); }; return getImplementingComponents( flattenDescendants(chainRootElement, currentRootAndNonRoots), BeforeEnterObserver.class); }).collect(Collectors.toList()); } private  EventUtil(); static List<BeforeEnterObserver> collectBeforeEnterObservers(
            Collection<? extends HasElement> oldChain,
            Collection<? extends HasElement> newChain); static List<BeforeEnterObserver> collectBeforeEnterObserversFromChain(
            Collection<? extends HasElement> chain,
            Collection<? extends HasElement> childrenExclusions); static List<BeforeEnterObserver> collectBeforeEnterObserversFromChainElement(
            HasElement element,
            Collection<? extends HasElement> childrenExclusions); static List<BeforeLeaveObserver> collectBeforeLeaveObservers(UI ui); static List<AfterNavigationObserver> collectAfterNavigationObservers(
            UI ui); static List<LocaleChangeObserver> collectLocaleChangeObservers(
            Element element); static List<LocaleChangeObserver> collectLocaleChangeObservers(
            List<HasElement> components); static void informLocaleChangeObservers(UI ui); static void informLocaleChangeObservers(UI ui,
            List<HasElement> components); static Stream<T> getImplementingComponents(
            Stream<Element> elementStream, Class<T> type); static void inspectHierarchy(Element node,
            Collection<Element> descendants, Predicate<Element> filter);  }
@Test public void collectBeforeNavigationObserversFromChains() throws Exception { Foo foo = new Foo(); EnterObserver toBeDetached = new EnterObserver(); foo.getElement().appendChild(new EnterObserver().getElement(), toBeDetached.getElement()); Bar bar = new Bar(); Element nested = new Element("nested"); nested.appendChild(new Element("nested-child"), new EnterObserver().getElement()); bar.getElement().appendChild(new Foo().getElement(), nested); EnterObserver toBeAttached = new EnterObserver(); Collection<? extends HasElement> oldChain = Arrays.asList(foo, toBeDetached); Collection<? extends HasElement> newChain = Arrays.asList(foo, toBeAttached); List<BeforeEnterObserver> beforeNavigationObservers = EventUtil .collectBeforeEnterObservers(oldChain, newChain); Assert.assertEquals("Wrong amount of listener instances found", 2, beforeNavigationObservers.size()); }