"count.fields" <-
function(file, sep = "", skip = 0)
{
	.Internal(count.fields(file, sep, skip))
}

"read.table" <-
function (file, header=FALSE, sep="", row.names, col.names, as.is=FALSE,
	na.strings="NA", skip=0)
{
	type.convert <-
	function(x, na.strings="NA", as.is=FALSE)
		.Internal(type.convert(x, na.strings, as.is))

		#  basic column counting and header determination
		#  we record whether it looks like we column names
		#  rlabp == 1

	row.lens <- count.fields(file, sep, skip)
	nlines <- length(row.lens)
	rlabp <- 0
	if (nlines > 1 && (row.lens[2] - row.lens[1]) == 1) {
		if (missing(header))
			header <- TRUE
		rlabp <- 1
	}

		# read in the header
	if (header) {
		col.names <- scan(file, what="", sep=sep, nlines=1, quiet=TRUE, skip=skip)
		skip <- skip + 1
		row.lens <- row.lens[-1]
		nlines <- nlines - 1
	}
	else if (missing(col.names))
		col.names <- paste("V", 1:row.lens[1], sep="")

		#  check that all rows have equal lengths

	cols <- unique(row.lens)
	if (length(cols) != 1)
		stop("all rows must have the same length",
			paste(row.lens, sep=","))

		#  set up for the scan of the file
		#  we read all values as character strings
		#  and convert later.

	what <- rep(list(""), cols)
	if (rlabp == 1)
		col.names <- c("row.names", col.names)
	names(what) <- col.names
	data <- scan(file=file, what=what, sep=sep, nlines=nlines, skip=skip,
			na.strings=na.strings, quiet=TRUE)

		#  ok, now we have the data
		#  we now we convert to numeric or factor variables
		#  (depending on the specifies value of "as.is")
		#  we do this here so that columns match up

	cols <- length(data)
	if(is.logical(as.is)) {
		as.is <- rep(as.is, length=cols)
	}
	else if(is.numeric(as.is)) {
		if(any(as.is < 1 | as.is > cols))
			stop("invalid numeric as.is expression")
		i <- rep(FALSE, cols)
		i[as.is] <- TRUE
		as.is <- i
	}
	if (length(as.is) != cols)
		stop("as.is has the wrong length")
	for (i in 1:cols) {
		if (!as.is[i])
			data[[i]] <- type.convert(data[[i]])
	}

		#  now we determine row names

	if (missing(row.names)) {
		if (rlabp == 1) {
			row.names <- data[[1]]
			data <- data[-1]
		}
		else row.names <- as.character(1:nlines)
	}
	else if (is.null(row.names))
		row.names <- as.character(1:nlines)
	else if (is.character(row.names)) {
		if (length(row.names) == 1) {
			rowvar <- (1:cols)[match(col.names, row.names, 0) == 1]
			row.names <- data[[rowvar]]
			data <- data[-rowvar]
		}
	}
	else if (is.numeric(row.names) && length(row.names) == 1) {
		rlabp <- row.names
		row.names <- data[[rlabp]]
		data <- data[-rlabp]
	}
	else stop("invalid row.names specification")

		#  this is extremely underhanded
		#  we should use the constructor function ...
		#  don't try this at home kids

	class(data) <- "data.frame"
	row.names(data) <- row.names
	return(data)
}
