more modular, still need cleanup