code: func (sm *StateMachine) SetState(in *Msg, label string) string {
  	desiredState := sm.states[label]
  
  	// If we're in a state beyond the desired state, go back. There are NO
  	// checks for state when going backward, so if you're changing state
  	// after its been completed, you'll need to do sanity checks OnEntry.
  	if sm.state > desiredState {
  		sm.state = desiredState
  		sm.stateEntered = false
  		sm.plugin.SetMemory(in, StateKey, desiredState)
  		sm.plugin.SetMemory(in, stateEnteredKey, false)
  		return sm.Handlers[desiredState].OnEntry(in)
  	}
  
  	// If we're in a state before the desired state, go forward only as far
  	// as we're allowed by the Complete guards.
  	for s := sm.state; s < desiredState; s++ {
  		ok, _ := sm.Handlers[s].Complete(in)
  		if !ok {
  			sm.state = s
  			sm.stateEntered = false
  			sm.plugin.SetMemory(in, StateKey, s)
  			sm.plugin.SetMemory(in, stateEnteredKey, false)
  			return sm.Handlers[s].OnEntry(in)
  		}
  	}
  
  	// No guards were triggered (go to state), or the state == desiredState,
  	// so reset the state and run OnEntry again unless the plugin is now
  	// complete.
  	sm.state = desiredState
  	sm.stateEntered = false
  	sm.plugin.SetMemory(in, StateKey, desiredState)
  	sm.plugin.SetMemory(in, stateEnteredKey, false)
  	return sm.Handlers[desiredState].OnEntry(in)
  }
docs: // SetState jumps from one state to another by its label. It will safely jump
  // forward but NO safety checks are performed on backward jumps. It's therefore
  // up to the developer to ensure that data is still OK when jumping backward.
  // Any forward jump will check the Complete() function of each state and get as
  // close as it can to the desired state as long as each Complete() == true at
  // each state.