qregression <- 
    function(bws, xeval, tau, quantile, quanterr = NA, quantgrad = NA, quantgerr = NA, ntrain, trainiseval = FALSE, gradients = FALSE,
             timing = NA, total.time = NA, optim.time = NA, fit.time = NA){

        if (missing(bws) || missing(xeval) || missing(tau) || missing(quantile) || missing(ntrain))
            stop("improper invocation of qregression constructor")

        d <- list(
            xbw = bws$xbw,
            ybw = bws$ybw,
            bws = bws,
            xnames = bws$xnames,
            ynames = bws$ynames,
            nobs = nrow(xeval),
            xndim = bws$xndim,
            yndim = bws$yndim,
            xnord = bws$xnord,
            xnuno = bws$xnuno,
            xncon = bws$xncon,
            ynord = bws$ynord,
            ynuno = bws$ynuno,
            yncon = bws$yncon,
            pscaling = bws$pscaling,
            ptype = bws$ptype,
            pcxkertype = bws$pcxkertype,
            puxkertype = bws$puxkertype,
            poxkertype = bws$poxkertype,
            pcykertype = bws$pcykertype,
            puykertype = bws$puykertype,
            poykertype = bws$poykertype,
            xeval = xeval,
            tau = tau,
            quantile = quantile,
            quanterr = quanterr,
            quantgrad = quantgrad,
            quantgerr = quantgerr,
            ntrain = ntrain,
            trainiseval = trainiseval,
            gradients = gradients,
            timing = timing, total.time = total.time,
            optim.time = optim.time, fit.time = fit.time)

        class(d) <- "qregression"

        return(d)
    }

print.qregression <- function(x, digits=NULL, ...){
  cat("\nQuantile regression data: ", x$ntrain, " training points,",
      if (x$trainiseval) "" else paste(" and ", x$nobs, " evaluation points,\n", sep=""),
      " in ", x$xndim + x$yndim, " variable(s)",
      "\n(", x$yndim, " dependent variable(s), and ", x$xndim, " explanatory variable(s))\n\n",
      sep="")
  if (length(x$tau) > 1L)
    cat("Tau values:", paste(format(x$tau, trim = TRUE), collapse = ", "), "\n\n")
  print(matrix(x$ybw,ncol=x$yndim,dimnames=list(paste("Dep. Var. ",x$pscaling,":",sep=""),x$ynames)))

  print(matrix(x$xbw,ncol=x$xndim,dimnames=list(paste("Exp. Var. ",x$pscaling,":",sep=""),x$xnames)))

  cat(genRegEstStr(x))
  cat(genBwKerStrs(x$bws))
  
  cat("\n\n")
  if(!missing(...))
    print(...,digits=digits)
  invisible(x)
}

fitted.qregression <- function(object, ...){
 object$quantile 
}
quantile.qregression <- function(x, ...){ x$quantile }
.npqreg_predict_newdata_to_exdat <- function(object, newdata) {
  if (is.data.frame(newdata) && !is.null(names(newdata))) {
    xnames <- object$bws$xnames
    if (length(xnames)) {
      missing.names <- setdiff(xnames, names(newdata))
      if (length(missing.names))
        stop(sprintf(
          "newdata must contain columns: %s",
          paste(shQuote(xnames), collapse = ", ")
        ), call. = FALSE)
      return(newdata[, xnames, drop = FALSE])
    }
  }
  newdata
}

predict.qregression <- function(object, se.fit = FALSE, ...) {
  se.fit <- npValidateScalarLogical(se.fit, "se.fit")
  dots <- list(...)
  has.formula.route <- !is.null(object$bws$formula)

  if (!is.null(dots$exdat) && !is.null(dots$newdata))
    dots$newdata <- NULL
  if (has.formula.route) {
    if (!is.null(dots$exdat)) {
      dots$newdata <- .npqreg_predict_newdata_to_exdat(object, dots$exdat)
      dots$exdat <- NULL
    } else if (!is.null(dots$newdata)) {
      dots$newdata <- .npqreg_predict_newdata_to_exdat(object, dots$newdata)
    }
  } else {
    if (!is.null(dots$newdata) && is.null(dots$exdat))
      dots$newdata <- .npqreg_predict_newdata_to_exdat(object, dots$newdata)
    if (is.null(dots$exdat) && !is.null(dots$newdata)) {
      dots$exdat <- dots$newdata
      dots$newdata <- NULL
    }
  }
  if (is.null(dots$tau))
    dots$tau <- object$tau
  tr <- do.call(npqreg, c(list(bws = object$bws), dots))
  if(se.fit)
    return(list(fit = fitted(tr), se.fit = se(tr), 
                df = tr$nobs, residual.scale = NA))
  else
    return(fitted(tr))
}

se.qregression <- function(x) { x$quanterr }
gradients.qregression <- function(x, errors = FALSE, ...) {
  errors <- npValidateScalarLogical(errors, "errors")
  gout <- if (!errors) x$quantgrad else x$quantgerr
  if (is.null(gout) || (length(gout) == 1L && is.logical(gout) && is.na(gout)))
    stop(if (!errors)
      "gradients are not available: fit the model with gradients=TRUE"
    else
      "gradient standard errors are not available: fit the model with gradients=TRUE")
  gout
}

summary.qregression <- function(object, ...) {
  cat("\nQuantile Regression Data: ", object$ntrain, " training points,",
      if (object$trainiseval) "" else paste(" and ", object$nobs, " evaluation points,\n", sep=""),
      " in ", object$xndim + object$yndim, " variable(s)",
      "\n(", object$yndim, " dependent variable(s), and ", object$xndim, " explanatory variable(s))\n\n",
      sep="")

  cat(genOmitStr(object))
  if (length(object$tau) > 1L)
    cat("Tau values:", paste(format(object$tau, trim = TRUE), collapse = ", "), "\n\n")

  print(matrix(object$ybw,ncol=object$yndim,dimnames=list(paste("Dep. Var. ",object$pscaling,":",sep=""),object$ynames)))

  print(matrix(object$xbw,ncol=object$xndim,dimnames=list(paste("Exp. Var. ",object$pscaling,":",sep=""),object$xnames)))

  cat(genRegEstStr(object))
  cat(genBwKerStrs(object$bws))
  cat(genTimingStr(object))
  
  cat("\n\n")
}
