@Test public void bindingServiceWorks() { TestKey rootKey = new TestKey("root"); ServiceTree.Scoped service = Mockito.mock(ServiceTree.Scoped.class); ServiceTree serviceTree = new ServiceTree(); ServiceTree.Node node = serviceTree.createRootNode(rootKey).bindService("SERVICE", service); List<ServiceTree.Node.Entry> entries = node.getBoundServices(); boolean didFind = false; for(ServiceTree.Node.Entry entry : entries) { if(entry.getService() == service) { assertThat(entry.getName()).isEqualTo("SERVICE"); didFind = true; break; } } assertThat(didFind).isTrue(); assertThat(node.getService("SERVICE")).isSameAs(service); assertThat(node.hasBoundService("SERVICE")).isTrue(); Mockito.verify(service, Mockito.never()).onExitScope(); node.removeService("SERVICE"); Mockito.verify(service, Mockito.atLeastOnce()).onExitScope(); }
@NonNull public Node createRootNode(@NonNull Object nodeKey) { checkKey(nodeKey); return createChildNode(root, nodeKey); }
ServiceTree { @NonNull public Node createRootNode(@NonNull Object nodeKey) { checkKey(nodeKey); return createChildNode(root, nodeKey); } }
ServiceTree { @NonNull public Node createRootNode(@NonNull Object nodeKey) { checkKey(nodeKey); return createChildNode(root, nodeKey); }  }
ServiceTree { @NonNull public Node createRootNode(@NonNull Object nodeKey) { checkKey(nodeKey); return createChildNode(root, nodeKey); }  boolean hasNodeWithKey(@NonNull Object key); @NonNull Node createRootNode(@NonNull Object nodeKey); @NonNull Node createChildNode(@NonNull Node parentNode, @NonNull Object nodeKey); @NonNull Node getNode(@NonNull Object key); void traverseTree(@Walk.Mode final int mode, @NonNull final Walk walk); void traverseTree(@Walk.Mode final int mode, boolean includeTreeRoot, @NonNull final Walk walk); void removeAllNodes(); void removeNodeAndChildren(@NonNull Node node); void traverseSubtree(@NonNull final Node node, @Walk.Mode final int mode, @NonNull final Walk walk); void traverseChain(@NonNull Node node, @NonNull Walk walk); void traverseChain(@NonNull Node node, boolean includeTreeRoot, @NonNull Walk walk); void traverseChain(@NonNull Node node, @Walk.Mode final int mode, @NonNull Walk walk); void traverseChain(@NonNull Node node, @Walk.Mode final int mode, final boolean includeTreeRoot, @NonNull Walk walk); @NonNull Node findRoot(@NonNull Node child); @NonNull Set<Object> getKeys(); Node getTreeRoot(); void registerRootService(@NonNull String name, @NonNull Object service); boolean hasRootService(String name); @NonNull T getRootService(String name); T unregisterRootService(String name); }
ServiceTree { @NonNull public Node createRootNode(@NonNull Object nodeKey) { checkKey(nodeKey); return createChildNode(root, nodeKey); }  boolean hasNodeWithKey(@NonNull Object key); @NonNull Node createRootNode(@NonNull Object nodeKey); @NonNull Node createChildNode(@NonNull Node parentNode, @NonNull Object nodeKey); @NonNull Node getNode(@NonNull Object key); void traverseTree(@Walk.Mode final int mode, @NonNull final Walk walk); void traverseTree(@Walk.Mode final int mode, boolean includeTreeRoot, @NonNull final Walk walk); void removeAllNodes(); void removeNodeAndChildren(@NonNull Node node); void traverseSubtree(@NonNull final Node node, @Walk.Mode final int mode, @NonNull final Walk walk); void traverseChain(@NonNull Node node, @NonNull Walk walk); void traverseChain(@NonNull Node node, boolean includeTreeRoot, @NonNull Walk walk); void traverseChain(@NonNull Node node, @Walk.Mode final int mode, @NonNull Walk walk); void traverseChain(@NonNull Node node, @Walk.Mode final int mode, final boolean includeTreeRoot, @NonNull Walk walk); @NonNull Node findRoot(@NonNull Node child); @NonNull Set<Object> getKeys(); Node getTreeRoot(); void registerRootService(@NonNull String name, @NonNull Object service); boolean hasRootService(String name); @NonNull T getRootService(String name); T unregisterRootService(String name);  }