Refactor to take input/output streams as arguments