StateNode implements Serializable { public void setParent(StateNode parent) { if (hasDetached()) { return; } boolean attachedBefore = isRegistered(); boolean attachedAfter = false; if (parent != null) { assert this.parent == null : "Node is already attached to a parent: " + this.parent; assert parent.hasChildAssert(this); if (isAncestorOf(parent)) { throw new IllegalStateException( "Can't set own child as parent"); } attachedAfter = parent.isRegistered(); NodeOwner parentOwner = parent.getOwner(); if (parentOwner != owner && parentOwner instanceof StateTree) { setTree((StateTree) parentOwner); } } if (!attachedBefore && attachedAfter) { this.parent = parent; onAttach(); } else if (attachedBefore && !attachedAfter) { onDetach(); this.parent = parent; } else { this.parent = parent; } } @SafeVarargs  StateNode(Class<? extends NodeFeature>... featureTypes); @SuppressWarnings("unchecked")  StateNode(StateNode node); @SafeVarargs  StateNode(List<Class<? extends NodeFeature>> reportableFeatureTypes,
            Class<? extends NodeFeature>... additionalFeatureTypes); NodeOwner getOwner(); StateNode getParent(); void setParent(StateNode parent); void removeFromTree(); T getFeature(Class<T> featureType); Optional<T> getFeatureIfInitialized(
            Class<T> featureType); boolean hasFeature(Class<? extends NodeFeature> featureType); int getId(); void markAsDirty(); boolean isAttached(); void collectChanges(Consumer<NodeChange> collector); void clearChanges(); void visitNodeTree(Consumer<StateNode> visitor); Registration addAttachListener(Command attachListener); Registration addDetachListener(Command detachListener); @SuppressWarnings("unchecked") T getChangeTracker(NodeFeature feature,
            Supplier<T> factory); void runWhenAttached(SerializableConsumer<UI> command); boolean isReportedFeature(Class<? extends NodeFeature> featureType); void updateActiveState(); boolean isInactive(); boolean hasBeforeClientResponseEntries(); List<StateTree.BeforeClientResponseEntry> dumpBeforeClientResponseEntries(); ExecutionRegistration addBeforeClientResponseEntry(
            BeforeClientResponseEntry entry); void setEnabled(boolean enabled); boolean isEnabled(); boolean isEnabledSelf();  }
@Test(expected = IllegalStateException.class) public void setChildAsParent() { StateNode parent = createParentNode("parent"); StateNode child = createParentNode("child"); setParent(child, parent); setParent(parent, child); }
@Test(expected = IllegalStateException.class) public void setAsOwnParent() { StateNode parent = createParentNode("parent"); setParent(parent, parent); }