### Question:
NodeState { void recursivelyPerformOperation(NodeStateContext nodeStateContext, OPERATION operation) { Map<NodeLink, Node> children = nodeStateContext.getChildren(); if (children != null) { for (NodeLink nodeLink : children.keySet()) { List<CascadeType> cascadeTypes = (List<CascadeType>) nodeLink.getLinkProperty(LinkProperty.CASCADE); switch (operation) { case REFRESH: if (cascadeTypes.contains(CascadeType.REFRESH) || cascadeTypes.contains(CascadeType.ALL)) { Node childNode = children.get(nodeLink); childNode.refresh(); } break; case DETACH: if (cascadeTypes.contains(CascadeType.DETACH) || cascadeTypes.contains(CascadeType.ALL)) { Node childNode = children.get(nodeLink); childNode.detach(); } break; } } } }  abstract void initialize(NodeStateContext nodeStateContext); abstract void handlePersist(NodeStateContext nodeStateContext); abstract void handleRemove(NodeStateContext nodeStateContext); abstract void handleRefresh(NodeStateContext nodeStateContext); abstract void handleMerge(NodeStateContext nodeStateContext); abstract void handleDetach(NodeStateContext nodeStateContext); abstract void handleClose(NodeStateContext nodeStateContext); abstract void handleLock(NodeStateContext nodeStateContext); abstract void handleCommit(NodeStateContext nodeStateContext); abstract void handleRollback(NodeStateContext nodeStateContext); abstract void handleFind(NodeStateContext nodeStateContext); abstract void handleGetReference(NodeStateContext nodeStateContext); abstract void handleContains(NodeStateContext nodeStateContext); abstract void handleClear(NodeStateContext nodeStateContext); abstract void handleFlush(NodeStateContext nodeStateContext);  }### Answer:
@Test public void testRecursivelyPerformOperation() { NodeState state = new TransientState(); Node storeNode = StoreBuilder.buildStoreNode(pc, state, CascadeType.PERSIST); state.recursivelyPerformOperation(storeNode, OPERATION.PERSIST); Assert.assertEquals(TransientState.class, storeNode.getCurrentNodeState().getClass()); for (Node childNode : storeNode.getChildren().values()) { Assert.assertEquals(BillingCounter.class, childNode.getDataClass()); } state = new DetachedState(); storeNode = StoreBuilder.buildStoreNode(pc, state, CascadeType.MERGE); state.recursivelyPerformOperation(storeNode, OPERATION.MERGE); Assert.assertEquals(DetachedState.class, storeNode.getCurrentNodeState().getClass()); for (Node childNode : storeNode.getChildren().values()) { Assert.assertEquals(BillingCounter.class, childNode.getDataClass()); } state = new ManagedState(); storeNode = StoreBuilder.buildStoreNode(pc, state, CascadeType.REMOVE); state.recursivelyPerformOperation(storeNode, OPERATION.REMOVE); Assert.assertEquals(ManagedState.class, storeNode.getCurrentNodeState().getClass()); for (Node childNode : storeNode.getChildren().values()) { Assert.assertEquals(BillingCounter.class, childNode.getDataClass()); } state = new DetachedState(); storeNode = StoreBuilder.buildStoreNode(pc, state, CascadeType.REFRESH); try { state.recursivelyPerformOperation(storeNode, OPERATION.REFRESH); Assert.fail("Refresh operation in Detached state should have thrown an exception"); } catch (Exception e) { Assert.assertEquals(IllegalArgumentException.class, e.getClass()); } state = new ManagedState(); storeNode = StoreBuilder.buildStoreNode(pc, state, CascadeType.DETACH); state.recursivelyPerformOperation(storeNode, OPERATION.DETACH); Assert.assertEquals(ManagedState.class, storeNode.getCurrentNodeState().getClass()); for (Node childNode : storeNode.getChildren().values()) { Assert.assertEquals(BillingCounter.class, childNode.getDataClass()); } }