refactored to use promises instead of callbacks