@SuppressWarnings("unchecked")
@Test
public void buildTreeTest() throws Exception {

  // Setup mock reference hierarchy:
  // MockRoot
  // -> Ref1
  // --> Ref2
  // --> Ref3
  // ---> Ref4
  // -> Ref5
  FakeInstanceObject fakeInstance1 =
    new FakeInstanceObject.Builder(myFakeCaptureObject, 1, "DUMMY_CLASS").setName("fake1").setFields(Collections.singletonList("mField"))
      .build();
  FakeInstanceObject fakeInstance2 =
    new FakeInstanceObject.Builder(myFakeCaptureObject, 1, "DUMMY_CLASS").setName("fake2").setFields(Collections.singletonList("mField"))
      .build();
  FakeInstanceObject fakeInstance3 =
    new FakeInstanceObject.Builder(myFakeCaptureObject, 1, "DUMMY_CLASS").setName("fake3").setFields(Collections.singletonList("mField"))
      .build();
  FakeInstanceObject fakeInstance4 =
    new FakeInstanceObject.Builder(myFakeCaptureObject, 1, "DUMMY_CLASS").setName("fake4").setFields(Collections.singletonList("mField"))
      .build();
  FakeInstanceObject fakeInstance5 =
    new FakeInstanceObject.Builder(myFakeCaptureObject, 1, "DUMMY_CLASS").setName("fake5").setFields(Collections.singletonList("mField"))
      .build();
  FakeInstanceObject fakeRootObject =
    new FakeInstanceObject.Builder(myFakeCaptureObject, 2, "DUMMY_ROOT").setName("FakeRoot").build();
  fakeInstance1.setFieldValue("mField", OBJECT, fakeRootObject);
  fakeInstance2.setFieldValue("mField", OBJECT, fakeInstance1);
  fakeInstance3.setFieldValue("mField", OBJECT, fakeInstance1);
  fakeInstance4.setFieldValue("mField", OBJECT, fakeInstance3);
  fakeInstance5.setFieldValue("mField", OBJECT, fakeRootObject);
  myFakeCaptureObject
    .addInstanceObjects(ImmutableSet.of(fakeInstance1, fakeInstance2, fakeInstance3, fakeInstance4, fakeInstance5, fakeRootObject));
  myStage.selectCaptureDuration(
    new CaptureDurationData<>(1, false, false, new CaptureEntry<CaptureObject>(new Object(), () -> myFakeCaptureObject)),
    null);
  JTree tree = myDetailsView.buildTree(fakeRootObject);
  DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();
  assertNotNull(treeModel);
  MemoryObjectTreeNode<ValueObject> treeRoot = (MemoryObjectTreeNode<ValueObject>)treeModel.getRoot();
  assertNotNull(treeRoot);
  // Check the initialize tree structure is correctly populated
  assertEquals(fakeRootObject, treeRoot.getAdapter());
  assertEquals(2, treeRoot.getChildCount());
  MemoryObjectTreeNode ref1 = treeRoot.getChildren().stream().filter(child -> child.getAdapter() instanceof ReferenceObject &&
                                                                              "fake1".equals(((ReferenceObject)child.getAdapter())
                                                                                               .getReferenceInstance().getName()))
    .findFirst().orElse(null);
  assertNotNull(ref1);
  assertEquals(fakeInstance1, ((ReferenceObject)ref1.getAdapter()).getReferenceInstance());
  MemoryObjectTreeNode ref5 = treeRoot.getChildren().stream().filter(child -> child.getAdapter() instanceof ReferenceObject &&
                                                                              "fake5".equals(((ReferenceObject)child.getAdapter())
                                                                                               .getReferenceInstance().getName()))
    .findFirst().orElse(null);
  assertNotNull(ref5);
  assertEquals(fakeInstance5, ((ReferenceObject)ref5.getAdapter()).getReferenceInstance());
  assertEquals(2, ref1.getChildCount());
  assertEquals(0, ref5.getChildCount());
  MemoryObjectTreeNode<ReferenceObject> ref2 = (MemoryObjectTreeNode<ReferenceObject>)ref1.getChildAt(0);
  MemoryObjectTreeNode<ReferenceObject> ref3 = (MemoryObjectTreeNode<ReferenceObject>)ref1.getChildAt(1);
  assertEquals(fakeInstance2, ref2.getAdapter().getReferenceInstance());
  assertEquals(fakeInstance3, ref3.getAdapter().getReferenceInstance());
  TreePath path = new TreePath(new Object[]{treeRoot, ref1});
  tree.expandPath(path);
  assertEquals(0, ref2.getChildCount());
  assertEquals(1, ref3.getChildCount());
  assertEquals(fakeInstance4, ((MemoryObjectTreeNode<ReferenceObject>)ref3.getChildAt(0)).getAdapter().getReferenceInstance());
}