refactor internals to allow more atomicity