void headerOnMouseDown (Event event) {
	if (event.button != 1) return;
	CTableColumn[] orderedColumns = getOrderedColumns ();
	int x = -horizontalOffset;
	for (int i = 0; i < orderedColumns.length; i++) {
		CTableColumn column = orderedColumns [i];
		x += column.width;
		/* if close to a resizable column separator line then begin column resize */
		if (column.resizable && Math.abs (x - event.x) <= TOLLERANCE_COLUMNRESIZE) {
			resizeColumn = column;
			resizeColumnX = x;
			return;
		}
		/*
		 * If within column but not near separator line then start column drag
		 * if column is moveable, or just fire column Selection otherwise.
		 */
		if (event.x < x) {
			if (column.moveable) {
				/* open tracker on the dragged column's header cell */
				int columnX = column.getX ();
				int pointerOffset = event.x - columnX;
				headerHideToolTip ();
				Tracker tracker = new Tracker (this, SWT.NONE);
				tracker.setRectangles (new Rectangle[] {
					new Rectangle (columnX, 0, column.width, getHeaderHeight ())
				});
				if (!tracker.open ()) return;	/* cancelled */
				/* determine which column was dragged onto */
				Rectangle result = tracker.getRectangles () [0];
				int pointerX = result.x + pointerOffset;
				if (pointerX < 0) return;	/* dragged too far left */
				x = -horizontalOffset;
				for (int destIndex = 0; destIndex < orderedColumns.length; destIndex++) {
					CTableColumn destColumn = orderedColumns [destIndex];
					x += destColumn.width;
					if (pointerX < x) {
						int oldIndex = column.getOrderIndex ();
						if (destIndex == oldIndex) {	/* dragged onto self */
							Event newEvent = new Event ();
							newEvent.widget = column;
							column.notifyListeners (SWT.Selection, newEvent);
							return;
						}
						int leftmostIndex = Math.min (destIndex, oldIndex);
						int[] oldOrder = getColumnOrder ();
						int[] newOrder = new int [oldOrder.length];
						System.arraycopy (oldOrder, 0, newOrder, 0, leftmostIndex);
						if (leftmostIndex == oldIndex) {
							/* column moving to the right */
							System.arraycopy (oldOrder, oldIndex + 1, newOrder, oldIndex, destIndex - oldIndex);
						} else {
							/* column moving to the left */
							System.arraycopy (oldOrder, destIndex, newOrder, destIndex + 1, oldIndex - destIndex);
						}
						newOrder [destIndex] = oldOrder [oldIndex];
						int rightmostIndex = Math.max (destIndex, oldIndex);
						System.arraycopy (
							oldOrder,
							rightmostIndex + 1,
							newOrder,
							rightmostIndex + 1,
							newOrder.length - rightmostIndex - 1);
						setColumnOrder (newOrder);
						return;
					}
				}
				return;		/* dragged too far right */
			}
			/* column is not moveable */
			Event newEvent = new Event ();
			newEvent.widget = column;
			column.notifyListeners (SWT.Selection, newEvent);
			return;
		}
	}
}