Add streaming and refactor and tests