You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by jb...@apache.org on 2010/06/26 15:51:23 UTC

svn commit: r958227 - in /commons/sandbox/gsoc/2010/scxml-js/trunk: ./ src/xslt/backends/js/ src/xslt/ir-compiler/ test/ test/conditional_transition/ test/conditional_transition/scripts/ test/kitchen_sink/scripts/

Author: jbeard
Date: Sat Jun 26 13:51:22 2010
New Revision: 958227

URL: http://svn.apache.org/viewvc?rev=958227&view=rev
Log:
Merged branch SCXML-138-139 back into trunk.

Added:
    commons/sandbox/gsoc/2010/scxml-js/trunk/test/conditional_transition/
      - copied from r958221, commons/sandbox/gsoc/2010/scxml-js/branches/core-module.SCXML-137/test/conditional_transition/
    commons/sandbox/gsoc/2010/scxml-js/trunk/test/conditional_transition/TestConditionalTransition.xml
      - copied unchanged from r958221, commons/sandbox/gsoc/2010/scxml-js/branches/core-module.SCXML-137/test/conditional_transition/TestConditionalTransition.xml
    commons/sandbox/gsoc/2010/scxml-js/trunk/test/conditional_transition/TestConditionalTransition_executableContent.xml
      - copied unchanged from r958221, commons/sandbox/gsoc/2010/scxml-js/branches/core-module.SCXML-137/test/conditional_transition/TestConditionalTransition_executableContent.xml
    commons/sandbox/gsoc/2010/scxml-js/trunk/test/conditional_transition/scripts/
      - copied from r958221, commons/sandbox/gsoc/2010/scxml-js/branches/core-module.SCXML-137/test/conditional_transition/scripts/
    commons/sandbox/gsoc/2010/scxml-js/trunk/test/conditional_transition/scripts/unitTest.js
      - copied unchanged from r958221, commons/sandbox/gsoc/2010/scxml-js/branches/core-module.SCXML-137/test/conditional_transition/scripts/unitTest.js
Modified:
    commons/sandbox/gsoc/2010/scxml-js/trunk/   (props changed)
    commons/sandbox/gsoc/2010/scxml-js/trunk/.gitignore
    commons/sandbox/gsoc/2010/scxml-js/trunk/build.js
    commons/sandbox/gsoc/2010/scxml-js/trunk/getDeps.xml
    commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractEnumeratedStatechartGenerator.xsl
    commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractStatechartGenerator.xsl
    commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StatePatternStatechartGenerator.xsl
    commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StatePatternStatechartGenerator_combined.xsl
    commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StateTableStatechartGenerator.xsl
    commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/ir-compiler/flattenTransitions.xsl
    commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/performanceTest.js
    commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/unitTest.js
    commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/unitTest_executableContent.js
    commons/sandbox/gsoc/2010/scxml-js/trunk/test/test_with_xsltproc.sh

Propchange: commons/sandbox/gsoc/2010/scxml-js/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jun 26 13:51:22 2010
@@ -1 +1,3 @@
+/commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-138-139:958222
 /commons/sandbox/gsoc/2010/scxml-js/branches/browser-tests.1.ie:954350-956951
+/commons/sandbox/gsoc/2010/scxml-js/branches/core-module.SCXML-137:957703-958221

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/.gitignore
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/.gitignore?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/.gitignore (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/.gitignore Sat Jun 26 13:51:22 2010
@@ -14,3 +14,4 @@ build_dbg.sh
 tmp*
 Session.vim
 *.bak
+test/out.js

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/build.js
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/build.js?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/build.js (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/build.js Sat Jun 26 13:51:22 2010
@@ -63,7 +63,8 @@ require.def("build",
 
 			var browsers = {
 				"FF" : { host:"localhost", port:4444, browser:"*firefox" , ie:false},
-				"Safari" : { host:"localhost", port:4444, browser:"*safari" , ie: false},
+				//FIXME: latest Safari seems to hang on Windows now under selenium
+				//"Safari" : { host:"localhost", port:4444, browser:"*safari" , ie: false},
 				//FIXME: selenium is unhappy with opera
 				//"Opera" : { host:"localhost", port:4444, browser:"*opera" , ie: false},
 				"IE" : { host:"localhost", port:4444, browser:"*iexplore", ie:true },
@@ -74,7 +75,9 @@ require.def("build",
 			var scxmlTests = {
 				KitchenSink :"test/kitchen_sink/KitchenSink.xml",
 				KitchenSink_performance :"test/kitchen_sink/KitchenSink_performance.xml",
-				KitchenSink_executableContent :"test/kitchen_sink/KitchenSink_executableContent.xml"
+				KitchenSink_executableContent :"test/kitchen_sink/KitchenSink_executableContent.xml",
+				ConditionalTransition :"test/conditional_transition/TestConditionalTransition.xml",
+				ConditionalTransition_executableContent :"test/conditional_transition/TestConditionalTransition_executableContent.xml"
 			}
 
 			//FIXME: this violates Don't Repeat Yourself; these paths are written here and in the module
@@ -94,24 +97,17 @@ require.def("build",
 
 			var pathToPreprocessScript = "src/xslt/util/preprocess_import.xsl"
 
+			//TODO: fix performanceTestScripts to requirejs, as is now done with unitTestScripts
 			var performanceTestScripts = [ 
-				{ 
-					path : "test/kitchen_sink/scripts/performanceTest.js",
-					scxmlTest : scxmlTests.KitchenSink_performance		//back-link
-				}
+				"test/kitchen_sink/scripts/performanceTest"
 			]
 
 
 			var unitTestScripts = [
-				{ 
-					path : "test/kitchen_sink/scripts/unitTest.js",
-					scxmlTest : scxmlTests.KitchenSink		//back-link
-				},
-				{ 
-					path : "test/kitchen_sink/scripts/unitTest_executableContent.js",
-					scxmlTest : scxmlTests.KitchenSink_executableContent		//back-link
-				}
-				
+					"test/kitchen_sink/scripts/unitTest",
+					"test/kitchen_sink/scripts/unitTest_executableContent",
+					"test/conditional_transition/scripts/unitTest",
+					"test/conditional_transition/scripts/unitTest"
 			]
 
 			//gets populated at run-time
@@ -237,9 +233,8 @@ require.def("build",
 								for (scxmlTest in scxmlTests) 
 								for (backend in backends)];
 
-					(function compileTarget(compileTargetsList){
-						var target = compileTargetsList.pop();
-						if(target){
+					tailRecurse(compileTargets,
+						function(target,step){
 							//do action
 
 							//run the build script on the test
@@ -314,20 +309,13 @@ require.def("build",
 											utilFile.writeFile(sc,fpath); 
 
 											//recursive callback
-											compileTarget(compileTargetsList);
+											step();
 										}
 									)
 								}
 							)
-
-						}else{
-							//base case
-							if(compilerCallback){
-								compilerCallback();
-							}
-						}
-
-					})(compileTargets);
+						},
+						compilerCallback);
 
 				},
 
@@ -336,41 +324,45 @@ require.def("build",
 
 						print("Generating html test files...");
 
-						testScripts.forEach(function(testScript){
-							var testScriptPath = testScript.path;
-							var testScriptRelativePath = "../" + testScriptPath;
-
-							scriptsGenerated.
-								filter(function(s){return scxmlTests[s.scxmlTest] == testScript.scxmlTest}).
-								forEach(function(generatedScript){
-								
-								//FIXME: this may need to be refactored
-								var testHtml = htmlGenFn(generatedScript.name,testScriptRelativePath);
-
-								//write testHtml
-								var fpath = buildDir + "/" + fileDescriptor + "_" + generatedScript.scxmlTest  + "_" + generatedScript.label + ".html";
-
-								print("Writing html test file " + fpath);
-
-								utilFile.writeFile(testHtml,fpath);
-
-								//save the path to the html for running in selenium later
-								testsGeneratedCollection.push({
-									 path : fpath, 
-									 scxmlTest : generatedScript.scxmlTest,
-									 testCasePath : generatedScript.path,
-									 backend : generatedScript.backend,
-									 ie : generatedScript.ie
-								});
-							});
-						});
+						//we use tail recurse, because we are requiring each unit test module, which is asynchronous
+						//we require each module, one at a time, rather than all-together, so as to keep the 
+						//relationship between its module path, and the module itself. DRY
+						tailRecurse(testScripts,
+							function(testModulePath,step){
+								require([testModulePath],
+									function(testScript){
+										scriptsGenerated.
+											filter(function(s){return scxmlTests[s.scxmlTest] == testScript.scxmlTest}).
+											forEach(function(generatedScript){
+											
+											var testHtml = htmlGenFn(generatedScript.name,testModulePath);
+
+											//write testHtml
+											var fpath = buildDir + "/" + fileDescriptor + "_" + generatedScript.scxmlTest  + "_" + generatedScript.label + ".html";
+
+											print("Writing html test file " + fpath);
+
+											utilFile.writeFile(testHtml,fpath);
+
+											//save the path to the html for running in selenium later
+											testsGeneratedCollection.push({
+												 path : fpath, 
+												 scxmlTest : generatedScript.scxmlTest,
+												 testCasePath : generatedScript.path,
+												 backend : generatedScript.backend,
+												 ie : generatedScript.ie
+											});
+										});
 
-						callback();
+										step();
+									});
+							},
+							callback);
 					});
 
 				},
 
