code: func (s *StateSyncer) nextFSMState(fs fsmState) fsmState {
  	switch fs {
  	case fullSyncState:
  		if s.Paused() {
  			return retryFullSyncState
  		}
  
  		err := s.State.SyncFull()
  		if err != nil {
  			s.Logger.Printf("[ERR] agent: failed to sync remote state: %v", err)
  			return retryFullSyncState
  		}
  
  		return partialSyncState
  
  	case retryFullSyncState:
  		e := s.retrySyncFullEvent()
  		switch e {
  		case syncFullNotifEvent, syncFullTimerEvent:
  			return fullSyncState
  		case shutdownEvent:
  			return doneState
  		default:
  			panic(fmt.Sprintf("invalid event: %s", e))
  		}
  
  	case partialSyncState:
  		e := s.syncChangesEvent()
  		switch e {
  		case syncFullNotifEvent, syncFullTimerEvent:
  			return fullSyncState
  
  		case syncChangesNotifEvent:
  			if s.Paused() {
  				return partialSyncState
  			}
  
  			err := s.State.SyncChanges()
  			if err != nil {
  				s.Logger.Printf("[ERR] agent: failed to sync changes: %v", err)
  			}
  			return partialSyncState
  
  		case shutdownEvent:
  			return doneState
  
  		default:
  			panic(fmt.Sprintf("invalid event: %s", e))
  		}
  
  	default:
  		panic(fmt.Sprintf("invalid state: %s", fs))
  	}
  }
docs: // nextFSMState determines the next state based on the current state.