public void cleanup() {
        Map<Annotation, Annotation> removedAnnotations = removeAnnotationsThatPointToInvalidSpanNodes();

        //here:
        //iterate through all annotations;
        //if any of those have ONLY an annotationreference as its value,
        //    - null reference
        //    - remove value from annotation
        //    - remove annotation and add it to removedAnnotations map
        if (!removedAnnotations.isEmpty()) {
            Iterator<Annotation> annotationIt = iterator();
            while (annotationIt.hasNext()) {
                Annotation a = annotationIt.next();
                if (!a.hasFieldValue()) {
                    continue;
                }
                FieldValue value = a.getFieldValue();

                if (value instanceof AnnotationReference ref) {
                    //the annotation "a" has a reference
                    if (removedAnnotations.get(ref.getReference()) != null) {
                        //this reference refers to a dead annotation
                        ref.setReference(null);
                        a.setFieldValue(null);
                        if (!a.isSpanNodeValid()) {
                            //this annotation has no span node, delete it
                            annotationIt.remove();
                            removedAnnotations.put(a, a);
                        }
                    }
                }
            }
        }

        //there may still be references to removed annotations,
        //inside maps, weighted sets, structs, etc.
        //if any of those have such references,
        //   - null reference
        //   - remove annotationref from struct, map, etc.
        //   - apart from this, keep struct, map etc. and annotation
        if (!removedAnnotations.isEmpty()) {
            for (Annotation a : this) {
                if (!a.hasFieldValue()) {
                    continue;
                }
                removeObsoleteReferencesFromFieldValue(a.getFieldValue(), removedAnnotations, true);
            }
        }
        //was any annotations removed from the global list? do we still have references to those annotations
        //that have been removed? if so, remove the references
        removeAnnotationReferencesThatPointToRemovedAnnotations();
    }
Ensures consistency of the tree in case SpanNodes have been removed, and there are still
Annotations pointing to them. This method has a maximum upper bound of O(3nm), where n is the
total number of Annotations, and m is the number of SpanNodes that had been removed from the tree.
The lower bound is Omega(n), if no SpanNodes had been removed from the tree.
document/src/main/java/com/yahoo/document/annotation/SpanTree.java