version 2, broke into macro plus helper functions