@Test
public void testMultiVersionTreeNodeState() throws Exception {

  // Some children are installed and some not. The latest version has an update available.
  // Cycling causes the latest to be installed, everything to be uninstalled, and back.
  List<DetailsTreeNode> children = getMultiVersionChildren();
  MultiVersionTreeNode node = new MultiVersionTreeNode(children);
  children.forEach(node::add);
  validateState(node, MIXED, MIXED, ImmutableList.of(NOT_INSTALLED, INSTALLED, INSTALLED, MIXED));
  node.cycleState();
  validateState(node, INSTALLED, MIXED, ImmutableList.of(NOT_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));
  // Some children are installed and some not. The latest version is not installed.
  // Cycling causes the latest to be installed, everything to be uninstalled, and back.
  children = getMultiVersionChildren();
  children.add(createMultiVersionChild(false, true, "3.0"));
  node = new MultiVersionTreeNode(children);
  children.forEach(node::add);
  validateState(node, MIXED, MIXED, ImmutableList.of(NOT_INSTALLED, INSTALLED, INSTALLED, MIXED, NOT_INSTALLED));
  node.cycleState();
  validateState(node, INSTALLED, MIXED, ImmutableList.of(NOT_INSTALLED, INSTALLED, INSTALLED, MIXED, INSTALLED));
  node.cycleState();
  validateState(node, NOT_INSTALLED, MIXED, ImmutableList.of(NOT_INSTALLED, NOT_INSTALLED, NOT_INSTALLED, NOT_INSTALLED, NOT_INSTALLED));
  node.cycleState();
  validateState(node, MIXED, MIXED, ImmutableList.of(NOT_INSTALLED, INSTALLED, INSTALLED, MIXED, NOT_INSTALLED));
  // Some children are installed and some not. The latest version is installed.
  // Cycling causes everything to be uninstalled and back.
  children = getMultiVersionChildren();
  children.add(createMultiVersionChild(true, false,"3.0"));
  node = new MultiVersionTreeNode(children);
  children.forEach(node::add);
  validateState(node, INSTALLED, INSTALLED, ImmutableList.of(NOT_INSTALLED, INSTALLED, INSTALLED, MIXED, INSTALLED));
  node.cycleState();
  validateState(node, NOT_INSTALLED, INSTALLED,
                ImmutableList.of(NOT_INSTALLED, NOT_INSTALLED, NOT_INSTALLED, NOT_INSTALLED, NOT_INSTALLED));
  node.cycleState();
  validateState(node, INSTALLED, INSTALLED, ImmutableList.of(NOT_INSTALLED, INSTALLED, INSTALLED, MIXED, INSTALLED));
  // All children are uninstalled. Cycling causes the latest to be installed and back.
  children = Lists.newArrayList(createMultiVersionChild(false, true, "1.0"),
                                createMultiVersionChild(false, true, "2.0"));
  node = new MultiVersionTreeNode(children);
  children.forEach(node::add);
  validateState(node, NOT_INSTALLED, NOT_INSTALLED, ImmutableList.of(NOT_INSTALLED, NOT_INSTALLED));
  node.cycleState();
  validateState(node, INSTALLED, NOT_INSTALLED, ImmutableList.of(NOT_INSTALLED, INSTALLED));
  node.cycleState();
  validateState(node, NOT_INSTALLED, NOT_INSTALLED, ImmutableList.of(NOT_INSTALLED, NOT_INSTALLED));
}