refactor code to make it more general and easier to change