docs: function Saga(){
  	// Decouple all properties from the prototype by calling the "parent" constructor.
  	EventSourcedAggregate.call(this);
  	// Create some storage for: transition definitions, current event space (the set of events expected for any transition).
  	this._currentState = '_';
  	/**
  	 * The list of transitions which are possible from here. Contains copies of remaining events, so that they can be removed until all are (and a transition is initiated).
  	 */
  	this._possibleTransitions = [];
  	/**
  	 * A map of all processed event IDs for duplicate avoidance.
  	 */
  	this._processedEventIDs = {};
  	
  	var self = this;
  	function applyTransition(transitionMetadata){
  		console.log('Saga.applyTransition');
  		// Change the state.
  		self._currentState = transitionMetadata.newState;
  		// Register the event as seen, just like in the "hold" case.
  		self._processedEventIDs[transitionMetadata.eventID] = true;
  		// Reset the current events, so that a new transition may take place later.
  		self._currentEvents = [];
  		// Copy the transition definitions to the current transition cache and do other cleanup work.
  		refreshState();
  	}
  	
  	// Helper function: copy the transitions and their events to a new, unshared store.
  	function refreshState(){
  		self._possibleTransitions = [];
  		for(var transitionIndex = 0; transitionIndex < self._states[self._currentState].transitions.length; ++transitionIndex){
  			var transition = self._states[self._currentState].transitions[transitionIndex];
  			// Initialize the new variable that we'll push() onto _possibleTransitions later.
  			var possibleTransition = {
  				destination: transition.destination,
  				action: transition.action,
  				outputEventType: transition.outputEventType,
  				remainingEvents: []
  			};
  			// Populate the list of remaining events that will be subsequently decreased, until it hits a count of zero, at which point this particular transition takes place.
  			for(var eventIndex = 0; eventIndex < transition.requiredEvents.length; ++eventIndex){
  				// Place the event specification into the list of remaining events.
  				var event = transition.requiredEvents[eventIndex];
  				possibleTransition.remainingEvents.push(event);
  			}
  			// Now that the transition specification is complete, add it to the list of transitions possible from the current state.
  			self._possibleTransitions.push(possibleTransition);
  			// Additionally, if the spec contained an outputEventType (which overrides SagaStateTransitioned for initiating transitions), register a handler for that event type.
  			if(possibleTransition.outputEventType){
  				// Duplicate handlers are checked, in order to avoid double state refresh (which would result in excessive event handler populations -> memory leak via avalanche effect after a few transitions).
  				//  This check is somewhat strange due to EventEmitter's listener function wrapping when using once().
  				if(!self.listeners(possibleTransition.outputEventType).some(function(listenerFunction){ return listenerFunction === applyTransition || listenerFunction.listener === applyTransition; })){
  					// The listener is not yet present, so add it.
  					self.once(possibleTransition.outputEventType, applyTransition);
  				}
  			}
  		}
  	};
  	
  	// Call the state refresher initially, so that the current transition list is initialized properly.
  	// BUG: "this" is set to undefined in the function. WTF?
  	refreshState.call(this);
  	
  	// Set up an event handler to facilitate state transitions.
  	this.on('SagaEventPutOnHold', function(eventEnvelope){
  		// Add the event to the waiting line.
  		this._currentEvents.push(eventEnvelope);
  		this._processedEventIDs[eventEnvelope.eventID] = true;
  	});
  	// Set up a listener to refresh our listeners etc. when a state transition occurs (generic event only).
  	this.on('SagaStateTransitioned', applyTransition);
  }