@Test
    public void testCleanup() {
        SpanList a = new SpanList();
        SpanTree tree = new SpanTree("ballooO", a);
        Span b = new Span(0,1);
        Span c = new Span(1,1);
        a.add(b).add(c);

        AnnotationReferenceDataType refTypeToDummy = new AnnotationReferenceDataType(dummy);
        AnnotationType annotationTypeWithRefToDummy = new AnnotationType("reftodummy", refTypeToDummy);

        AnnotationReferenceDataType refTypeToRefTypeToDummy = new AnnotationReferenceDataType(annotationTypeWithRefToDummy);
        AnnotationType annotationTypeWithRefToRefToDummy = new AnnotationType("reftoreftodummy", refTypeToRefTypeToDummy);

        StructDataType structType = new StructDataType("str");
        Field refToDummyField = new Field("refToDummy", refTypeToDummy);
        structType.addField(refToDummyField);
        AnnotationType annotationTypeWithStruct = new AnnotationType("structwithref", structType);


        Annotation dummyAnnotationForB = new Annotation(dummy);
        tree.annotate(b, dummyAnnotationForB);

        AnnotationReference referenceToDummyB = new AnnotationReference(refTypeToDummy, dummyAnnotationForB);
        Annotation annotationWithRefToDummyB = new Annotation(annotationTypeWithRefToDummy, referenceToDummyB);
        tree.annotate(annotationWithRefToDummyB);

        AnnotationReference referenceToRefToDummyB = new AnnotationReference(refTypeToRefTypeToDummy, annotationWithRefToDummyB);
        Annotation annotationWithRefToRefToDummyB = new Annotation(annotationTypeWithRefToRefToDummy, referenceToRefToDummyB);
        tree.annotate(annotationWithRefToRefToDummyB);

        Struct struct = new Struct(structType);
        struct.setFieldValue(refToDummyField, new AnnotationReference(refTypeToDummy, dummyAnnotationForB));
        Annotation annotationWithStruct = new Annotation(annotationTypeWithStruct, struct);
        tree.annotate(annotationWithStruct);


        Iterator<Annotation> annotationIt;

        assertEquals(4, tree.numAnnotations());
        assertTrue(a.isValid());
        assertTrue(b.isValid());
        assertTrue(c.isValid());
        assertEquals(2, a.numChildren());

        {
            List<Annotation> allAnnotationsList = new ArrayList<>();
            for (Annotation an : tree) {
                allAnnotationsList.add(an);
            }
            Collections.sort(allAnnotationsList);

            annotationIt = allAnnotationsList.iterator();
        }
        // NOTE: ordering of annotations is derived from their name

        assertSame(annotationWithRefToDummyB, annotationIt.next());
        assertFalse(annotationWithRefToDummyB.hasSpanNode());
        assertFalse(annotationWithRefToDummyB.isSpanNodeValid());
        assertTrue(annotationWithRefToDummyB.hasFieldValue());
        assertSame(dummyAnnotationForB, ((AnnotationReference) annotationWithRefToDummyB.getFieldValue()).getReference());

        assertSame(annotationWithStruct, annotationIt.next());
        assertFalse(annotationWithStruct.hasSpanNode());
        assertFalse(annotationWithStruct.isSpanNodeValid());
        assertTrue(annotationWithStruct.hasFieldValue());
        assertSame(struct, annotationWithStruct.getFieldValue());
        assertSame(dummyAnnotationForB, ((AnnotationReference) struct.getFieldValue(refToDummyField)).getReference());

        assertSame(annotationWithRefToRefToDummyB, annotationIt.next());
        assertFalse(annotationWithRefToRefToDummyB.hasSpanNode());
        assertFalse(annotationWithRefToRefToDummyB.isSpanNodeValid());
        assertTrue(annotationWithRefToRefToDummyB.hasFieldValue());
        assertSame(annotationWithRefToDummyB, ((AnnotationReference) annotationWithRefToRefToDummyB.getFieldValue()).getReference());

        assertSame(dummyAnnotationForB, annotationIt.next());
        assertTrue(dummyAnnotationForB.hasSpanNode());
        assertTrue(dummyAnnotationForB.isSpanNodeValid());
        assertFalse(dummyAnnotationForB.hasFieldValue());

        assertFalse(annotationIt.hasNext());

        //removing b!!
        a.remove(b);


        assertEquals(4, tree.numAnnotations());
        assertTrue(a.isValid());
        assertFalse(b.isValid());
        assertTrue(c.isValid());
        assertEquals(1, a.numChildren());

        {
            List<Annotation> allAnnotationsList = new ArrayList<>();
            for (Annotation an : tree) {
                allAnnotationsList.add(an);
            }
            Collections.sort(allAnnotationsList);

            annotationIt = allAnnotationsList.iterator();
        }

        assertSame(annotationWithRefToDummyB, annotationIt.next());
        assertFalse(annotationWithRefToDummyB.hasSpanNode());
        assertFalse(annotationWithRefToDummyB.isSpanNodeValid());
        assertTrue(annotationWithRefToDummyB.hasFieldValue());
        assertSame(dummyAnnotationForB, ((AnnotationReference) annotationWithRefToDummyB.getFieldValue()).getReference());

        assertSame(annotationWithStruct, annotationIt.next());
        assertFalse(annotationWithStruct.hasSpanNode());
        assertFalse(annotationWithStruct.isSpanNodeValid());
        assertTrue(annotationWithStruct.hasFieldValue());
        assertSame(struct, annotationWithStruct.getFieldValue());
        assertSame(dummyAnnotationForB, ((AnnotationReference) struct.getFieldValue(refToDummyField)).getReference());

        assertSame(annotationWithRefToRefToDummyB, annotationIt.next());
        assertFalse(annotationWithRefToRefToDummyB.hasSpanNode());
        assertFalse(annotationWithRefToRefToDummyB.isSpanNodeValid());
        assertTrue(annotationWithRefToRefToDummyB.hasFieldValue());
        assertSame(annotationWithRefToDummyB, ((AnnotationReference) annotationWithRefToRefToDummyB.getFieldValue()).getReference());

        assertSame(dummyAnnotationForB, annotationIt.next());
        assertTrue(dummyAnnotationForB.hasSpanNode());
        assertFalse(dummyAnnotationForB.isSpanNodeValid());
        assertFalse(dummyAnnotationForB.hasFieldValue());

        assertFalse(annotationIt.hasNext());


        //cleaning up tree!!
        tree.cleanup();

        assertEquals(1, tree.numAnnotations());
        assertTrue(a.isValid());
        assertFalse(b.isValid());
        assertTrue(c.isValid());
        assertEquals(1, a.numChildren());

        assertFalse(dummyAnnotationForB.hasSpanNode());
        assertFalse(dummyAnnotationForB.isSpanNodeValid());
        assertFalse(dummyAnnotationForB.hasFieldValue());

        assertFalse(annotationWithRefToDummyB.hasSpanNode());
        assertFalse(annotationWithRefToDummyB.isSpanNodeValid());
        assertFalse(annotationWithRefToDummyB.hasFieldValue());

        assertFalse(annotationWithRefToRefToDummyB.hasSpanNode());
        assertFalse(annotationWithRefToRefToDummyB.isSpanNodeValid());
        assertFalse(annotationWithRefToRefToDummyB.hasFieldValue());

        annotationIt = tree.iterator();
        assertSame(annotationWithStruct, annotationIt.next());
        assertFalse(annotationWithStruct.hasSpanNode());
        assertFalse(annotationWithStruct.isSpanNodeValid());
        assertTrue(annotationWithStruct.hasFieldValue());
        assertSame(struct, annotationWithStruct.getFieldValue());
        assertNull(struct.getFieldValue(refToDummyField));

        assertFalse(annotationIt.hasNext());
    }
Tests iterating through E's annotations in a tree.
document/src/test/java/com/yahoo/document/annotation/SpanTreeTestCase.java