controllerManager.init(ctrlCtx).then(function afterLoadingControllers(ctrlManager){
			
			//TODO make isForceGeneration this thread-safe(?)
			var usePrecompiledViewsVal = isForceGeneration? 'false' : 'true';
			configurationManager.set('usePrecompiledViews', usePrecompiledViewsVal);
			
			var callback = cbFunc, isForceGeneration = isForceGen;
			
			controllerManager = ctrlManager;
			
			//FIX: halt execution -> do not allow to continue, in case a template file could not be read!
			var isError = false;
			var errorList = [];
			var originalAjax = $.ajax;
			$.ajax = function(options){
				var originalErrorFunc = options.error;
				options.error = function(loadContext, status, exc){
					if(originalErrorFunc){
						originalErrorFunc(exc);
					}
					
					//ignore errors for reading checksum-files:
					if(new RegExp('\\'+checksumUtils.getFileExt()+'$', 'i').test(this.url)){
						return;
					}
					
//					console.log('Standalone-Template-Parser.ajax-shim: '+(exc.stack?exc.stack:exc));
//					console.error('Standalone-Template-Parser.ajax-shim ERROR for URL: '+options.url);
//					throw(exc);
					errorList.push(exc);
					isError = true;
				};
				return originalAjax(options);
			};
			
			//do trigger loading of the template files (*.ehtml) by requesting the PresentationManager instance:
		    var pm = require('mmirf/presentationManager');
		    pm.init().then(function(){

				if(isError){
					var msg = ' Details: \n';
					for(var err_i in errorList){
						var error = errorList[err_i];
						msg += (error.stack ? error.stack : error.toString()) + '\n';
					}
					throw(new Error('Encountered errors while reading templates files: abort parsing!'+msg));
				}
			    
			    console.log('--------------------------------------------- finished parsing *.ehtml templates --------------------------------');
			    
			    var storageBasePath = compiledViewGenPath;
			    
			    var View = require('mmirf/view');
			    var Partial = require('mmirf/partial');
			    var Layout = require('mmirf/layout');
			    
//			    console.log(' \n ');
//			    console.log(
//			    	'--------------------------- writing to "'
//			    		+storageBasePath
//			    		+'" compiled *.ehtml templates (as JavaScript files)...'
//			    		+' --------------------------'
//			    );
			    
			    var wroteFileCounter = 0;

				// stringify and store the views, ie. store "compiled" views
				var utils = commonUtils;
			    var partialPrefix = utils.getPartialsPrefix();
			    var isPartialView = function(name){
			    	return name.charAt(0) == partialPrefix;
			    };
			    var regExprFileExt = /\.ehtml$/igm;
			    
			    var constants = require('mmirf/constants');
			    
				var viewList = utils.listDir('views');
				
				//prepare view-list and compute total count of views that will be compiled
				var counter = 0;
				var unchangedCounter = 0;
				var total = 0;
				for(var i=0, size=viewList.length; i < size; ++i){
					
					var name = viewList[i];
					
					if(!name){
						continue;
					}
					
					var views = utils.listDir('views/'+name);
					
					viewList[i] = {
						name: name,
						views: views
					};
					
					for(var j=0, jsize=views.length; j < jsize; ++j){
						
						if(views[j]){
							++total;
						}
					}
				}
			    
				for(i=0, size=viewList.length; i < size; ++i){
					
					var viewEntry = viewList[i];
					var name = viewEntry.name;
					
					if(!name){
						console.error('Invalid view-directory at views/['+i+']!');
						continue;
					}
					
					var views = viewEntry.views;
					
					if(!views){
						console.info('Found non-directory entry (i.e. file) in views/['+i+']: "'+name+'"');
						continue;
					}
					
					var isLayout = false;
					var ctrlName;
					if(name === 'layouts'){
						isLayout = true;
					}
					else {
						ctrlName = name.charAt(0).toUpperCase() + name.substring(1);
					}
					
					for(j=0, jsize=views.length; j < jsize; ++j){
						
						var viewFileName = views[j];
						
						if(!viewFileName){
							console.error('Invalid view-name at views/'+name+'/['+j+']!');
							continue;
						}
						
						var viewName;
						if(! regExprFileExt.test(viewFileName) ){
							console.warn('Unknown file-extension for view in directory-structure at views/'+name+'/'+viewFileName);
							viewName = viewFileName;
						}
						else {
							//remove file extension ".ehtml"
							viewName = viewFileName.substring(0, viewFileName.length - 6);
						}
						regExprFileExt.lastIndex = 0;
						
						console.log('  processing view (ehtml) at views/'+name+'/'+viewName+'...');
						
						var isPartial = isPartialView(viewName);
						
						var view;
						if( isLayout ){
							//layouts are specific to controllers, so the layout's lookup-key is actually the controller-name
							// --> "convert" layout name to controller-name format (i.e. first letter to upper case)
							var layoutKey = viewName.charAt(0).toUpperCase() + viewName.substring(1);
							view = pm.getLayout(layoutKey);
						} 
						else if( isPartial ){
							//remove partial's name-prefix:
							var partialName =  viewName.substring(partialPrefix.length);
							view = pm.getPartial(ctrlName, partialName);
						}
						else {
							view = pm.getView(ctrlName, viewName);
						}
						
						++counter;
						
						if(!view){
							
							console.error('Could not create compiled view '+(isLayout? '(layout) ':' ')+(isPartial? '(partial) ':' ')+'for '+ctrlName+'/'+viewName);
							
							if(counter === total) callback && callback();
							
							continue;
						}
						
						var stringifiedView = view.stringify();
						var path = storageBasePath + 'views/'+name+'/'+viewName;
						
						var viewEHtmlPath = constants.getViewPath()+name+'/'+viewName + '.ehtml';

						var rawViewContent = loadLocalFile(viewEHtmlPath, 'text');
						
						if(!isForceGeneration && !_isNeedCompile(rawViewContent, path + '.js', path, true)){
							
							++unchangedCounter;
							
							if(isDebugOutput) console.log('----------------------------------- did nothing: view is unchanged! ---------------------------');
							
							if(counter === total) callback && callback();
							
							continue;
							
						} else if(isForceGeneration && !_isNeedCompile(rawViewContent, path + '.js', path, true)){
							
							//if generation is forced, but the content seems unchanged, then the compiled view was loaded
							// -> force re-compiling the source (ehtml) file, before continuing:
							if( isLayout ){
								view = new Layout(view.getName(), rawViewContent, view.remoteaccess, true);
							} 
							else if( isPartial ){
								view = new Partial(view.getController(), view.getName(), rawViewContent);
							}
							else {
								view = new View(view.getController(), view.getName(), rawViewContent);
							}
							
							stringifiedView = view.stringify();
						}

						var wasWritten = saveToFile(stringifiedView, path + '.js');
						if(wasWritten){
							
							++wroteFileCounter;

							//create checksum files to be used on loading pre-compiled templates
							// (in order to check up-to-date status)
							var digestContent = checksumUtils.createContent(rawViewContent);
							saveToFile(digestContent, path + checksumUtils.getFileExt());

							if(counter === total) callback && callback();
							
						} else {
							
							console.error('Could not store compiled view at '+path + '.js');

							if(counter === total) callback && callback();	
						}
						
					}//END: for( view-subdir-list )
					
				}//END: for( views-list )

				console.log('  ----');
				console.log('  processed views (updated / total): '+ (total-unchangedCounter)+ ' / ' + total);
				console.log('  wrote '+wroteFileCounter+' file(s) to '+storageBasePath);
				console.log('----------------------------------------------- finished processing views ---------------------------------------\n');
				
		    });//END:  presentationManager.init().then(...
		    
		});//END: afterLoadingControllers()
		
//after initializing:
//  re-enable log-messages for parsing templates
console.log = consoleLogImpl;
console.debug = consoleDebugImpl;
//for ANT it makes no difference, if messages are written into the std-out or err-out
//		-> "normalize" messages into std-out 
//		(-> this avoids synchronization problems when both streams are displayed in same output stream)
console.info  = console.log;
console.warn  = console.log;
console.error = console.log;

var configurationManager = require('mmirf/configurationManager');

//force view-generation (i.e. disable change-check for compiled views)
configurationManager.set('usePrecompiledViews', 'false');

console.log('------------------------------------- completed initialization, start parsing *.ehtml files... -------------------');

var controllerManager = require('mmirf/controllerManager');

//modify loadImpl-function, so that stub Controllers are loaded instead of actual controllers
//(for creating template JS code, the controllers are not really required, only the paths etc. they contain for loading
//the templates)
var constants = require('mmirf/constants');

var Helper = require('mmirf/helper');
var Controller = require('mmirf/controller');
Controller.prototype.__loadHelper = Controller.prototype.loadHelper;
Controller.prototype.loadHelper = function(name, helperPath){