refactored to split base classes