private boolean removeObsoleteReferencesFromFieldValue(FieldValue value, Map<Annotation, Annotation> selectedAnnotations, boolean removeIfPresent) {
        if (value == null) {
            return false;
        }

        if (value.getDataType() instanceof AnnotationReferenceDataType) {
            AnnotationReference ref = (AnnotationReference) value;
            if (removeIfPresent) {
                if (selectedAnnotations.containsValue(ref.getReference())) {
                    //this reference refers to a dead annotation
                    ref.setReference(null);
                    return true;
                }
            } else {
                if (!selectedAnnotations.containsValue(ref.getReference())) {
                    //this reference refers to a dead annotation
                    ref.setReference(null);
                    return true;
                }
            }
        } else if (value.getDataType() instanceof StructuredDataType) {
            removeObsoleteReferencesFromStructuredType((StructuredFieldValue) value, selectedAnnotations, removeIfPresent);
        } else if (value.getDataType() instanceof CollectionDataType) {
            removeObsoleteReferencesFromCollectionType((CollectionFieldValue) value, selectedAnnotations, removeIfPresent);
        } else if (value.getDataType() instanceof MapDataType) {
            removeObsoleteReferencesFromMapType((MapFieldValue) value, selectedAnnotations, removeIfPresent);
        }
        return false;
    }
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