fsm implementation