void onEnd (int stateMask) {
	int lastAvailableIndex = itemsCount - 1;
	if ((stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
		/* End with no modifiers */
		if (focusItem.index == lastAvailableIndex) return; 	/* at bottom */
		CTableItem item = items [lastAvailableIndex]; 
		selectItem (item, false);
		setFocusItem (item, true);
		redrawItem (lastAvailableIndex, true);
		showItem (item);
		Event newEvent = new Event ();
		newEvent.item = item;
		notifyListeners (SWT.Selection, newEvent);
		return;
	}
	if ((getStyle () & SWT.SINGLE) != 0) {
		if ((stateMask & SWT.CTRL) != 0) {
			/* CTRL+End, CTRL+Shift+End */
			int visibleItemCount = (clientArea.height - getHeaderHeight ()) / itemHeight;
			setTopIndex (itemsCount - visibleItemCount);
			return;
		}
		/* Shift+End */
		if (focusItem.index == lastAvailableIndex) return; /* at bottom */
		CTableItem item = items [lastAvailableIndex]; 
		selectItem (item, false);
		setFocusItem (item, true);
		redrawItem (lastAvailableIndex, true);
		showItem (item);
		Event newEvent = new Event ();
		newEvent.item = item;
		notifyListeners (SWT.Selection, newEvent);
		return;
	}
	/* SWT.MULTI */
	if ((stateMask & SWT.CTRL) != 0) {
		if ((stateMask & SWT.SHIFT) != 0) {
			/* CTRL+Shift+End */
			showItem (items [lastAvailableIndex]);
			return;
		}
		/* CTRL+End */
		if (focusItem.index == lastAvailableIndex) return; /* at bottom */
		CTableItem item = items [lastAvailableIndex];
		setFocusItem (item, true);
		showItem (item);
		redrawItem (item.index, true);
		return;
	}
	/* Shift+End */
	if (anchorItem == null) anchorItem = focusItem;
	CTableItem selectedItem = items [lastAvailableIndex];
	if (selectedItem == focusItem && selectedItem.isSelected ()) return;
	int anchorIndex = anchorItem.index;
	int selectIndex = selectedItem.index;
	CTableItem[] newSelection = new CTableItem [selectIndex - anchorIndex + 1];
	int writeIndex = 0;
	for (int i = anchorIndex; i <= selectIndex; i++) {
		newSelection [writeIndex++] = items [i];
	}
	setSelection (newSelection, false);
	setFocusItem (selectedItem, true);
	redrawItems (anchorIndex, selectIndex, true);
	showItem (selectedItem);
	Event newEvent = new Event ();
	newEvent.item = selectedItem;
	notifyListeners (SWT.Selection, newEvent);
}