refactored to state pattern