refactor state pattern