public static String removeOverlap(String originalText, String suggestion) {
        if (CommonUtils.isEmpty(suggestion) || CommonUtils.isEmpty(originalText)) {
            return suggestion;
        }

        String endOfOriginal = originalText.length() <= 20 ?
            originalText : originalText.substring(originalText.length() - 20);

        endOfOriginal = endOfOriginal.replaceAll("\\s+", " ").toLowerCase();
        String cleanSuggestion = suggestion.replaceAll("\\s+", " ");

        for (int length = Math.min(endOfOriginal.length(), cleanSuggestion.length()); length > 0; length--) {
            if (endOfOriginal.length() >= length) {
                String endSubstring = endOfOriginal.substring(endOfOriginal.length() - length);
                if (cleanSuggestion.toLowerCase().startsWith(endSubstring)) {
                    return cleanSuggestion.substring(length).trim();
                }
            }
        }

        return suggestion;
    }
Converts a widget offset to a corresponding model offset in the text viewer.

@param viewer       the text viewer from which the widget offset is taken
@param widgetOffset the offset in the widget
@return the corresponding model offset in the viewer
plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/suggestion/TextRenderingUtils.java