-				_genInBrowserHtml : function(fileDescriptor,testsGeneratedCollection){
+				_genInBrowserHtml : function(fileDescriptor,testsGeneratedCollection,callback){
 
 					//for each type of browser (IE and non-IE) [though we can make this part dynamic
 					//for each unit test script
@@ -379,51 +371,47 @@ require.def("build",
 
 					print("Generating in-browser html test files...");
 
+					tailRecurse(unitTestScripts,
+						function(testModule,step){
+							require([testModule],
+								function(testScript){
+									var pathToSCXMLTest = testScript.scxmlTest;
+
+									var compileTargets = [{scxmlTest:scxmlTest, backend:backend, isIE:isIE} 
+												for (backend in backends)
+												for each (isIE in [true,false])
+												for (scxmlTest in scxmlTests)
+													if ( scxmlTests[scxmlTest] == pathToSCXMLTest ) ];
+
+									compileTargets.forEach(function({scxmlTest:scxmlTestName, backend:backendName, isIE:isIE}){
+
+										//TODO: update this function to use RequireJS
+										var testHtml = inBrowserUnitTestHtmlTemplate(pathToSCXMLTest,testModule,backendName,isIE);
+
+										//write testHtml
+										var fpath = buildDir + "/" + fileDescriptor + "_" + scxmlTestName  + "_" + backendName 
+												+ (isIE ? "IE" : "") + ".html";
+
+										print("Writing in-browser html test file " + fpath);
+
+										utilFile.writeFile(testHtml,fpath);
+
+										//save the path to the html for running in selenium later
+										testsGeneratedCollection.push({
+											 path : fpath, 
+											 scxmlTest : scxmlTestName,
+											 testCasePath : testModule,
+											 backend : backendName,
+											 ie : isIE
+										});
 
-					var compileTargets = [{scxmlTest:scxmlTest, backend:backend, isIE:isIE} 
-								for (scxmlTest in scxmlTests) 
-								for (backend in backends)
-								for each (isIE in [true,false])];
-
-					compileTargets.forEach(function(target){
-						//run the build script on the test
-						var scxmlTestName = target.scxmlTest;
-						var backendName = target.backend;
-						var isIE = target.isIE;
-
-						var pathToSCXMLTest = scxmlTests[scxmlTestName];
-
-						var correspondingUnitTests = unitTestScripts.filter(function(t){return t.scxmlTest == pathToSCXMLTest});
-
-						correspondingUnitTests.forEach(function(unitTest){
-
-							var pathToUnitTest = unitTest.path;
-
-							var relativePathToUnitTest  = "../" + pathToUnitTest;
+										
+									});
 
-							var testHtml = inBrowserUnitTestHtmlTemplate(pathToSCXMLTest,relativePathToUnitTest,backendName,isIE);
-
-							//write testHtml
-							var fpath = buildDir + "/" + fileDescriptor + "_" + scxmlTestName  + "_" + backendName 
-									+ (isIE ? "IE" : "") + ".html";
-
-							print("Writing in-browser html test file " + fpath);
-
-							utilFile.writeFile(testHtml,fpath);
-
-							//save the path to the html for running in selenium later
-							testsGeneratedCollection.push({
-								 path : fpath, 
-								 scxmlTest : scxmlTestName,
-								 testCasePath : pathToUnitTest,
-								 backend : backendName,
-								 ie : isIE
-							});
-
-						}); 
-
-						
-					});
+									step();
+								});
+						},
+						callback);
 
 				},
 
@@ -445,73 +433,73 @@ require.def("build",
 							collect results
 				**/
 				runPerformanceTestsWithSelenium : function(){
-					this.genPerformanceTestHtml();
+					this.genPerformanceTestHtml(function(){
+						print("Running Selenium performance tests...");
+
+						for(var browserName in browsers){ 
 
-					print("Running Selenium performance tests...");
+							print("Running test for " + browserName + "...");
 
-					for(var browserName in browsers){ 
+							var bSpec = browsers[browserName];
+							var bSel = new DefaultSelenium(bSpec.host, bSpec.port, bSpec.browser, seleniumConf.rootUrl);
+							bSel.start();
 
-						print("Running test for " + browserName + "...");
+							htmlPerformanceTestsGenerated.forEach(function(htmlTest){
 
-						var bSpec = browsers[browserName];
-						var bSel = new DefaultSelenium(bSpec.host, bSpec.port, bSpec.browser, seleniumConf.rootUrl);
-						bSel.start();
+								//ensure we are not testing an ie html test
+								//on a non-ie browser
+								if(htmlTest.ie == bSpec.ie){
 
-						htmlPerformanceTestsGenerated.forEach(function(htmlTest){
+									var performanceResult = [];
 
-							//ensure we are not testing an ie html test
-							//on a non-ie browser
-							if(htmlTest.ie == bSpec.ie){
+									//we do this 10 times
+									for(var i = 0; i<10;i++){
 
-								var performanceResult = [];
+										var performanceResultString = testPerformanceWithSelenium(bSel,htmlTest.path); 
 
-								//we do this 10 times
-								for(var i = 0; i<10;i++){
+										//TODO: parse performanceResults from string into obj?
+										performanceResult.push(JSON.parse(performanceResultString)); 
+									}
 
-									var performanceResultString = testPerformanceWithSelenium(bSel,htmlTest.path); 
 
-									//TODO: parse performanceResults from string into obj?
-									performanceResult.push(JSON.parse(performanceResultString)); 
-								}
+									performanceResults.push({
+										data : performanceResult,
+										browser : browserName,
+										scxmlTest : htmlTest.scxmlTest,
+										backend : htmlTest.backend,
+									});
 
+									//persist to file
+									var fname = browserName +
+										"_" + "performance" + 
+										"_" + htmlTest.scxmlTest +
+										"_" + htmlTest.backend + ".json";
 
-								performanceResults.push({
-									data : performanceResult,
-									browser : browserName,
-									scxmlTest : htmlTest.scxmlTest,
-									backend : htmlTest.backend,
-								});
+									print("Writing performance results to " + fname);
+									utilFile.writeFile(performanceResultString,"build/" + fname)
+								}
+							});
 
-								//persist to file
-								var fname = browserName +
-									"_" + "performance" + 
-									"_" + htmlTest.scxmlTest +
-									"_" + htmlTest.backend + ".json";
-
-								print("Writing performance results to " + fname);
-								utilFile.writeFile(performanceResultString,"build/" + fname)
-							}
-						});
+							bSel.stop();
+						}
 
-						bSel.stop();
-					}
+						//make one big, self-describing data structure
+						//this is what analyze uses to do its analyses
+						allPerformanceResults = {
+							//FIXME: maybe make this an obj, so that we can add more info to it (for reports, etc.)
+							data : performanceResults,	
+							browsers : browsers,
+							backends : backends,
+							scxmlTests : scxmlTests
+						};
 
-					//make one big, self-describing data structure
-					//this is what analyze uses to do its analyses
-					allPerformanceResults = {
-						//FIXME: maybe make this an obj, so that we can add more info to it (for reports, etc.)
-						data : performanceResults,	
-						browsers : browsers,
-						backends : backends,
-						scxmlTests : scxmlTests
-					};
-
-					//stringify it, and serialize it for posterity
-					var allPerformanceResultsString = 
-							JSON.stringify(allPerformanceResults)
+						//stringify it, and serialize it for posterity
+						var allPerformanceResultsString = 
+								JSON.stringify(allPerformanceResults)
 
-					print("writing a summary of performance results to " + performanceResultsPath);
-					utilFile.writeFile(allPerformanceResultsString,performanceResultsPath);
+						print("writing a summary of performance results to " + performanceResultsPath);
+						utilFile.writeFile(allPerformanceResultsString,performanceResultsPath);
+					});
 
 				},
 
@@ -611,81 +599,84 @@ require.def("build",
 					});
 				},
 
-				genInBrowserUnitTestHtml : function(){
+				genInBrowserUnitTestHtml : function(callback){
 					print("Generating html performance test files...");
-					this._genInBrowserHtml("in-browser-unit",htmlInBrowserUnitTestsGenerated);
+					this._genInBrowserHtml("in-browser-unit",htmlInBrowserUnitTestsGenerated,callback);
 				},
 
 				runInBrowserUnitTestsWithSelenium : function(){
-					this.genInBrowserUnitTestHtml();
+					this.genInBrowserUnitTestHtml(function(){
 
-					print("Running Selenium unit tests...");
+						print("Running Selenium unit tests...");
 
-					for(var browserName in browsers){ 
+						for(var browserName in browsers){ 
 
-						print("Running test for " + browserName + "...");
+							print("Running test for " + browserName + "...");
 
-						var bSpec = browsers[browserName];
-						var bSel = new DefaultSelenium(bSpec.host, bSpec.port, bSpec.browser, seleniumConf.rootUrl);
-						bSel.start();
+							var bSpec = browsers[browserName];
+							var bSel = new DefaultSelenium(bSpec.host, bSpec.port, bSpec.browser, seleniumConf.rootUrl);
+							bSel.start();
 
-						htmlInBrowserUnitTestsGenerated.forEach(function(htmlTest){
-							//ensure we are not testing an ie html test
-							//on a non-ie browser
-							if(htmlTest.ie == bSpec.ie){
+							htmlInBrowserUnitTestsGenerated.forEach(function(htmlTest){
+								//ensure we are not testing an ie html test
+								//on a non-ie browser
+								if(htmlTest.ie == bSpec.ie){
 
-								var unitTestResult = unitTestWithSelenium(bSel,htmlTest.path); 
+									var unitTestResult = unitTestWithSelenium(bSel,htmlTest.path); 
 
-								var unitTestResultObj = {
-									data : unitTestResult,
-									browser : browserName,
-									scxmlTest : htmlTest.scxmlTest,
-									backend : htmlTest.backend,
-								};
+									var unitTestResultObj = {
+										data : unitTestResult,
+										browser : browserName,
+										scxmlTest : htmlTest.scxmlTest,
+										backend : htmlTest.backend,
+									};
 
-								unitTestResults.push(unitTestResultObj);
+									unitTestResults.push(unitTestResultObj);
 
-								//report errors and failures that may occur
-								if(unitTestResult.failCount || unitTestResult.errorCount){
-									print("UNIT TEST ERROR");
-									print(JSON.stringify(unitTestResultObj));
+									//report errors and failures that may occur
+									if(unitTestResult.failCount || unitTestResult.errorCount){
+										print("UNIT TEST ERROR");
+										print(JSON.stringify(unitTestResultObj));
+									}
 								}
-							}
-						});
+							});
 
-						bSel.stop();
-					}
+							bSel.stop();
+						}
+
+						//make one big, self-describing data structure
+						//this is what analyze uses to do its analyses
+						allUnitTestResults = {
+							//FIXME: maybe make this an obj, so that we can add more info to it (for reports, etc.)
+							data : unitTestResults,	
+							browsers : browsers,
+							backends : backends,
+							scxmlTests : scxmlTests
+						};
+
+						//stringify it, and serialize it for posterity
+						var allUnitTestResultsString = 
+								JSON.stringify(allUnitTestResults)
+
+
+						//print report that says whether all tests passed
+						var totalTests = unitTestResults.reduce(function(a,b){return a + b.data.testCount},0);
+						var totalTestsFailed = unitTestResults.reduce(function(a,b){return a + b.data.errorCount},0);
+						var totalTestsErrored = unitTestResults.reduce(function(a,b){return a + b.data.failCount},0);
+						var totalTestsPassed = unitTestResults.reduce(function(a,b){return a + b.data.testsPassed},0);
+
+						print("Test Results:");
+						print("Total Tests: " + totalTests);
+						print("Total Tests Failed: " + totalTestsFailed);
+						print("Total Tests Errored: " + totalTestsErrored);
+						print("Total Tests Passed: " + totalTestsPassed);
+
+						var unitTestResultsPath = "build/allUnitTestResults.json";
+						print("writing a summary of performance results to " + unitTestResultsPath);
+						utilFile.writeFile(allUnitTestResultsString, unitTestResultsPath);
+
+					});
 
-					//make one big, self-describing data structure
-					//this is what analyze uses to do its analyses
-					allUnitTestResults = {
-						//FIXME: maybe make this an obj, so that we can add more info to it (for reports, etc.)
-						data : unitTestResults,	
-						browsers : browsers,
-						backends : backends,
-						scxmlTests : scxmlTests
-					};
-
-					//stringify it, and serialize it for posterity
-					var allUnitTestResultsString = 
-							JSON.stringify(allUnitTestResults)
-
-
-					//print report that says whether all tests passed
-					var totalTests = unitTestResults.reduce(function(a,b){return a + b.data.testCount},0);
-					var totalTestsFailed = unitTestResults.reduce(function(a,b){return a + b.data.errorCount},0);
-					var totalTestsErrored = unitTestResults.reduce(function(a,b){return a + b.data.failCount},0);
-					var totalTestsPassed = unitTestResults.reduce(function(a,b){return a + b.data.testsPassed},0);
-
-					print("Test Results:");
-					print("Total Tests: " + totalTests);
-					print("Total Tests Failed: " + totalTestsFailed);
-					print("Total Tests Errored: " + totalTestsErrored);
-					print("Total Tests Passed: " + totalTestsPassed);
-
-					var unitTestResultsPath = "build/allUnitTestResults.json";
-					print("writing a summary of performance results to " + unitTestResultsPath);
-					utilFile.writeFile(allUnitTestResultsString, unitTestResultsPath);
 				},
 
 
@@ -699,23 +690,29 @@ require.def("build",
 						//unit tests have a doh dependency, so load doh with dojo.require
 						dojo.require("doh.runner");	
 
-						unitTestScripts.forEach(function(unitTestScript){
+						require(unitTestScripts,
+							function(){
+								var unitTestModules = util.toJsArray(arguments);
 
-							scriptsGenerated.	
-								filter(function(s){return scxmlTests[s.scxmlTest] == unitTestScript.scxmlTest}).
-								filter(function(s){return !s.ie}).
-								forEach(function(generatedScript){
+								unitTestModules.forEach(function(unitTestModule){
 
-								load(generatedScript.path);
+									scriptsGenerated.	
+										filter(function(s){return scxmlTests[s.scxmlTest] == unitTestModule.scxmlTest}).
+										filter(function(s){return !s.ie}).
+										forEach(function(generatedScript){
 
-								load(unitTestScript.path);
+											load(generatedScript.path);
 
-								delete StatechartExecutionContext;
-							});
+											unitTestModule.register(StatechartExecutionContext);
 
-						});
+											delete StatechartExecutionContext;
+									});
 
-						doh.run();
+								});
+
+								doh.run();
+
+							});
 					});
 
 
@@ -765,24 +762,29 @@ require.def("build",
 			}
 
 
-			function performanceTestHtmlTemplate(generatedJsCodeRelativePath,testScriptRelativePath){
+			function performanceTestHtmlTemplate(generatedJsCodeRelativePath,testScriptModulePath){
 			default xml namespace = ""
 			return <html>
 			  <head>
+				<script src="../lib/js/requirejs/require.js" type="text/javascript">true;</script>
 				<script src="../lib/test-js/dojo-release-1.4.2-src/dojo/dojo.js" type="text/javascript">true;</script>
 				<script type="text/javascript" src={generatedJsCodeRelativePath}>true;</script>
-				<script src={testScriptRelativePath} type="text/javascript">true;</script>
 				<script type="text/javascript">
-					dojo.addOnLoad(function()&#x7B;
-						window.trial = performanceTest(StatechartExecutionContext); 
-						
-						window.trialString = dojo.toJson(trial);
-						//console.log(window.trialsString);
+					require(
+						&#x7B; baseUrl : "/" &#x7D;,
+						["{testScriptModulePath}"],
+						function(performanceTest)&#x7B; 
+							
+							window.trial = performanceTest.run(StatechartExecutionContext);
+							
+							window.trialString = dojo.toJson(trial);
+							//console.log(window.trialsString);
 
-						window.testsComplete = true;
-					&#x7D;);
+							window.testsComplete = true;
+						&#x7D;);
 				
 				</script>
+
 			  </head>
 			  <body>
 				<h1>Test</h1>
@@ -792,12 +794,13 @@ require.def("build",
 			}
 
 
-			function unitTestHtmlTemplate(generatedJsCodeRelativePath,testScriptRelativePath){
+			function unitTestHtmlTemplate(generatedJsCodeRelativePath,testScriptModulePath){
 				//fixme: we probably want to put all unit test scripts in one html file
 				//but this may ential a different flow than the performance tests, so i'm marking it as a todo
 				default xml namespace = "";
 				return <html>
 					<head>
+						<script src="../lib/js/requirejs/require.js" type="text/javascript">true;</script>
 						<script type="text/javascript" src="../lib/test-js/dojo-release-1.4.2-src/dojo/dojo.js" djConfig="isDebug:true">true;</script>
 						<script type="text/javascript">
 							dojo.require("doh.runner");
@@ -807,10 +810,16 @@ require.def("build",
 						</script>
 						<script type="text/javascript" src="../test/testHelpers.js">true;</script>
 						<script type="text/javascript" src={generatedJsCodeRelativePath}>true;</script>
-						<script type="text/javascript" src={testScriptRelativePath}>true;</script>
 						<script type="text/javascript">
-							dojo.require("doh.runner");
-							doh.run();
+							require(
+								&#x7B; baseUrl : "/" &#x7D;,
+								["{testScriptModulePath}"],
+								function(unitTestModule)&#x7B; 
+									unitTestModule.register(StatechartExecutionContext);
+
+									dojo.require("doh.runner");
+									doh.run();
+								&#x7D;);
 						</script>
 					</head>
 					<body>
@@ -819,7 +828,7 @@ require.def("build",
 				</html>
 			}
 
-			function inBrowserUnitTestHtmlTemplate(modulePathToXMLTest,testScriptRelativePath,backendName,isIE){
+			function inBrowserUnitTestHtmlTemplate(modulePathToXMLTest,testScriptModulePath,backendName,isIE){
 				default xml namespace = "";
 				return <html>
 				<head>
@@ -833,7 +842,6 @@ require.def("build",
 						window.doh._onEnd = function() &#x7B; window.dohIsComplete = true; window.oldDohOnEnd.apply(window.doh); &#x7D;;
 					</script>
 					<script src="../test/testHelpers.js" type="text/javascript">true;</script>
-					<script src={testScriptRelativePath} type="text/javascript">true;</script>
 					<script>
 						var resultText;
 
@@ -842,8 +850,9 @@ require.def("build",
 								"baseUrl":"/"
 							&#x7D;,
 							[ "src/javascript/scxml/cgf/SCXMLCompiler",
-								"xml!{modulePathToXMLTest}"],
-							function(compiler,KitchenSink_executableContent)&#x7B;
+								"xml!{modulePathToXMLTest}",
+								"{testScriptModulePath}"],
+							function(compiler,KitchenSink_executableContent,testScriptModule)&#x7B;
 								var compileLog = true;
 
 								compiler.compile(&#x7B;
@@ -860,7 +869,9 @@ require.def("build",
 
 									//eval
 									eval(transformedJs);
-									window.StatechartExecutionContext = StatechartExecutionContext;
+
+									testScriptModule.register(StatechartExecutionContext);
+
 									dojo.require("doh.runner"); 
 									doh.run();
 								&#x7D;);
@@ -874,8 +885,20 @@ require.def("build",
 				</html>
 			}
 
+			//helper function that abstracts out the process of iteration using tail recursion
+			//useful for much of the asynchronous programming that happens with RequireJS and scxml-js's async API
+			function tailRecurse(list,stepCallback,baseCaseCallback){
+				var target = list.pop();
+				
+				if(target){
+					stepCallback(target, 
+						function(){tailRecurse(list,stepCallback,baseCaseCallback)});
+				}else{
+					if(baseCaseCallback) baseCaseCallback();
+				}
+			}
 
-
+			
 			if(args.length){
 				for(var i=0; i<args.length; i++){
 					if(tasks[args[i]]){

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/getDeps.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/getDeps.xml?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/getDeps.xml (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/getDeps.xml Sat Jun 26 13:51:22 2010
@@ -28,6 +28,13 @@
 	<target name="get-deps" >
 	
 		<mkdir dir="${tmp-dir}"/>
+		
+		<get dest="${tmp-dir}/xalan-j_2_7_1-bin.zip" usetimestamp="true" ignoreerrors="true" src="http://mirror.csclub.uwaterloo.ca/apache/xml/xalan-j/binaries/xalan-j_2_7_1-bin.zip"/>
+		<unzip src="${tmp-dir}/xalan-j_2_7_1-bin.zip" dest="${tmp-dir}"/>
+		<move file="${tmp-dir}/xalan-j_2_7_1/serializer.jar" todir="${lib-java}"/>
+		<move file="${tmp-dir}/xalan-j_2_7_1/xalan.jar" todir="${lib-java}"/>
+		<move file="${tmp-dir}/xalan-j_2_7_1/xercesImpl.jar" todir="${lib-java}"/>
+		<move file="${tmp-dir}/xalan-j_2_7_1/xml-apis.jar" todir="${lib-java}"/>
 
 		<!--selenium is a bit tricky, as selenium-server in maven repository is old and breaks with FF on WinXP SP3-->
 		<get dest="${tmp-dir}/selenium-remote-control-1.0.3.zip" usetimestamp="true" ignoreerrors="true" src="http://selenium.googlecode.com/files/selenium-remote-control-1.0.3.zip" />
@@ -60,6 +67,7 @@
 		<get dest="${lib-test-js}/env.js" usetimestamp="true" ignoreerrors="true" src="http://jqueryjs.googlecode.com/svn/trunk/jquery/build/runtest/env.js"/>
 		-->
 
+
 		<!-- so the last question that remains, then, is do we need full dojo? -->
 
 		<delete dir="${tmp-dir}"/>

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractEnumeratedStatechartGenerator.xsl
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractEnumeratedStatechartGenerator.xsl?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractEnumeratedStatechartGenerator.xsl (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractEnumeratedStatechartGenerator.xsl Sat Jun 26 13:51:22 2010
@@ -65,12 +65,7 @@
 		<call-template name="genTriggerIdToNameMap"/>
 
 		//transition functions
-		<for-each select="$transitions">
-			<call-template name="genTriggerDispatcherContext">
-				<with-param name="s" select=".."/>
-				<with-param name="t" select="."/>
-			</call-template>
-		</for-each>
+		<call-template name="genTriggerHandlerFunctions"/>
 
 		<call-template name="genEnumeratedHooks"/>
 	</template>
@@ -94,25 +89,52 @@
 		];
 	</template>
 
+	<template name="genTriggerHandlerFunctions">
+
+		<for-each select="$basicStates">
+
+			<variable name="state" select="."/>
+
+			<for-each select="$eventsEnum/c:name">
+				<variable name="eventName">
+					<value-of select="."/>
+				</variable>
+
+				<variable name="transitionsForEvent" select="$state/s:transition[@event = $eventName]"/>
+
+				<if test="$transitionsForEvent">
+					<call-template name="genTriggerDispatcherContext">
+						<with-param name="s" select="$state"/>
+						<with-param name="transitions" select="$transitionsForEvent"/>
+						<with-param name="eventName" select="$eventName"/>
+					</call-template>
+				</if>
+			</for-each>
+
+			<!-- now do default transitions -->
+			<variable name="defaultTransitionsForState" select="$state/s:transition[not(@event)]"/>
+			<if test="$defaultTransitionsForState">
+				<call-template name="genTriggerDispatcherContext">
+					<with-param name="s" select="$state"/>
+					<with-param name="transitions" select="$defaultTransitionsForState"/>
+					<with-param name="eventName" select="'$default'"/>
+				</call-template>
+			</if>
+
+		</for-each>
+	</template>
+
 	<template name="genTriggerDispatcherContext">
 		<param name="s"/>
-		<param name="t"/>
+		<param name="transitions"/>
+		<param name="eventName"/>
 
-		var <value-of select="$t/@c:tName"/> = function(){
-			<choose>
-				<when test="$s/@c:isHistory">
-					<call-template name="genHistoryTriggerDispatcher">
-						<with-param name="s" select="$s"/>
-						<with-param name="t" select="$t"/>
-					</call-template>
-				</when>
-				<otherwise>
-					<call-template name="genTriggerDispatcherContents">
-						<with-param name="s" select="$s"/>
-						<with-param name="t" select="$t"/>
-					</call-template>
-				</otherwise>
-			</choose>
+		var <value-of select="$transitions[1]/@c:tName"/> = function(){
+			<call-template name="genTriggerDispatcherContents">
+				<with-param name="s" select="$s"/>
+				<with-param name="transitions" select="$transitions"/>
+				<with-param name="eventName" select="$eventName"/>
+			</call-template>
 		}
 	</template>
 

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractStatechartGenerator.xsl
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractStatechartGenerator.xsl?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractStatechartGenerator.xsl (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractStatechartGenerator.xsl Sat Jun 26 13:51:22 2010
@@ -59,6 +59,8 @@
 	<variable name="nonDefaultTransitions" select="//s:transition[@event]"/>
 	-->
 
+	<variable name="abstractStateName" select="'AbstractState'"/>
+
 	<template match="/s:scxml">
 
 		<if test="$noIndexOf">
@@ -124,7 +126,7 @@
 	<template name="genAbstractState">
 		<param name="events"/>
 
-		var AbstractState = new function(){
+		var <value-of select="$abstractStateName"/> = new function(){
 			//triggers are methods
 
 			<for-each select="$events">
@@ -142,16 +144,16 @@
 
 		<variable name="parentName">
 			<choose>
-				<!-- FIXME: probably want to refine this query, as we may not be able to assume that all states have ids?-->
 				<when test="$state/../@id">
 					<value-of select="$state/../@id"/>
 				</when>
 				<otherwise>
-					<value-of select="'AbstractState'"/>
+					<value-of select="$abstractStateName"/>
 				</otherwise>
 			</choose>
 		</variable>
 
+
 		<variable name="historyState" select="$state/s:history"/>
 		
 		<variable name="constructorFunctionName" select="concat($stateName,'Constructor')"/>
@@ -524,7 +526,7 @@
 			</choose>
 			
 		}else{
-			<call-template name="genTriggerDispatcherContents">
+			<call-template name="genTriggerDispatcherGuardConditionBlockContents">
 				<with-param name="s" select="$s"/>
 				<with-param name="t" select="$t"/>
 			</call-template>
@@ -572,10 +574,56 @@
 		});
 	</template>
 
-	<template name="genTriggerDispatcherContents"> 
+	<template name="genTriggerDispatcherContents">
+		<param name="s"/>
+		<param name="transitions"/>
+		<param name="eventName"/>
+
+		<choose>
+			<when test="$s/@c:isHistory">
+				<call-template name="genHistoryTriggerDispatcher">
+					<with-param name="s" select="$s"/>
+					<with-param name="t" select="$transitions[1]"/>
+				</call-template>
+			</when>
+			<otherwise>
+				<for-each select="$transitions">
+					<call-template name="genTriggerDispatcherGuardConditionBlockContents">
+						<with-param name="s" select="$s"/>
+						<with-param name="t" select="."/>
+					</call-template>
+				</for-each>
+			</otherwise>
+		</choose>
+	</template>
+
+	<template name="genTriggerDispatcherGuardConditionBlockContents"> 
 		<param name="s"/>
 		<param name="t"/>
-	
+
+		<!-- conditionally wrap contents in an if block for the guard condition -->
+		<choose>
+			<when test="$t/@cond">
+				if(<value-of select="$t/@cond"/>){
+					<call-template name="genTriggerDispatcherInnerContents">
+						<with-param name="s" select="$s"/>
+						<with-param name="t" select="$t"/>
+					</call-template>
+				}
+			</when>
+			<otherwise>
+				<call-template name="genTriggerDispatcherInnerContents">
+					<with-param name="s" select="$s"/>
+					<with-param name="t" select="$t"/>
+				</call-template>
+			</otherwise>	
+		</choose>
+	</template>
+
+	<template name="genTriggerDispatcherInnerContents">
+		<param name="s"/>
+		<param name="t"/>
+
 		<if test="not($t/@event)">
 			hasTakenDefaultTransition = true;
 		</if>
@@ -628,6 +676,8 @@
 		<if test="$t/@c:isPreempted">
 			isPreempted = true;
 		</if>
+
+		return;
 	</template>
 
 	<template name="genNoForEachArrayPrototypeExtension">

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StatePatternStatechartGenerator.xsl
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StatePatternStatechartGenerator.xsl?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StatePatternStatechartGenerator.xsl (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StatePatternStatechartGenerator.xsl Sat Jun 26 13:51:22 2010
@@ -33,12 +33,33 @@
 
 	<template name="genStateHooks">
 		<param name="state"/>
-		<for-each select="$state/s:transition">
+
+		<!-- iterate through groups of transitions, grouped by event -->
+		<!--FIXME: this is likely to be a bit slow, as we're iterating through all events -->
+		<for-each select="$eventsEnum/c:name">
+			<variable name="eventName">
+				<value-of select="."/>
+			</variable>
+
+			<variable name="transitionsForEvent" select="$state/s:transition[@event = $eventName]"/>
+			<if test="$transitionsForEvent">
+				<call-template name="genTriggerDispatcherContext">
+					<with-param name="s" select="$state"/>
+					<with-param name="transitions" select="$transitionsForEvent"/>
+					<with-param name="eventName" select="$eventName"/>
+				</call-template>
+			</if>
+		</for-each>
+
+		<!-- now do default transitions -->
+		<variable name="defaultTransitionsForState" select="$state/s:transition[not(@event)]"/>
+		<if test="$defaultTransitionsForState">
 			<call-template name="genTriggerDispatcherContext">
 				<with-param name="s" select="$state"/>
-				<with-param name="t" select="."/>
+				<with-param name="transitions" select="$defaultTransitionsForState"/>
+				<with-param name="eventName" select="'$default'"/>
 			</call-template>
-		</for-each>
+		</if>
 	</template>
 
 	<template name="genExternalTriggerDispatcher">
@@ -93,34 +114,32 @@
 
 	<template name="genTriggerDispatcherContext">
 		<param name="s"/>
-		<param name="t"/>
-
-		<variable name="eventName">
-			<choose>
-				<when test="$t/@event">
-					<value-of select="$t/@event"/>
-				</when>	
-				<otherwise>
-					<value-of select="'$default'"/>
-				</otherwise>
-			</choose>
-		</variable>
+		<param name="transitions"/>
+		<param name="eventName"/>
 
 		this.<value-of select="$eventName"/> = function(){
-			<choose>
-				<when test="local-name($s) = 'history'">
-					<call-template name="genHistoryTriggerDispatcher">
-						<with-param name="s" select="$s"/>
-						<with-param name="t" select="$t"/>
-					</call-template>
-				</when>
-				<otherwise>
-					<call-template name="genTriggerDispatcherContents">
-						<with-param name="s" select="$s"/>
-						<with-param name="t" select="$t"/>
-					</call-template>
-				</otherwise>
-			</choose>
+
+			<call-template name="genTriggerDispatcherContents">
+				<with-param name="s" select="$s"/>
+				<with-param name="transitions" select="$transitions"/>
+				<with-param name="eventName" select="$eventName"/>
+			</call-template>
+
+			<!-- if by this point he hasn't returned, then none of the transitions passed, 
+				and we need to pass the transition up the hierarchy chain -->
+
+			<variable name="parentName">
+				<choose>
+					<when test="$s/../@id">
+						<value-of select="$s/../@id"/>
+					</when>
+					<otherwise>
+						<value-of select="$abstractStateName"/>
+					</otherwise>
+				</choose>
+			</variable>
+
+			<value-of select="$parentName"/>['<value-of select="$eventName"/>']();
 		}
 	</template>
 

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StatePatternStatechartGenerator_combined.xsl
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StatePatternStatechartGenerator_combined.xsl?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StatePatternStatechartGenerator_combined.xsl (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StatePatternStatechartGenerator_combined.xsl Sat Jun 26 13:51:22 2010
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?><!--
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -14,29 +13,21 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
---><stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:c="urn://scxml-js" xmlns:s="http://www.w3.org/2005/07/scxml">
-  <output method="text"/>
-  <param name="log" select="true()"/>
-  <param name="noIndexOf" select="false()"/>
-  <param name="noMap" select="false()"/>
-  <param name="noForEach" select="false()"/>
-  <param name="name"/>
-  <variable name="allStates" select="//*[(self::s:state or self::s:parallel or self::s:final or self::s:initial or self::s:scxml or self::s:history)]"/>
-  <variable name="states" select="//s:state"/>
-  <variable name="transitions" select="//s:transition"/>
-  <variable name="basicStates" select="$allStates[not(.//*[(self::s:state or self::s:parallel or self::s:final or self::s:initial or self::s:scxml or self::s:history)])]"/>
-  <variable name="compositeStates" select="$allStates[.//*[(self::s:state or self::s:parallel or self::s:final or self::s:initial or self::s:scxml or self::s:history)]]"/>
-  <variable name="eventsEnum" select="/s:scxml/c:eventsEnum/c:event"/>
-  <template match="/s:scxml">
-    <if test="$noIndexOf">
-      <call-template name="genNoIndexOfArrayPrototypeExtension"/>
-    </if>
-    <if test="$noMap">
-      <call-template name="genNoMapArrayPrototypeExtension"/>
-    </if>
-    <if test="$noForEach">
-      <call-template name="genNoForEachArrayPrototypeExtension"/>
-    </if>
+--><stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://www.w3.org/2005/07/scxml" xmlns:c="urn://scxml-js" version="1.0">
+
+	<output method="text"/><param name="log" select="true()"/><param name="noIndexOf" select="false()"/><param name="noMap" select="false()"/><param name="noForEach" select="false()"/><param name="name"/><variable name="allStates" select="//*[(self::s:state or self::s:parallel or self::s:final or self::s:initial or self::s:scxml or self::s:history)]"/><variable name="states" select="//s:state"/><variable name="transitions" select="//s:transition"/><variable name="basicStates" select="$allStates[not(.//*[(self::s:state or self::s:parallel or self::s:final or self::s:initial or self::s:scxml or self::s:history)])]"/><variable name="compositeStates" select="$allStates[.//*[(self::s:state or self::s:parallel or self::s:final or self::s:initial or self::s:scxml or self::s:history)]]"/><variable name="eventsEnum" select="/s:scxml/c:eventsEnum/c:event"/><variable name="abstractStateName" select="'AbstractState'"/><template match="/s:scxml">
+
+		<if test="$noIndexOf">
+			<call-template name="genNoIndexOfArrayPrototypeExtension"/>
+		</if>
+
+		<if test="$noMap">
+			<call-template name="genNoMapArrayPrototypeExtension"/>
+		</if>
+
+		<if test="$noForEach">
+			<call-template name="genNoForEachArrayPrototypeExtension"/>
+		</if>
 
 		function <value-of select="$name"/>StatechartExecutionContext(){
 
@@ -44,17 +35,31 @@
 
 				//abstract state
 
-				<call-template name="genAbstractState"><with-param name="events" select="$eventsEnum"/></call-template>
+				<call-template name="genAbstractState">
+					<with-param name="events" select="$eventsEnum"/>
+				</call-template>
 
 				//states
-				<for-each select="$allStates"><call-template name="genState"><with-param name="state" select="."/></call-template></for-each>
+				<for-each select="$allStates">
+					<call-template name="genState">
+						<with-param name="state" select="."/>
+					</call-template>
+				</for-each>
 
 		
 				//states enum for glass-box unit testing
-				<call-template name="genStatesEnum"><with-param name="states" select="$basicStates"/></call-template>
+				<call-template name="genStatesEnum">
+						<with-param name="states" select="$basicStates"/>
+				</call-template>
 
 				//trigger methods for synchronous interaction
-				<for-each select="$eventsEnum"><call-template name="genExternalTriggerDispatcher"><with-param name="event" select="."/></call-template></for-each><call-template name="genContextHooks"/>
+				<for-each select="$eventsEnum">
+					<call-template name="genExternalTriggerDispatcher">
+						<with-param name="event" select="."/>
+					</call-template>
+				</for-each>
+
+				<call-template name="genContextHooks"/>
 
 				//initialization script
 				<value-of select="s:script"/>
@@ -70,11 +75,10 @@
 
 			}
 
-	</template>
-  <template name="genAbstractState">
-    <param name="events"/>
+	</template><template name="genAbstractState">
+		<param name="events"/>
 
-		var AbstractState = new function(){
+		var <value-of select="$abstractStateName"/> = new function(){
 			//triggers are methods
 
 			<for-each select="$events">
@@ -83,23 +87,26 @@
 
 			this.$default = function(){};
 		}
-	</template>
-  <template name="genState">
-    <param name="state"/>
-    <variable name="stateName" select="$state/@id"/>
-    <variable name="parentName">
-      <choose>
-        <!-- FIXME: probably want to refine this query, as we may not be able to assume that all states have ids?-->
-        <when test="$state/../@id">
-          <value-of select="$state/../@id"/>
-        </when>
-        <otherwise>
-          <value-of select="'AbstractState'"/>
-        </otherwise>
-      </choose>
-    </variable>
-    <variable name="historyState" select="$state/s:history"/>
-    <variable name="constructorFunctionName" select="concat($stateName,'Constructor')"/>
+	</template><template name="genState">
+		<param name="state"/>
+
+		<variable name="stateName" select="$state/@id"/>
+
+		<variable name="parentName">
+			<choose>
+				<when test="$state/../@id">
+					<value-of select="$state/../@id"/>
+				</when>
+				<otherwise>
+					<value-of select="$abstractStateName"/>
+				</otherwise>
+			</choose>
+		</variable>
+
+
+		<variable name="historyState" select="$state/s:history"/>
+		
+		<variable name="constructorFunctionName" select="concat($stateName,'Constructor')"/>
 
 		<!--
 					var stateName = state.@id;
@@ -122,7 +129,9 @@
 
 				<if test="$state/self::s:history">
 					this.parent.historyState = this; //init parent's pointer to history state
-				</if><if test="$state/self::s:initial">
+				</if>
+
+				<if test="$state/self::s:initial">
 					this.parent.initial = this; //init parent's pointer to initial state
 				</if>
 				
@@ -133,18 +142,26 @@
 				this.enterAction = function(){
 					<if test="$log">
 						console.log("entering <value-of select="$stateName"/>");
-					</if><apply-templates select="$state/s:onentry/*[self::s:if or self::s:raise or self::s:log or self::s:script or self::s:send or self::s:cancel or self::s:invoke or self::s:finalize or self::s:datamodel or self::s:data or self::s:assign or self::s:validate or self::s:param]"/>
+					</if>
+
+					<apply-templates select="$state/s:onentry/*[self::s:if or self::s:raise or self::s:log or self::s:script or self::s:send or self::s:cancel or self::s:invoke or self::s:finalize or self::s:datamodel or self::s:data or self::s:assign or self::s:validate or self::s:param]"/>
 				}
 
 				this.exitAction = function(){
 					<if test="$log">
 						console.log("exiting <value-of select="$stateName"/>" );
-					</if><if test="$historyState">
+					</if>
+
+					<if test="$historyState">
 						this.historyState.lastConfiguration = currentConfiguration.slice();
-					</if><apply-templates select="$state/s:onexit/*[self::s:if or self::s:raise or self::s:log or self::s:script or self::s:send or self::s:cancel or self::s:invoke or self::s:finalize or self::s:datamodel or self::s:data or self::s:assign or self::s:validate or self::s:param]"/>
+					</if>
+
+					<apply-templates select="$state/s:onexit/*[self::s:if or self::s:raise or self::s:log or self::s:script or self::s:send or self::s:cancel or self::s:invoke or self::s:finalize or self::s:datamodel or self::s:data or self::s:assign or self::s:validate or self::s:param]"/>
 				}
 
-				<call-template name="genStateHooks"><with-param name="state" select="$state"/></call-template>
+				<call-template name="genStateHooks">
+					<with-param name="state" select="$state"/>
+				</call-template>
 				
 
 			}
@@ -152,75 +169,63 @@
 			return new <value-of select="$constructorFunctionName"/>();
 		})();
 
-	</template>
-  <template name="genStatesEnum">
-    <param name="states"/>
+	</template><template name="genStatesEnum">
+		<param name="states"/>
 
 		this._states = {
-			<for-each select="$states"><value-of select="@id"/> : <value-of select="@id"/><if test="not(position() = last())">,</if></for-each>
+			<for-each select="$states">
+				<value-of select="@id"/> : <value-of select="@id"/>
+				<if test="not(position() = last())">,</if>
+			</for-each>
 		}
 
-	</template>
-  <template match="s:if">
+	</template><template match="s:if">
 		if (<value-of select="@cond"/>) {
 			<apply-templates select="c:executableContent/*"/>	
 		}
-		<apply-templates select="s:elseif"/><apply-templates select="s:else"/></template>
-  <template match="s:elseif">
+		<apply-templates select="s:elseif"/>
+		<apply-templates select="s:else"/>
+	</template><template match="s:elseif">
 		else if (<value-of select="@cond"/>) {
 			<apply-templates select="c:executableContent/*"/>
 		}
-	</template>
-  <template match="s:else">
+	</template><template match="s:else">
 		else {
 			<apply-templates select="c:executableContent/*"/>
 		}
-	</template>
-  <template match="s:log">
-    <if test="@label">
+	</template><template match="s:log">
+		<if test="@label">
 			console.log( ' <value-of select="@label"/> : ' );
 		</if>
-    <if test="@expr">
+		<if test="@expr">
 			console.log(  <value-of select="@expr"/>  );
 			
 		</if>
-  </template>
-  <template match="s:raise">
+	</template><template match="s:raise">
 	<!--TODO-->
-	</template>
-  <template match="s:script">
-    <value-of select="."/>
-  </template>
-  <template match="s:cancel">
+	</template><template match="s:script">
+		<value-of select="."/>
+	</template><template match="s:cancel">
 	<!--TODO-->
-	</template>
-  <template match="s:invoke">
+	</template><template match="s:invoke">
 	<!--TODO-->
-	</template>
-  <template match="s:finalize">
+	</template><template match="s:finalize">
 	<!--TODO-->
-	</template>
-  <template match="s:datamodel">
+	</template><template match="s:datamodel">
 	<!--TODO-->
-	</template>
-  <template match="s:data">
+	</template><template match="s:data">
 	<!--TODO-->
-	</template>
-  <template match="s:assign">
+	</template><template match="s:assign">
 	<!--TODO-->
-	</template>
-  <template match="s:validate">
+	</template><template match="s:validate">
 	<!--TODO-->
-	</template>
-  <template match="s:param">
+	</template><template match="s:param">
 	<!--TODO-->
-	</template>
-  <template name="genInternalRuntimeFunctions">
+	</template><template name="genInternalRuntimeFunctions">
 		function sortByDepthDeepToShallow(a,b){
 			return b.depth - a.depth;
 		}
-	</template>
-  <template name="genBoilerplateDispatchCode">
+	</template><template name="genBoilerplateDispatchCode">
 		//static private member variables
 		var currentConfiguration = []; //current configuration
 		var innerEventQueue = []; //inner event queue
@@ -311,53 +316,55 @@
 		}
 
 		//end static boilerplate code
-	</template>
-  <variable name="deepHistoryEnterAction">
-    <text>
+	</template><variable name="deepHistoryEnterAction">
+		<text>
 			var topState;
 			while(topState = statesEntered.pop()){
 				topState.enterAction();
 			}
 		</text>
-  </variable>
-  <variable name="shallowHistoryEnterAction">
-    <text>
+	</variable><variable name="shallowHistoryEnterAction">
+		<text>
 			var topState = statesEntered.pop();
 
 			topState.enterAction();
 
 			newConfiguration.push(topState.initial ? topState.initial : topState );	
 		</text>
-  </variable>
-  <variable name="genNonBasicTriggerDispatcherExitBlockInnerForEach">
-    <text>
+	</variable><variable name="genNonBasicTriggerDispatcherExitBlockInnerForEach">
+		<text>
 			do{
 				statesExited.push(state);
 			}while((state = state.parent) &amp;&amp;
 				state != lca &amp;&amp; 
 				statesExited.indexOf(state) == -1)
 		</text>
-  </variable>
-  <template name="genHistoryTriggerDispatcher">
-    <param name="s"/>
-    <param name="t"/>
-    <variable name="isDeep" select="$s/@type = 'deep'"/>
-    <variable name="historyStateReference">
-      <call-template name="genHistoryTriggerDispatcherHistoryStateReference">
-        <with-param name="s" select="$s"/>
-      </call-template>
-    </variable>
+	</variable><template name="genHistoryTriggerDispatcher">
+		<param name="s"/>
+		<param name="t"/>
+
+		<variable name="isDeep" select="$s/@type = 'deep'"/>
+		<variable name="historyStateReference">
+			<call-template name="genHistoryTriggerDispatcherHistoryStateReference">
+				<with-param name="s" select="$s"/>
+			</call-template>
+		</variable>
 
 
 		//history state semantics
 		if(<value-of select="$historyStateReference"/>.lastConfiguration){
 
 			//transition action
-			<if test="$log"><choose><when test="$isDeep">
+			<if test="$log">
+				<choose>
+					<when test="$isDeep">
 						console.log("return to last deep configuration");
-					</when><otherwise>
+					</when>
+					<otherwise>
 						console.log("return to last shallow configuration");
-					</otherwise></choose></if>
+					</otherwise>
+				</choose>
+			</if>
 					
 				
 			<!--gen executable content for t-->
@@ -369,22 +376,31 @@
 
 			<if test="not($isDeep)">
 				var newConfiguration = [];
-			</if><value-of select="$historyStateReference"/>.lastConfiguration.forEach(function(state){
-				<call-template name="genHistoryTriggerDispatcherInnerForEach"><with-param name="isDeep" select="$isDeep"/></call-template>
+			</if>
+
+			<value-of select="$historyStateReference"/>.lastConfiguration.forEach(function(state){
+				<call-template name="genHistoryTriggerDispatcherInnerForEach">
+					<with-param name="isDeep" select="$isDeep"/>
+				</call-template>
 			});
 			
-			<choose><when test="$isDeep">
+			<choose>
+				<when test="$isDeep">
 					currentConfiguration =  <value-of select="$historyStateReference"/>.lastConfiguration.slice();
-				</when><otherwise>
+				</when>
+				<otherwise>
 					currentConfiguration = <value-of select="$genHistoryTriggerDispatcherCurrentConfigurationAssignmentRHS"/>;
-				</otherwise></choose>
+				</otherwise>
+			</choose>
 			
 		}else{
-			<call-template name="genTriggerDispatcherContents"><with-param name="s" select="$s"/><with-param name="t" select="$t"/></call-template>
+			<call-template name="genTriggerDispatcherContents">
+				<with-param name="s" select="$s"/>
+				<with-param name="t" select="$t"/>
+			</call-template>
 		}
-	</template>
-  <template name="genHistoryTriggerDispatcherInnerForEach">
-    <param name="isDeep"/>
+	</template><template name="genHistoryTriggerDispatcherInnerForEach">
+		<param name="isDeep"/>
 
 		var statesEntered = [<value-of select="$genHistoryTriggerDispatcherInnerForEachStateReference"/>]; 
 
@@ -395,9 +411,16 @@
 		}
 
 		
-		<choose><when test="$isDeep"><value-of select="$deepHistoryEnterAction"/></when><otherwise><value-of select="$shallowHistoryEnterAction"/></otherwise></choose></template>
-  <template name="genNonBasicTriggerDispatcherExitBlock">
-    <param name="t"/> 
+		<choose>
+			<when test="$isDeep">
+				<value-of select="$deepHistoryEnterAction"/>
+			</when>
+			<otherwise>
+				<value-of select="$shallowHistoryEnterAction"/>
+			</otherwise>
+		</choose>
+	</template><template name="genNonBasicTriggerDispatcherExitBlock">
+		<param name="t"/> 
 
 		var statesExited = [];
 		var lca = <value-of select="$t/c:lca"/>;
@@ -413,17 +436,48 @@
 		statesExited.forEach(function(state){
 			state.exitAction();
 		});
-	</template>
-  <template name="genTriggerDispatcherContents">
-    <param name="s"/>
-    <param name="t"/>
-    <if test="not($t/@event)">
+	</template><template name="genTriggerDispatcherContents"> 
+		<param name="s"/>
+		<param name="t"/>
+
+		<!-- conditionally wrap contents in an if block for the guard condition -->
+		<choose>
+			<when test="$t/@cond">
+				if(<value-of select="$t/@cond"/>){
+					<call-template name="genTriggerDispatcherInnerContents">
+						<with-param name="s" select="$s"/>
+						<with-param name="t" select="$t"/>
+					</call-template>
+				}
+			</when>
+			<otherwise>
+				<call-template name="genTriggerDispatcherInnerContents">
+					<with-param name="s" select="$s"/>
+					<with-param name="t" select="$t"/>
+				</call-template>
+			</otherwise>	
+		</choose>
+	</template><template name="genTriggerDispatcherInnerContents">
+		<param name="s"/>
+		<param name="t"/>
+
+		<if test="not($t/@event)">
 			hasTakenDefaultTransition = true;
 		</if>
 
 		//exit states
-		<choose><when test="local-name($s) = 'initial' or local-name($s) = 'history' or        ( $s/@c:isBasic and         ( not($s/@c:isParallelSubstate) or          ($s/@c:isParallelSubstate and not($t/@c:exitsParallelRegion))))"><for-each select="$t/c:exitpath/c:state"><value-of select="."/>.exitAction();
-				</for-each></when><otherwise><call-template name="genNonBasicTriggerDispatcherExitBlock"><with-param name="t" select="$t"/></call-template></otherwise></choose>
+		<choose>
+			<when test="local-name($s) = 'initial' or local-name($s) = 'history' or        ( $s/@c:isBasic and         ( not($s/@c:isParallelSubstate) or          ($s/@c:isParallelSubstate and not($t/@c:exitsParallelRegion))))">
+				<for-each select="$t/c:exitpath/c:state">
+					<value-of select="."/>.exitAction();
+				</for-each>
+			</when>
+			<otherwise>
+				<call-template name="genNonBasicTriggerDispatcherExitBlock">
+					<with-param name="t" select="$t"/>
+				</call-template>
+			</otherwise>
+		</choose>
 
 		//transition action
 		<apply-templates select="$t/*[self::s:if or self::s:raise or self::s:log or self::s:script or self::s:send or self::s:cancel or self::s:invoke or self::s:finalize or self::s:datamodel or self::s:data or self::s:assign or self::s:validate or self::s:param]"/>
@@ -431,18 +485,34 @@
 		//enter states
 		<for-each select="$t/c:targets/c:target/c:enterpath/c:state"> 
 			<!-- iterate in reverse order -->
-			<sort data-type="number" order="descending" select="position()"/><value-of select="."/>.enterAction();
+			<sort select="position()" data-type="number" order="descending"/>
+			<value-of select="."/>.enterAction();
 		</for-each>
 
 		//update configuration
-		<choose><when test="$s/@c:isParallelSubstate and not($t/@c:exitsParallelRegion)"><call-template name="genParallelSubstateConfigurationSetString"><with-param name="s" select="$s"/><with-param name="t" select="$t"/></call-template></when><otherwise><call-template name="genNonParallelSubstateConfigurationSetString"><with-param name="s" select="$s"/><with-param name="t" select="$t"/></call-template></otherwise></choose>
+		<choose>
+			<when test="$s/@c:isParallelSubstate and not($t/@c:exitsParallelRegion)">
+				<call-template name="genParallelSubstateConfigurationSetString">
+					<with-param name="s" select="$s"/>
+					<with-param name="t" select="$t"/>
+				</call-template>
+			</when>
+			<otherwise>
+				<call-template name="genNonParallelSubstateConfigurationSetString">
+					<with-param name="s" select="$s"/>
+					<with-param name="t" select="$t"/>
+				</call-template>
+			</otherwise>
+		</choose>
 
 
 		//set whether preempted
 		<if test="$t/@c:isPreempted">
 			isPreempted = true;
-		</if></template>
-  <template name="genNoForEachArrayPrototypeExtension">
+		</if>
+
+		return;
+	</template><template name="genNoForEachArrayPrototypeExtension">
 		if(!Array.forEach){
 			Array.prototype.forEach = function(fn){
 				for(var i=0; i &lt; this.length; i++){
@@ -451,8 +521,7 @@
 				return undefined;
 			}
 		}
-	</template>
-  <template name="genNoIndexOfArrayPrototypeExtension">
+	</template><template name="genNoIndexOfArrayPrototypeExtension">
 		if(!Array.indexOf){
 			Array.prototype.indexOf = function(obj){
 				for(var i=0; i &lt; this.length; i++){
@@ -463,8 +532,7 @@
 				return -1;
 			}
 		}
-	</template>
-  <template name="genNoMapArrayPrototypeExtension">
+	</template><template name="genNoMapArrayPrototypeExtension">
 		if(!Array.map){
 			Array.prototype.map = function(fn){
 				var toReturn = [];
@@ -474,26 +542,50 @@
 				return toReturn;
 			}
 		}
+	</template><template name="genContextHooks"/>
+
+	<!-- these params get overridden by subclasses -->
+	<param name="dispatchInvocation" select="'state[e]();'"/>
+	<param name="defaultEventLiteral" select="'&quot;$default&quot;'"/>
+	<param name="currentConfigurationExpression" select="'currentConfiguration.slice()'"/>
+
+	<param name="genHistoryTriggerDispatcherCurrentConfigurationAssignmentRHS" select="'newConfiguration'"/>
+	<param name="genHistoryTriggerDispatcherInnerForEachStateReference" select="'state'"/>
+	<param name="genNonBasicTriggerDispatcherExitBlockIteratorExpression" select="'currentConfiguration'"/>
+
+	<template name="genStateHooks">
+		<param name="state"/>
+
+		<!-- iterate through groups of transitions, grouped by event -->
+		<!--FIXME: this is likely to be a bit slow, as we're iterating through all events -->
+		<for-each select="$eventsEnum/c:name">
+			<variable name="eventName">
+				<value-of select="."/>
+			</variable>
+
+			<variable name="transitionsForEvent" select="$state/s:transition[@event = $eventName]"/>
+			<if test="$transitionsForEvent">
+				<call-template name="genTriggerDispatcherContext">
+					<with-param name="s" select="$state"/>
+					<with-param name="transitions" select="$transitionsForEvent"/>
+					<with-param name="eventName" select="$eventName"/>
+				</call-template>
+			</if>
+		</for-each>
+
+		<!-- now do default transitions -->
+		<variable name="defaultTransitionsForState" select="$state/s:transition[not(@event)]"/>
+		<if test="$defaultTransitionsForState">
+			<call-template name="genTriggerDispatcherContext">
+				<with-param name="s" select="$state"/>
+				<with-param name="transitions" select="$defaultTransitionsForState"/>
+				<with-param name="eventName" select="'$default'"/>
+			</call-template>
+		</if>
 	</template>
-  <template name="genContextHooks"/>
-  <!-- these params get overridden by subclasses -->
-  <param name="dispatchInvocation" select="'state[e]();'"/>
-  <param name="defaultEventLiteral" select="'&quot;$default&quot;'"/>
-  <param name="currentConfigurationExpression" select="'currentConfiguration.slice()'"/>
-  <param name="genHistoryTriggerDispatcherCurrentConfigurationAssignmentRHS" select="'newConfiguration'"/>
-  <param name="genHistoryTriggerDispatcherInnerForEachStateReference" select="'state'"/>
-  <param name="genNonBasicTriggerDispatcherExitBlockIteratorExpression" select="'currentConfiguration'"/>
-  <template name="genStateHooks">
-    <param name="state"/>
-    <for-each select="$state/s:transition">
-      <call-template name="genTriggerDispatcherContext">
-        <with-param name="s" select="$state"/>
-        <with-param name="t" select="."/>
-      </call-template>
-    </for-each>
-  </template>
-  <template name="genExternalTriggerDispatcher">
-    <param name="event"/>
+
+	<template name="genExternalTriggerDispatcher">
+		<param name="event"/>
 
 		this.<value-of select="$event/c:name"/> = function(){
 			if(isInStableState){
@@ -503,26 +595,36 @@
 			}
 		}
 	</template>
-  <template name="genParallelSubstateConfigurationSetString">
-    <param name="s"/>
-    <param name="t"/>
+
+	<template name="genParallelSubstateConfigurationSetString">
+		<param name="s"/>
+		<param name="t"/>
 
 		currentConfiguration.splice(currentConfiguration.indexOf(this),1,
-			<for-each select="$t/c:targets/c:target/c:targetState"><value-of select="."/><if test="not(position() = last())">,</if></for-each> 
+			<for-each select="$t/c:targets/c:target/c:targetState">
+				<value-of select="."/>
+				<if test="not(position() = last())">,</if>
+			</for-each> 
 		); 
 	</template>
-  <template name="genNonParallelSubstateConfigurationSetString">
-    <param name="t"/>
-    <param name="s"/>
+
+	<template name="genNonParallelSubstateConfigurationSetString">
+		<param name="t"/>
+		<param name="s"/>
 
 		currentConfiguration = [
-			<for-each select="$t/c:targets/c:target/c:targetState"><value-of select="."/><if test="not(position() = last())">,</if></for-each>
+			<for-each select="$t/c:targets/c:target/c:targetState">
+				<value-of select="."/>
+				<if test="not(position() = last())">,</if>
+			</for-each>
 		]; 
 	</template>
-  <template name="genInitialization">
-    <variable name="initialStateName">
-      <value-of select="/s:scxml/s:initial/s:transition/c:targets/c:target/c:targetState"/>
-    </variable>
+
+	<template name="genInitialization">
+
+		<variable name="initialStateName">
+			<value-of select="/s:scxml/s:initial/s:transition/c:targets/c:target/c:targetState"/>
+		</variable>
  
 		this.initialize = function(){
 			currentConfiguration = [<value-of select="$initialStateName"/>];
@@ -531,38 +633,65 @@
 		}
 
 	</template>
-  <template name="genTriggerDispatcherContext">
-    <param name="s"/>
-    <param name="t"/>
-    <variable name="eventName">
-      <choose>
-        <when test="$t/@event">
-          <value-of select="$t/@event"/>
-        </when>
-        <otherwise>
-          <value-of select="'$default'"/>
-        </otherwise>
-      </choose>
-    </variable>
+
+	<template name="genTriggerDispatcherContext">
+		<param name="s"/>
+		<param name="transitions"/>
+		<param name="eventName"/>
 
 		this.<value-of select="$eventName"/> = function(){
-			<choose><when test="local-name($s) = 'history'"><call-template name="genHistoryTriggerDispatcher"><with-param name="s" select="$s"/><with-param name="t" select="$t"/></call-template></when><otherwise><call-template name="genTriggerDispatcherContents"><with-param name="s" select="$s"/><with-param name="t" select="$t"/></call-template></otherwise></choose>
+			<choose>
+				<when test="local-name($s) = 'history'">
+					<call-template name="genHistoryTriggerDispatcher">
+						<with-param name="s" select="$s"/>
+						<with-param name="t" select="$transitions[1]"/>
+					</call-template>
+				</when>
+				<otherwise>
+					<for-each select="$transitions">
+						<call-template name="genTriggerDispatcherContents">
+							<with-param name="s" select="$s"/>
+							<with-param name="t" select="."/>
+						</call-template>
+					</for-each>
+				</otherwise>
+			</choose>
+
+			<!-- if by this point he hasn't returned, then none of the transitions passed, 
+				and we need to pass the transition up the hierarchy chain -->
+
+			<variable name="parentName">
+				<choose>
+					<when test="$s/../@id">
+						<value-of select="$s/../@id"/>
+					</when>
+					<otherwise>
+						<value-of select="$abstractStateName"/>
+					</otherwise>
+				</choose>
+			</variable>
+
+			<value-of select="$parentName"/>['<value-of select="$eventName"/>']();
 		}
 	</template>
-  <template name="genHistoryTriggerDispatcherHistoryStateReference">
-    <param name="s"/>
-    <text>this</text>
-  </template>
-  <template match="s:send">
-    <choose>
-      <when test="@delay">
+
+	<template name="genHistoryTriggerDispatcherHistoryStateReference">
+		<param name="s"/>
+
+		<text>this</text>
+	</template> 
+
+	<template match="s:send">
+		<choose>
+			<when test="@delay">
 				window.setTimeout(function(){
 					self.GEN("<value-of select="@event"/>");
 				},<value-of select="number(@delay)*1000"/>);
 			</when>
-      <otherwise>
+			<otherwise>
 				innerEventQueue.push("<value-of select="@event"/>");
 			</otherwise>
-    </choose>
-  </template>
-</stylesheet>
+		</choose>
+	</template>
+
+</stylesheet>
\ No newline at end of file

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StateTableStatechartGenerator.xsl
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StateTableStatechartGenerator.xsl?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StateTableStatechartGenerator.xsl (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/StateTableStatechartGenerator.xsl Sat Jun 26 13:51:22 2010
@@ -76,9 +76,7 @@
 
 						<choose>
 							<when test="$correspondingTransitions">
-								<for-each select="$correspondingTransitions">
-									<value-of select="@c:tName"/>
-								</for-each>
+								<value-of select="$correspondingTransitions[1]/@c:tName"/>
 							</when>
 							<otherwise>
 								<value-of select="$nullTransitionFunctionName"/>

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/ir-compiler/flattenTransitions.xsl
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/ir-compiler/flattenTransitions.xsl?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/ir-compiler/flattenTransitions.xsl (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/ir-compiler/flattenTransitions.xsl Sat Jun 26 13:51:22 2010
@@ -59,10 +59,11 @@ collision. 
 
 		<xsl:variable name="currentTransitions" select="s:transition"/>
 
-		<!-- get active transitions -->
-		<xsl:variable name="filteredParentTransitions" select="$parentTransitions[not(@event = $currentTransitions/@event)]"/>
+		<!-- we used to filter the parent transitions here to avoid transitions with duplicate events,
+			but this is no longer necessary, as parent transitions will have lower priority
+			as they are appended in a deeper document order -->
 
-		<xsl:variable name="activeTransitions" select="$filteredParentTransitions | $currentTransitions"/>
+		<xsl:variable name="activeTransitions" select="$currentTransitions | $parentTransitions"/>
 
 		<!--
 		<xsl:message>
@@ -98,10 +99,11 @@ collision. 
 
 		<xsl:variable name="currentTransitions" select="s:transition"/>
 
-		<!-- get active transitions -->
-		<xsl:variable name="filteredParentTransitions" select="$parentTransitions[not(@event = $currentTransitions/@event)]"/>
+		<!-- we used to filter the parent transitions here to avoid transitions with duplicate events,
+			but this is no longer necessary, as parent transitions will have lower priority
+			as they are appended in a deeper document order -->
 
-		<xsl:variable name="activeTransitions" select="$filteredParentTransitions | $currentTransitions"/>
+		<xsl:variable name="activeTransitions" select="$currentTransitions | $parentTransitions"/>
 
 		<!--
 		<xsl:message>

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/performanceTest.js
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/performanceTest.js?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/performanceTest.js (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/performanceTest.js Sat Jun 26 13:51:22 2010
@@ -15,35 +15,38 @@
  * limitations under the License.
  */
 
+require.def("test/kitchen_sink/scripts/performanceTest",
+{
+	scxmlTest : "test/kitchen_sink/KitchenSink_performance.xml",
+	run : function(scConstructor,ticToc){
 
-performanceTest = function(scConstructor,ticToc){
+		var d1 = new Date();
 
-	var d1 = new Date();
+		sc = new scConstructor()
 
-	sc = new scConstructor()
+		sc.initialize();
 
-	sc.initialize();
+		sc.t1()
 
-	sc.t1()
+		sc.t2_7()
 
-	sc.t2_7()
+		sc.t3()
 
-	sc.t3()
+		sc.t4_9()
 
-	sc.t4_9()
+		sc.t5()
 
-	sc.t5()
+		sc.t2_7()
 
-	sc.t2_7()
+		sc.t8()
 
-	sc.t8()
+		sc.t4_9()
 
-	sc.t4_9()
+		var etime = new Date() - d1;
 
-	var etime = new Date() - d1;
-
-	//return an array of times
-	//index 0 is initialization time
-	//FIXME: maybe way want labels for this data? Might be easier to analyze later...
-	return etime;
-}
+		//return an array of times
+		//index 0 is initialization time
+		//FIXME: maybe way want labels for this data? Might be easier to analyze later...
+		return etime;
+	}
+});

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/unitTest.js
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/unitTest.js?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/unitTest.js (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/unitTest.js Sat Jun 26 13:51:22 2010
@@ -15,92 +15,95 @@
  * limitations under the License.
  */
 
-
-dojo.require("doh.runner");
-
-//we assume statechart is imported here. should probably do registermodulepath instead
-
-(function(){
-	var sc;
-	doh.register("testKitchenSinkSuite",[
-			{
-				name:"testAll",
-				//timeout:5000,
-				setUp:function(){
-					sc = new StatechartExecutionContext()
-					sc.initialize();
-				},
-				runTest:function(){
-					var $ = function(conf){return conf.map(function(s){return s.toString()})};
-
-					var conf0 = sc.getCurrentConfiguration();
-					console.log($(conf0));
-					doh.assertTrue(setwiseEqual(conf0,[sc._states.Basic1]));
-
-					console.info("sending event t1")
-					sc.t1()
-					var conf1 = sc.getCurrentConfiguration();
-					console.log($(conf1));
-					doh.assertTrue(setwiseEqual(conf1,[sc._states.Basic2]));
-
-
-					console.info("sending event t2_7")
-					sc.t2_7()
-					var conf2 = sc.getCurrentConfiguration();
-					console.log($(conf2));
-					doh.assertTrue(setwiseEqual(conf2,[sc._states.Basic4,sc._states.Basic6]));
-
-
-					console.info("sending event t3")
-					sc.t3()
-					var conf3 = sc.getCurrentConfiguration();
-					console.log($(conf3));
-					doh.assertTrue(setwiseEqual(conf3,[sc._states.Basic5,sc._states.Basic7]));
-
-					console.info("sending event t4_9")
-					sc.t4_9()
-					var conf4 = sc.getCurrentConfiguration();
-					console.log($(conf4));
-					doh.assertTrue(setwiseEqual(conf4,[sc._states.Basic2]));
-
-					console.info("sending event t5")
-					sc.t5()
-					var conf5 = sc.getCurrentConfiguration();
-					console.log($(conf5));
-					doh.assertTrue(setwiseEqual(conf5,[sc._states.Basic1]));
-
-					console.info("sending event t2_7")
-					sc.t2_7()
-					var conf6 = sc.getCurrentConfiguration();
-					console.log($(conf6));
-					doh.assertTrue(setwiseEqual(conf6,[sc._states.Basic5,sc._states.Basic7]));
-
-					console.info("sending event t8")
-					sc.t8()
-					var conf7 = sc.getCurrentConfiguration();
-					console.log($(conf7));
-					doh.assertTrue(setwiseEqual(conf7,[sc._states.Basic4,sc._states.Basic7]));
-
-					console.info("sending event t4_9")
-					sc.t4_9()
-					var conf8 = sc.getCurrentConfiguration();
-					console.log($(conf8));
-					doh.assertTrue(setwiseEqual(conf8,[sc._states.Basic3]));
-
-					//TODO: hook this up with doh.Deferred...
-					/*
-					var deferred = new doh.Deferred();
-					window.setTimeout(function(){
-						var conf9 = sc.getCurrentConfiguration();
-						console.log($(conf9));
-						deferred.callback(setwiseEqual(conf9,[sc._states.FinalState]));
-					},1500);
-					return deferred;
-					*/
-				},
-				tearDown:function(){
-					 sc.destroy();
+require.def( "test/kitchen_sink/scripts/unitTest",
+{
+	scxmlTest:"test/kitchen_sink/KitchenSink.xml",
+
+	register : function(scConstructor){
+
+		//TODO: can load this using RequireJS, so we don't need to use the dojo module system?
+		dojo.require("doh.runner");
+		var sc;
+		doh.register("testKitchenSinkSuite",[
+				{
+					name:"testAll",
+					//timeout:5000,
+					setUp:function(){
+						sc = new scConstructor()
+						sc.initialize();
+					},
+					runTest:function(){
+						var $ = function(conf){return conf.map(function(s){return s.toString()})};
+
+						var conf0 = sc.getCurrentConfiguration();
+						console.log($(conf0));
+						doh.assertTrue(setwiseEqual(conf0,[sc._states.Basic1]));
+
+						console.info("sending event t1")
+						sc.t1()
+						var conf1 = sc.getCurrentConfiguration();
+						console.log($(conf1));
+						doh.assertTrue(setwiseEqual(conf1,[sc._states.Basic2]));
+
+
+						console.info("sending event t2_7")
+						sc.t2_7()
+						var conf2 = sc.getCurrentConfiguration();
+						console.log($(conf2));
+						doh.assertTrue(setwiseEqual(conf2,[sc._states.Basic4,sc._states.Basic6]));
+
+
+						console.info("sending event t3")
+						sc.t3()
+						var conf3 = sc.getCurrentConfiguration();
+						console.log($(conf3));
+						doh.assertTrue(setwiseEqual(conf3,[sc._states.Basic5,sc._states.Basic7]));
+
+						console.info("sending event t4_9")
+						sc.t4_9()
+						var conf4 = sc.getCurrentConfiguration();
+						console.log($(conf4));
+						doh.assertTrue(setwiseEqual(conf4,[sc._states.Basic2]));
+
+						console.info("sending event t5")
+						sc.t5()
+						var conf5 = sc.getCurrentConfiguration();
+						console.log($(conf5));
+						doh.assertTrue(setwiseEqual(conf5,[sc._states.Basic1]));
+
+						console.info("sending event t2_7")
+						sc.t2_7()
+						var conf6 = sc.getCurrentConfiguration();
+						console.log($(conf6));
+						doh.assertTrue(setwiseEqual(conf6,[sc._states.Basic5,sc._states.Basic7]));
+
+						console.info("sending event t8")
+						sc.t8()
+						var conf7 = sc.getCurrentConfiguration();
+						console.log($(conf7));
+						doh.assertTrue(setwiseEqual(conf7,[sc._states.Basic4,sc._states.Basic7]));
+
+						console.info("sending event t4_9")
+						sc.t4_9()
+						var conf8 = sc.getCurrentConfiguration();
+						console.log($(conf8));
+						doh.assertTrue(setwiseEqual(conf8,[sc._states.Basic3]));
+
+						//TODO: hook this up with doh.Deferred...
+						/*
+						var deferred = new doh.Deferred();
+						window.setTimeout(function(){
+							var conf9 = sc.getCurrentConfiguration();
+							console.log($(conf9));
+							deferred.callback(setwiseEqual(conf9,[sc._states.FinalState]));
+						},1500);
+						return deferred;
+						*/
+					},
+					tearDown:function(){
+						 sc.destroy();
+					}
 				}
-			}
-	]);
-})()
+		]);
+	}
+});

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/unitTest_executableContent.js
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/unitTest_executableContent.js?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/unitTest_executableContent.js (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/test/kitchen_sink/scripts/unitTest_executableContent.js Sat Jun 26 13:51:22 2010
@@ -15,111 +15,115 @@
  * limitations under the License.
  */
 
-
-dojo.require("doh.runner");
-
-//we assume statechart is imported here. should probably do registermodulepath instead
-
-(function(){
-	var sc;
-	doh.register("testKitchenSinkSuite",[
-			{
-				name:"testAll",
-				//timeout:5000,
-				setUp:function(){
-					sc = new StatechartExecutionContext()
-					sc.initialize();
-				},
-				runTest:function(){
-					var conf0 = sc.getCurrentConfiguration();
-					console.log(conf0);
-					doh.assertTrue(setwiseEqual(conf0,[sc._states.Basic1]));
-
-					doh.assertEqual(sc.x,0);
-					doh.assertEqual(sc.y,0);
-
-					console.info("sending event t1")
-					sc.t1()
-					var conf1 = sc.getCurrentConfiguration();
-					console.log(conf1);
-					doh.assertTrue(setwiseEqual(conf1,[sc._states.Basic2]));
-
-					doh.assertEqual(sc.x,1);
-					doh.assertEqual(sc.y,0);
-
-
-					console.info("sending event t2_7")
-					sc.t2_7()
-					var conf2 = sc.getCurrentConfiguration();
-					console.log(conf2);
-					doh.assertTrue(setwiseEqual(conf2,[sc._states.Basic4,sc._states.Basic6]));
-
-					doh.assertEqual(sc.x,9);
-					doh.assertEqual(sc.y,0);
-
-					console.info("sending event t3")
-					sc.t3()
-					var conf3 = sc.getCurrentConfiguration();
-					console.log(conf3);
-					doh.assertTrue(setwiseEqual(conf3,[sc._states.Basic5,sc._states.Basic7]));
-
-					doh.assertEqual(sc.x,9);
-					doh.assertEqual(sc.y,1);
-
-					console.info("sending event t4_9")
-					sc.t4_9()
-					var conf4 = sc.getCurrentConfiguration();
-					console.log(conf4);
-					doh.assertTrue(setwiseEqual(conf4,[sc._states.Basic2]));
-
-					doh.assertEqual(sc.x,3);
-					doh.assertEqual(sc.y,3);
-
-					console.info("sending event t5")
-					sc.t5()
-					var conf5 = sc.getCurrentConfiguration();
-					console.log(conf5);
-					doh.assertTrue(setwiseEqual(conf5,[sc._states.Basic1]));
-
-					console.info("sending event t2_7")
-					sc.t2_7()
-					var conf6 = sc.getCurrentConfiguration();
-					console.log(conf6);
-					doh.assertTrue(setwiseEqual(conf6,[sc._states.Basic5,sc._states.Basic7]));
-
-					doh.assertEqual(sc.x,81);
-					doh.assertEqual(sc.y,3);
-
-					console.info("sending event t8")
-					sc.t8()
-					var conf7 = sc.getCurrentConfiguration();
-					console.log(conf7);
-					doh.assertTrue(setwiseEqual(conf7,[sc._states.Basic4,sc._states.Basic7]));
-
-					console.info("sending event t4_9")
-					sc.t4_9()
-					var conf8 = sc.getCurrentConfiguration();
-					console.log(conf8);
-					doh.assertTrue(setwiseEqual(conf8,[sc._states.Basic3]));
-
-					doh.assertEqual(sc.x,9);
-					doh.assertEqual(sc.y,9);
-
-					//TODO: hook this up with doh.Deferred...
-					/*
-					var deferred = new doh.Deferred();
-					window.setTimeout(function(){
-						var conf9 = sc.getCurrentConfiguration();
-						console.log(conf9);
-						deferred.callback(setwiseEqual(conf9,[sc._states.FinalState]));
-					},1500);
-					return deferred;
-					*/
-				},
-				tearDown:function(){
-					 sc.destroy();
+require.def( "test/kitchen_sink/scripts/unitTest_executableContent",
+{
+	scxmlTest:"test/kitchen_sink/KitchenSink_executableContent.xml",
+
+	register:function(scConstructor){
+
+		//TODO: can load this using RequireJS, so we don't need to use the dojo module system?
+		dojo.require("doh.runner");
+
+		var sc;
+		doh.register("testKitchenSinkSuite",[
+				{
+					name:"testAll",
+					//timeout:5000,
+					setUp:function(){
+						sc = new scConstructor()
+						sc.initialize();
+					},
+					runTest:function(){
+						var conf0 = sc.getCurrentConfiguration();
+						console.log(conf0);
+						doh.assertTrue(setwiseEqual(conf0,[sc._states.Basic1]));
+
+						doh.assertEqual(sc.x,0);
+						doh.assertEqual(sc.y,0);
+
+						console.info("sending event t1")
+						sc.t1()
+						var conf1 = sc.getCurrentConfiguration();
+						console.log(conf1);
+						doh.assertTrue(setwiseEqual(conf1,[sc._states.Basic2]));
+
+						doh.assertEqual(sc.x,1);
+						doh.assertEqual(sc.y,0);
+
+
+						console.info("sending event t2_7")
+						sc.t2_7()
+						var conf2 = sc.getCurrentConfiguration();
+						console.log(conf2);
+						doh.assertTrue(setwiseEqual(conf2,[sc._states.Basic4,sc._states.Basic6]));
+
+						doh.assertEqual(sc.x,9);
+						doh.assertEqual(sc.y,0);
+
+						console.info("sending event t3")
+						sc.t3()
+						var conf3 = sc.getCurrentConfiguration();
+						console.log(conf3);
+						doh.assertTrue(setwiseEqual(conf3,[sc._states.Basic5,sc._states.Basic7]));
+
+						doh.assertEqual(sc.x,9);
+						doh.assertEqual(sc.y,1);
+
+						console.info("sending event t4_9")
+						sc.t4_9()
+						var conf4 = sc.getCurrentConfiguration();
+						console.log(conf4);
+						doh.assertTrue(setwiseEqual(conf4,[sc._states.Basic2]));
+
+						doh.assertEqual(sc.x,3);
+						doh.assertEqual(sc.y,3);
+
+						console.info("sending event t5")
+						sc.t5()
+						var conf5 = sc.getCurrentConfiguration();
+						console.log(conf5);
+						doh.assertTrue(setwiseEqual(conf5,[sc._states.Basic1]));
+
+						console.info("sending event t2_7")
+						sc.t2_7()
+						var conf6 = sc.getCurrentConfiguration();
+						console.log(conf6);
+						doh.assertTrue(setwiseEqual(conf6,[sc._states.Basic5,sc._states.Basic7]));
+
+						doh.assertEqual(sc.x,81);
+						doh.assertEqual(sc.y,3);
+
+						console.info("sending event t8")
+						sc.t8()
+						var conf7 = sc.getCurrentConfiguration();
+						console.log(conf7);
+						doh.assertTrue(setwiseEqual(conf7,[sc._states.Basic4,sc._states.Basic7]));
+
+						console.info("sending event t4_9")
+						sc.t4_9()
+						var conf8 = sc.getCurrentConfiguration();
+						console.log(conf8);
+						doh.assertTrue(setwiseEqual(conf8,[sc._states.Basic3]));
+
+						doh.assertEqual(sc.x,9);
+						doh.assertEqual(sc.y,9);
+
+						//TODO: hook this up with doh.Deferred...
+						/*
+						var deferred = new doh.Deferred();
+						window.setTimeout(function(){
+							var conf9 = sc.getCurrentConfiguration();
+							console.log(conf9);
+							deferred.callback(setwiseEqual(conf9,[sc._states.FinalState]));
+						},1500);
+						return deferred;
+						*/
+					},
+					tearDown:function(){
+						 sc.destroy();
+					}
 				}
-			}
-	]);
-})()
+		]);
+	}
+});
 

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/test/test_with_xsltproc.sh
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/test/test_with_xsltproc.sh?rev=958227&r1=958226&r2=958227&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/test/test_with_xsltproc.sh (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/test/test_with_xsltproc.sh Sat Jun 26 13:51:22 2010
@@ -17,7 +17,7 @@ xsltproc ../src/xslt/ir-compiler/numberS
 xmlindent > tmp_IR.xml;
 
 #uncomment to compile IR to js
-#xsltproc ../src/xslt/ir-compiler/StatePatternStatechartGenerator.xsl tmp_IR.xml > out.js
+xsltproc ../build/StatePatternStatechartGenerator_combined.xsl tmp_IR.xml > out.js
 
 #uncomment to prettify js. need to have beautify.js, beautify-cl.js and beautify-html.js in this directory
 #java -cp ../lib/java/js.jar org.mozilla.javascript.tools.shell.Main -debug beautify-cl.js -i 4 out.js > out_pretty.js