implemented proper FSM