implement state machine