@Test
public void testParentTreeNodeState() throws Exception {

  // All children are not installed. Cycling causes all children to be installed, and back.
  ParentTreeNode node = new ParentTreeNode("foo");
  addUnselectedChildren(node);
  validateState(node, NOT_INSTALLED, NOT_INSTALLED, ImmutableList.of(NOT_INSTALLED, NOT_INSTALLED));
  node.cycleState();
  validateState(node, INSTALLED, NOT_INSTALLED, ImmutableList.of(INSTALLED, INSTALLED));
  node.cycleState();
  validateState(node, NOT_INSTALLED, NOT_INSTALLED, ImmutableList.of(NOT_INSTALLED, NOT_INSTALLED));
  // All children are installed. Cycling causes all children to be uninstalled, and back.
  node = new ParentTreeNode(new AndroidVersion(10, null));
  addSelectedChildren(node);
  validateState(node, INSTALLED, INSTALLED, ImmutableList.of(INSTALLED, INSTALLED));
  node.cycleState();
  validateState(node, NOT_INSTALLED, INSTALLED, ImmutableList.of(NOT_INSTALLED, NOT_INSTALLED));
  node.cycleState();
  validateState(node, INSTALLED, INSTALLED, ImmutableList.of(INSTALLED, INSTALLED));
  // Some children are installed, some not, and some have upgrades available.
  // Cycling causes all to be installed, not installed, and back.
  node = new ParentTreeNode(new AndroidVersion(10, null));
  addMixedChildren(node);
  validateState(node, MIXED, MIXED, ImmutableList.of(NOT_INSTALLED, INSTALLED, INSTALLED, MIXED));
  node.cycleState();
  validateState(node, INSTALLED, MIXED, ImmutableList.of(INSTALLED, INSTALLED, INSTALLED, INSTALLED));
  node.cycleState();
  validateState(node, NOT_INSTALLED, MIXED, ImmutableList.of(NOT_INSTALLED, NOT_INSTALLED, NOT_INSTALLED, NOT_INSTALLED));
  node.cycleState();
  validateState(node, MIXED, MIXED, ImmutableList.of(NOT_INSTALLED, INSTALLED, INSTALLED, MIXED));
}