@Override public void remove(FilterBypass fb,
                                         int          offset,
                                         int          length)
                                  throws BadLocationException {
                int caret = getCaret().getDot();
                int mark = getCaret().getMark();
                String buffer = getText();
                String newContent = buffer.substring(0, offset)
                        + buffer.substring(offset + length);
                ChoiceMatch match = getBestMatch(newContent);
                if (match.content == null) {
                    return;
                }

                String proposal = match.content.toString();
                // on text content, this comparator cannot be null
                Comparator<String> cmp = popup.getStringComparator();
                if (!match.exact || (0 != cmp.compare(newContent, proposal))) {
                    if (
                        ChoiceMatch.getMatchingLength(proposal, newContent, cmp)
                            <= ChoiceMatch.getMatchingLength(buffer, newContent,
                                cmp)) {
                        proposal = buffer;
                    }
                }

                // special case if the removal is due to BACK SPACE
                AWTEvent ev = EventQueue.getCurrentEvent();
                if ((ev instanceof KeyEvent)
                        && (((KeyEvent) ev).getKeyCode()
                            == KeyEvent.VK_BACK_SPACE)) {
                    if (caret > mark) {
                        caret = mark;
                    } else if (Strings.areSameInstance(buffer, proposal)) {
                        --caret;
                    } else if (caret == mark) {
                        caret = offset;
                    }
                }

                if ((0 == caret) && Strings.areSameInstance(buffer, proposal)) {
                    // remove all text in this case
                    match.content = CustomChoice.MATCH_ALL;
                    proposal = match.content.toString();
                }

                if (!Strings.areSameInstance(buffer, proposal)) {
                    super.replace(fb, 0, buffer.length(), proposal, null);
                }

                int len = proposal.length();
                setCaretPosition(len);
                moveCaretPosition(Math.min(len, caret));
                deactivateCustomDecoration();

                if (userUpdate && instantFiltering && !Strings.areSameInstance(proposal, buffer)) {
                    match.exact = true;
                    updateFilter(proposal, match, true);
                }
            }
@Override public void remove(FilterBypass fb,
                                         int          offset,
                                         int          length)