@Test
public void testExtractReferences() throws Exception {

  MockClassInstance mockInstance = new MockClassInstance(-1, 0, MOCK_CLASS);
  // Set up valid/invalid reference case
  MockClassInstance hardInstanceRef = new MockClassInstance(-1, 3, MOCK_CLASS);
  hardInstanceRef.addFieldValue(Type.OBJECT, "hardInstanceRef", mockInstance);
  hardInstanceRef.addFieldValue(Type.OBJECT, "invalidRef", new Object());
  // Set up multiple case
  MockArrayInstance hardArrayRef = new MockArrayInstance(-1, Type.OBJECT, 3, 2);
  hardArrayRef.setValue(0, new Object());
  hardArrayRef.setValue(1, mockInstance);
  hardArrayRef.setValue(2, mockInstance);
  // Set up different type case
  MockClassObj hardClassRef = new MockClassObj(-1, "hardClassRef", 1);
  hardClassRef.addStaticField(Type.OBJECT, "staticClassRef", mockInstance);
  hardClassRef.addStaticField(Type.BOOLEAN, "invalidBoolRef", false);
  // Set up soft references appear at end
  MockClassInstance softInstanceRef = new MockClassInstance(-1, 0, MOCK_CLASS);
  softInstanceRef.addFieldValue(Type.OBJECT, "softInstanceRef", mockInstance);
  softInstanceRef.addFieldValue(Type.OBJECT, "invalidRef", new Object());
  mockInstance.addHardReference(hardInstanceRef);
  mockInstance.addHardReference(hardArrayRef);
  mockInstance.addHardReference(hardClassRef);
  mockInstance.addSoftReferences(softInstanceRef);
  ClassDb.ClassEntry mockClassEntry = myCaptureObject.getClassDb().registerClass(0, MOCK_CLASS);
  myCaptureObject.addInstance(hardInstanceRef, new HeapDumpInstanceObject(
    myCaptureObject, hardInstanceRef, mockClassEntry, OBJECT));
  myCaptureObject.addInstance(hardArrayRef, new HeapDumpInstanceObject(
    myCaptureObject, hardArrayRef, mockClassEntry, ARRAY));
  myCaptureObject.addInstance(hardClassRef, new HeapDumpInstanceObject(
    myCaptureObject, hardClassRef, mockClassEntry, CLASS));
  myCaptureObject.addInstance(softInstanceRef, new HeapDumpInstanceObject(
    myCaptureObject, softInstanceRef, mockClassEntry, OBJECT));
  myCaptureObject.addInstance(mockInstance, new HeapDumpInstanceObject(
    myCaptureObject, mockInstance, mockClassEntry, OBJECT));
  // extractReference is expected to return a list of sorted hard references first
  // then sorted soft references.
  List<ReferenceObject> referrers = myCaptureObject.getInstance(mockInstance).extractReferences();
  assertEquals(4, referrers.size());
  // The first object should refer to the hardClassRef which has the shortest distance to root.
  List<String> refs = referrers.get(0).getReferenceFieldNames();
  assertEquals(1, refs.size());
  assertEquals("staticClassRef", refs.get(0));
  // The second object should refer to hardArrayRef with two indices references
  refs = referrers.get(1).getReferenceFieldNames();
  assertEquals(2, refs.size());
  assertEquals("1", refs.get(0));
  assertEquals("2", refs.get(1));
  // The third object should refer to hardInstanceRef
  refs = referrers.get(2).getReferenceFieldNames();
  assertEquals(1, refs.size());
  assertEquals("hardInstanceRef", refs.get(0));
  // The fourth object should refer to softInstanceRef
  refs = referrers.get(3).getReferenceFieldNames();
  assertEquals(1, refs.size());
  assertEquals("softInstanceRef", refs.get(0));
}