refactor to use template