refactored heavily