refactored to use interfaces