refactoring + little more metaprogramming