#' @export
latregBIRT=function(formula,X,object, method=c("posterior","Croon"),nboot=1000){
  method=match.arg(method)
  pairwise=any(is.na(X))
  mcmc.object=object$mcmc
  if(!is.matrix(X)) stop("X needs to be a matrix with column names corresponding to the predictors in 'formula'")
  if((all.vars(formula[[1]])!="~") | (!inherits(formula, "formula"))) stop("invalid formula, provide a formula in the form: ~VAR1+VAR2+VAR3, where VAR1-VAR3 refer to variables in X")
  if(!all(all.vars(formula[[2]])%in%colnames(X))) stop("all predictors from 'formula' should have corresponding column names in matrix X")

  theta_post=rstan::extract(mcmc.object,"theta")$theta
  N=ncol(theta_post)
  npar=length(all.vars(formula[[2]]))
  X=X[,all.vars(formula[[2]]),drop=FALSE]

  if(method=="posterior"){
    EAP=colMeans(theta_post)
    sds=apply(theta_post,2,stats::sd)
    r=stats::var(EAP)/(stats::var(EAP)+(sds^2))
    f=(stats::var(EAP)+(sds^2))
    covX=stats::cov(X,use="p")
    b=matrix(,nrow(theta_post),npar*2)

    for(jj in 1:nrow(theta_post)){
      y=theta_post[jj,]
      all=cbind(y,X)

      mu=matrix(colMeans(all),N,npar+1,TRUE)
      if(pairwise) corcov=cov_pairwise(all,r) else
        corcov=1/(N-1)*t(all-mu)%*%diag(1/r)%*%((all-mu))
      diag(corcov)[1]=1/(N-1)*sum((y-mean(y))^2/r^2-f*(1-r)/r)

      covXY=corcov[-1,1]
      ests=solve(covX)%*%covXY
      df=N - npar

      sig2= 1/df*(corcov[1,1]-t(ests)%*%covX%*%ests)
      samp_var=(df * sig2[1])/stats::rchisq(1, df)
      avar=samp_var*solve(covX)

      b[jj,1:npar]=MASS::mvrnorm(1,ests,avar)
      b[jj,(npar+1):(2*npar)]=sqrt(diag(avar))
    }
    output0=t(matrix(colMeans(b[,1:npar,drop=FALSE])))
    output0=rbind(output0,apply(b[,1:npar,drop=FALSE],2,stats::sd))
    rownames(output0)=c("mean","sd")
    output0=rbind(output0,apply(b[,1:npar,drop=FALSE],2,stats::quantile,prob=c(.025,.25,.50,.75,.975)))
    colnames(output0)=colnames(X)
    ests=rbind(NA,b)
    colnames(ests)=c(colnames(X),paste0("sd_",colnames(X)))
  }
  if(method=="Croon"){
    ests=matrix(,nboot+1,npar)
    EAPm=colMeans(theta_post)
    EAPs=apply(theta_post,2,stats::sd)
    for(ii in 0:nboot){
      if(ii>0) select=sample(1:N,replace=TRUE) else select=1:N

      y=EAPm[select]
      sds=EAPs[select]

      all=cbind(y,X[select,,drop=FALSE])

      r=stats::var(y)/(stats::var(y)+(sds^2))
      f=(stats::var(y)+(sds^2))

      mu=matrix(colMeans(all),N,npar+1,TRUE)
      if(pairwise) corcov=cov_pairwise(all,r) else
        corcov=1/(N-1)*t(all-mu)%*%diag(1/r)%*%((all-mu))
      diag(corcov)[1]=1/(N-1)*sum((y-mean(y))^2/r^2-f*(1-r)/r)

      covX=stats::cov(all[,-1,drop=FALSE],use="p")
      covXY=corcov[-1,1]
      b=solve(covX)%*%covXY
      ests[ii+1,]=t(b)
    }
    se_ests=apply(ests[-1,,drop=FALSE],2,stats::sd)
    output0=rbind(ests[1,,drop=FALSE],se_ests)
    rownames(output0)=c("est","se")
    colnames(ests)=colnames(X)
    colnames(output0)=colnames(X)
    }

  results=list(output=output0,samples=ests[-1,])
  class(results)="latregBIRT"
  return(results)
}


