refactored into a separate library