public void remove(Key obj) { optimizeWrites(); VerseRange thatRange = toVerseRange(getVersification(), obj); boolean removed = false; // This allows us to modify store which iterating through a copy Set<Key> newStore = new TreeSet<Key>(); newStore.addAll(store); // go through all the VerseRanges for (Key aKey : newStore) { // if this range touches the range to be removed ... VerseRange thisRange = (VerseRange) aKey; if (thisRange.overlaps(thatRange)) { // ... remove it and add the remainder store.remove(thisRange); VerseRange[] vra = VerseRange.remainder(thisRange, thatRange); for (int i = 0; i < vra.length; i++) { store.add(vra[i]); } removed = true; } } if (removed) { normalize(); } // we do an extra check here because the cost of calculating the // params is non-zero an may be wasted if (suppressEvents == 0) { fireIntervalRemoved(this, thatRange.getStart(), thatRange.getEnd()); } }