factored to support promise
promise and some refactoring