refactored heavily, renamed