#8 moved core functionality to a standalone library