docs: function loadAggregate(ARConstructor, ARID, eventSink, snapshotter, cacher){
  	// Determine the aggregate type. The snapshot loader and/or the rehydrator (sink) may need this to find the data.
  	var aggregateType = ARConstructor.prototype._aggregateType;
  	// Function definitions for later use in loadAggregate:
  	// Aggregate construction.
  	function constructAggregate(){
  		var ARObject = new ARConstructor();
  		ARObject.setAggregateID(ARID);
  		ARObject.setEventSink(eventSink);
  		// If no snapshotter has been passed (or is not needed/used), instead of complicating logic, we simply replace it locally with a stub that knows no aggregates and rejects all loads.
  		//  This happens in constructAggregate since it relies on the AR object existing.
  		if(!snapshotter || !ARObject.supportsSnapshotApplication()){
  			snapshotter = new NoOpSnapshotter();
  		}
  		ARObject.setSnapshotter(snapshotter);
  		return ARObject;
  	}
  	
  	var cacheProvider = cacher || new NoOpCacher();
  	
  	// Rehydration. It will resolve the top-level promise for us, so that there is no need to call anything else to finish the loading.
  	function rehydrateAggregate(ARObject){
  		return when.try(eventSink.rehydrate.bind(eventSink), ARObject, ARID, ARObject.getNextSequenceNumber());
  	}
  	
  	// Nominal loading function - in case the aggregate is not in the aggregate cache:
  	function nominalLoad(){
  		// Actual retrieval/construction/rehydration:
  		var ARObject = constructAggregate();
  		return when.try(snapshotter.loadSnapshot.bind(snapshotter), aggregateType, ARID).then(function _applySnapshot(snapshot){
  			// A snapshot has been found and loaded, so let the AR apply it to itself, according to its internal logic.
  			return when.try(ARObject.applySnapshot.bind(ARObject), snapshot);
  		}, function _snapshotNonexistent(){
  			// This function intentionally does nothing. It simply turns a rejection from loadSnapshot() into a resolution.
  		}).then(rehydrateAggregate.bind(undefined, ARObject)).then(function(){
  			return ARObject;
  		});
  	}
  	
  	// If the aggregate instance is in the cache, we can use a much simpler procedure.
  	function cacheLoad(){
  		return cacheProvider.getAggregateInstance(aggregateType, ARID);
  	}
  	
  	// Finally, put the defined procedures to action:
  	var instance = cacheLoad();
  	if(instance){
  		// We've got what we came for: a ready instance.
  		return when.resolve(instance);
  	}
  	else{
  		return nominalLoad().then(function(loadedAggregate){
  			// Now that the aggregate has been (tediously) loaded from our store, ask the cacher to cache it for further use.
  			cacheProvider.cacheAggregateInstance(loadedAggregate);
  			return loadedAggregate;
  		});
  	}
  }