counting.sort <- function(x, xmin = min(x, na.rm = TRUE), xmax = max(x, na.rm = TRUE), na.last = NA) {

	if (! is.finite(xmin) || ! is.finite(xmax)) stop("invalid argument")

	if (has.na <- any(ina <- is.na(x))) {
		nas <- x[ina]
		if (length(x) == length(nas))
			return(
				if (is.na(na.last)) integer(0) else x
			)
		x <- x[!ina]
	}

	counts <- integer(xmax - xmin + 1)
	names(counts) <- xmin:xmax

        for (e in x) {
		stopifnot(xmin <= e, e <= xmax)
		counts[e - xmin + 1] <- counts[e - xmin + 1] + 1
	}
	counts <- cumsum(counts)

	y <- integer(length(x))
	for (j in length(x) : 1) {
		y[counts[x[j] - xmin + 1]] <- x[j]
		counts[x[j] - xmin + 1] <- counts[x[j] - xmin + 1] - 1
	}

	if (has.na && ! is.na(na.last))
		y <- if (na.last) c(y, nas) else c(nas, y)

	y
}

as.list(body(counting.sort))
trace(counting.sort, browser, at=6:8)
counting.sort(sample(1:10, size=50, replace=TRUE))
untrace(counting.sort)
