function dispatch(reactorState, actionType, payload) {
	  var logging = reactorState.get('logger');

	  if (actionType === undefined && getOption(reactorState, 'throwOnUndefinedActionType')) {
	    throw new Error('`dispatch` cannot be called with an `undefined` action type.');
	  }

	  var currState = reactorState.get('state');
	  var dirtyStores = reactorState.get('dirtyStores');

	  var nextState = currState.withMutations(function (state) {
	    logging.dispatchStart(reactorState, actionType, payload);

	    // let each store handle the message
	    reactorState.get('stores').forEach(function (store, id) {
	      var currState = state.get(id);
	      var newState = undefined;

	      try {
	        newState = store.handle(currState, actionType, payload);
	      } catch (e) {
	        // ensure console.group is properly closed
	        logging.dispatchError(reactorState, e.message);
	        throw e;
	      }

	      if (newState === undefined && getOption(reactorState, 'throwOnUndefinedStoreReturnValue')) {
	        var errorMsg = 'Store handler must return a value, did you forget a return statement';
	        logging.dispatchError(reactorState, errorMsg);
	        throw new Error(errorMsg);
	      }

	      state.set(id, newState);

	      if (currState !== newState) {
	        // if the store state changed add store to list of dirty stores
	        dirtyStores = dirtyStores.add(id);
	      }
	    });

	    logging.dispatchEnd(reactorState, state, dirtyStores, currState);
	  });

	  var nextReactorState = reactorState.set('state', nextState).set('dirtyStores', dirtyStores).update('storeStates', function (storeStates) {
	    return incrementStoreStates(storeStates, dirtyStores);
	  });

	  return incrementId(nextReactorState);
	}
@param {ReactorState} reactorState
@param {String} actionType
@param {*} payload
@return {ReactorState}