vcov_function <- function(f, Q, theta_hat, X, Y, jacobian_args, hessian_args){
  stopifnot(is.numeric(Y), is.vector(Y), is.numeric(X), is.matrix(X),
            is.numeric(Q) || is.list(Q), is.numeric(theta_hat),
            is.vector(theta_hat), is.function(f))
  n <- length(Y)
  p <- length(theta_hat)
  ftheta <- f2ftheta(f, X, n)
  g <- function(theta) (covprod(Q, (Y - ftheta(theta))))^2
  J <- as.matrix(drop(do.call(calculus::jacobian,
                              args = combine_lists(list(f = g, var = unname(theta_hat)),
                                                   jacobian_args))))
  
  psi <- simplify2array(apply(J, MARGIN = 1, FUN = tcrossprod, simplify = FALSE))
  P_psi <- if(is.vector(psi)) as.matrix(sum(psi)) else rowSums(psi, dims = 2)
  
  hess <- do.call(calculus::hessian,
                  args = combine_lists(list(f = g, var = unname(theta_hat), drop = FALSE),
                                       hessian_args))
  P_psi_dot <- apply(colSums(hess), MARGIN = 3, rbind)
  P_psi_dot_inv <- solve(P_psi_dot)
  
  return(P_psi_dot_inv %*% P_psi %*% t(P_psi_dot_inv))
}
