Model <-
function(my_formula, data=d, brief=getOption("brief"), xlab=NULL, ...) {


  if (missing(my_formula)) {
    cat("\n"); stop(call.=FALSE, "\n","------\n",
      "Specify a model by listing it first or set according to:  my_formula\n\n")
  }

  # let deprecated mydata work as default
  dfs <- .getdfs()
  if ("mydata" %in% dfs  &&  !("d" %in% dfs)) d <- mydata

  dname <- deparse(substitute(data))  # get data frame name for cor before sort
  options(dname = dname)

  nm <- all.vars(my_formula)  # names of vars in the model
  n.vars <- length(nm)
  n.pred <- n.vars - 1

  if (n.pred < 1) {
    cat("\n"); stop(call.=FALSE, "\n","------\n",
      "Specify at least one predictor variable in the model.\n\n")
  }

  in.data <- nm %in% names(data)
  if (!all(in.data)) {
    cat("\n"); stop(call.=FALSE, "\n","------\n",
      "Variable(s) in the model but not in the data frame ", dname, ": ",
      paste(nm[!in.data], collapse=", "), "\n\n")
  }

  # classify each variable in the model as categorical or numerical
  var.type <- character(length=n.vars)
  n.unique <- integer(length=n.vars)
  for (i in 1:n.vars) {
    v <- data[[nm[i]]]
    if (is.numeric(v)) var.type[i] <- "num"
    else if (is.factor(v) || is.character(v) || is.logical(v))
      var.type[i] <- "cat"
    else var.type[i] <- "other"
    n.unique[i] <- length(unique(na.omit(v)))
  }

  if (any(var.type == "other")) {
    cat("\n"); stop(call.=FALSE, "\n","------\n",
      "Variable(s) in the model not categorical or numerical: ",
      paste(nm[var.type == "other"], collapse=", "), "\n\n")
  }

  if (n.unique[1] < 2) {
    cat("\n"); stop(call.=FALSE, "\n","------\n",
      "The response variable ", nm[1], " needs at least two unique\n",
      "values to model.\n\n")
  }

  all.preds.cat <- all(var.type[2:n.vars] == "cat")

  # route on the analytic structure of the model's variables

  if (var.type[1] == "cat") {  # categorical response

    if (n.unique[1] == 2) {
      cat("\n")
      .dash(60)
      cat("The response variable ", nm[1], " is categorical with two\n",
          "categories, so run Logit Regression analysis.\n", sep="")
      .dash(60)
      cat("\n")
      invisible(Logit(my_formula, data, brief=brief, xlab=xlab, ...))
    }

    else {
      cat("\n"); stop(call.=FALSE, "\n","------\n",
        "The response variable ", nm[1], " is categorical with more than\n",
        "two categories. Models of a multi-category response are not\n",
        "supported.\n\n")
    }
  }

  else {  # numerical response

    y.vals <- na.omit(data[[nm[1]]])

    if (all(y.vals %in% c(0,1))) {  # binary response
      cat("\n")
      .dash(60)
      cat("Run Logit Regression analysis to account for\n",
          "binary response variable ", nm[1], ".\n", sep="")
      .dash(60)
      cat("\n")
      invisible(Logit(my_formula, data, brief=brief, xlab=xlab, ...))
    }

    else if (n.unique[1] == 2) {
      cat("\n"); stop(call.=FALSE, "\n","------\n",
        "The response variable ", nm[1], " is binary, but a numeric\n",
        "binary response can only have values of 0 or 1.\n\n",
        "Use recode() to transform the existing values to 0's and 1's.\n\n")
    }

    else if (all.preds.cat) {

      if (n.pred == 1  &&  n.unique[2] == 2) {  # t-test
        cat("\n")
        .dash(60)
        cat("Predictor variable, ", nm[2], ", has exactly two values.\n",
            "Run the t-test function to compare the corresponding\n",
            "group means of response variable ", nm[1], ".\n", sep="")
        .dash(60)
        cat("\n")
        # ttest() detects a formula from deparse(substitute(x)), so pass
        # the formula value in a re-built call for the tilde to be visible
        tt.cl <- match.call()
        tt.cl[[1L]] <- as.name("ttest")
        names(tt.cl)[names(tt.cl) == "my_formula"] <- "x"
        tt.cl$x <- my_formula
        invisible(eval(tt.cl, parent.frame()))
      }

      else {  # ANOVA
        cat("\n")
        .dash(60)
        cat("Run the ANOVA function to compare the corresponding \n",
            "group means of response variable ", nm[1], ".\n", sep="")
        .dash(60)
        invisible(ANOVA(my_formula, data, brief=brief, ...))
      }
    }  # all preds are categorical

    else {  # numerical or mixed numerical/categorical predictors
      cat("\n")
      .dash(60)
      cat("Run Regression analysis to account for response variable ",
          nm[1], ".\n", sep="")
      .dash(60)
      cat("\n")
      invisible(Regression(my_formula, data, brief=brief, ...))
    }

  }  # dv is numerical

}
