private void selectAndPossiblyCenter(JTextComponent component, int start,
                                         int end) {
        component.setSelectionStart(start);
        component.setSelectionEnd(end);

        Rectangle r = null;
        try {
            r = component.modelToView(start);
            if (r == null) { // Not yet visible; i.e. JUnit tests
                return;
            }
            if (end != start) {
                r = r.union(component.modelToView(end));
            }
        } catch (BadLocationException ble) { // Never happens
            ble.printStackTrace();
            component.setSelectionStart(start);
            component.setSelectionEnd(end);
            return;
        }

        Rectangle visible = component.getVisibleRect();

        // If the new selection is already in the view, don't scroll,
        // as that is visually jarring.
        if (visible.contains(r)) {
            component.setSelectionStart(start);
            component.setSelectionEnd(end);
            return;
        }

        visible.x = r.x - (visible.width - r.width) / 2;
        visible.y = r.y - (visible.height - r.height) / 2;

        Rectangle bounds = component.getBounds();
        Insets i = component.getInsets();
        bounds.x = i.left;
        bounds.y = i.top;
        bounds.width -= i.left + i.right;
        bounds.height -= i.top + i.bottom;

        if (visible.x < bounds.x) {
            visible.x = bounds.x;
        }

        if (visible.x + visible.width > bounds.x + bounds.width) {
            visible.x = bounds.x + bounds.width - visible.width;
        }

        if (visible.y < bounds.y) {
            visible.y = bounds.y;
        }

        if (visible.y + visible.height > bounds.y + bounds.height) {
            visible.y = bounds.y + bounds.height - visible.height;
        }

        component.scrollRectToVisible(visible);
    }