refactor and modularize