You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by gt...@apache.org on 2012/12/13 22:44:47 UTC

svn commit: r1421558 - in /river/jtsk/skunk/surrogate: nbproject/ src/org/apache/river/container/ src/org/apache/river/container/deployer/ src/org/apache/river/container/hsm/ test/org/apache/river/container/hsm/ test/org/apache/river/container/work/

Author: gtrasuk
Date: Thu Dec 13 21:44:43 2012
New Revision: 1421558

URL: http://svn.apache.org/viewvc?rev=1421558&view=rev
Log:
Did some work on the state machine that controls application startup and shutdown.

Added:
    river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceDeployerMXBean.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceLifeCycle.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceLifeCycleSM.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeAndTransitionEvaluator.java
      - copied, changed from r1408168, river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeEvaluator.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidAndTransitionEvaluator.java
      - copied, changed from r1408168, river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidEvaluator.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/Transition.java
      - copied, changed from r1408168, river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/State.java
    river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedMachineTest.java
    river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedTestSM.java
    river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedTestSMInterface.java
    river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/ReturnTypeTest.java
Modified:
    river/jtsk/skunk/surrogate/nbproject/build-impl.xml
    river/jtsk/skunk/surrogate/nbproject/genfiles.properties
    river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
    river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeEvaluator.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidEvaluator.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachine.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachineFactory.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachineImpl.java
    river/jtsk/skunk/surrogate/test/org/apache/river/container/work/ContextualWorkManagerTest.java

Modified: river/jtsk/skunk/surrogate/nbproject/build-impl.xml
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/nbproject/build-impl.xml?rev=1421558&r1=1421557&r2=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/nbproject/build-impl.xml (original)
+++ river/jtsk/skunk/surrogate/nbproject/build-impl.xml Thu Dec 13 21:44:43 2012
@@ -12,9 +12,9 @@ is divided into following sections:
   - execution
   - debugging
   - javadoc
-  - junit compilation
-  - junit execution
-  - junit debugging
+  - test compilation
+  - test execution
+  - test debugging
   - applet
   - cleanup
 
@@ -156,6 +156,7 @@ is divided into following sections:
             </and>
         </condition>
         <property name="run.jvmargs" value=""/>
+        <property name="run.jvmargs.ide" value=""/>
         <property name="javac.compilerargs" value=""/>
         <property name="work.dir" value="${basedir}"/>
         <condition property="no.deps">
@@ -200,6 +201,27 @@ is divided into following sections:
         <property name="jar.index.metainf" value="${jar.index}"/>
         <property name="copylibs.rebase" value="true"/>
         <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
+        <condition property="junit.available">
+            <or>
+                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
+                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
+            </or>
+        </condition>
+        <condition property="testng.available">
+            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
+        </condition>
+        <condition property="junit+testng.available">
+            <and>
+                <istrue value="${junit.available}"/>
+                <istrue value="${testng.available}"/>
+            </and>
+        </condition>
+        <condition else="testng" property="testng.mode" value="mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <condition else="" property="testng.debug.mode" value="-mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
     </target>
     <target name="-post-init">
         <!-- Empty placeholder for easier customization. -->
@@ -332,11 +354,52 @@ is divided into following sections:
             </sequential>
         </macrodef>
     </target>
-    <target name="-init-macrodef-junit">
+    <target if="${junit.available}" name="-init-macrodef-junit-init">
+        <condition else="false" property="nb.junit.batch" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <not>
+                    <isset property="test.method"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="nb.junit.single" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <isset property="test.method"/>
+            </and>
+        </condition>
+    </target>
+    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
         <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
             <attribute default="${includes}" name="includes"/>
             <attribute default="${excludes}" name="excludes"/>
             <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
             <sequential>
                 <property name="junit.forkmode" value="perTest"/>
                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
@@ -345,32 +408,270 @@ is divided into following sections:
                             <filename name="@{testincludes}"/>
                         </fileset>
                     </batchtest>
-                    <classpath>
-                        <path path="${run.test.classpath}"/>
-                    </classpath>
                     <syspropertyset>
                         <propertyref prefix="test-sys-prop."/>
                         <mapper from="test-sys-prop.*" to="*" type="glob"/>
                     </syspropertyset>
                     <formatter type="brief" usefile="false"/>
                     <formatter type="xml"/>
-                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
                     <jvmarg value="-ea"/>
-                    <jvmarg line="${run.jvmargs}"/>
+                    <customize/>
                 </junit>
             </sequential>
         </macrodef>
     </target>
-    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" name="profile-init"/>
-    <target name="-profile-pre-init">
+    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
+    <target if="${testng.available}" name="-init-macrodef-testng">
+        <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
+                    <isset property="test.method"/>
+                </condition>
+                <union id="test.set">
+                    <fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">
+                        <filename name="@{testincludes}"/>
+                    </fileset>
+                </union>
+                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
+                <testng classfilesetref="test.set" failureProperty="tests.failed" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="RiverSurrogate" testname="TestNG tests" workingDir="${work.dir}">
+                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
+                    <propertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </propertyset>
+                    <customize/>
+                </testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-test-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <echo>No tests executed.</echo>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
+        <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <sequential>
+                <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customize>
+                </j2seproject3:test-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                            <filename name="@{testincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
+        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:junit-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${testng.available}" name="-init-macrodef-testng-debug">
+        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element name="customize2" optional="true"/>
+            <sequential>
+                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
+                    <isset property="test.method"/>
+                </condition>
+                <condition else="-suitename RiverSurrogate -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
+                    <matches pattern=".*\.xml" string="@{testClass}"/>
+                </condition>
+                <delete dir="${build.test.results.dir}" quiet="true"/>
+                <mkdir dir="${build.test.results.dir}"/>
+                <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">
+                    <customize>
+                        <customize2/>
+                        <jvmarg value="-ea"/>
+                        <arg line="${testng.debug.mode}"/>
+                        <arg line="-d ${build.test.results.dir}"/>
+                        <arg line="-listener org.testng.reporters.VerboseReporter"/>
+                        <arg line="${testng.cmd.args}"/>
+                    </customize>
+                </j2seproject3:debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
+        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element implicit="true" name="customize2" optional="true"/>
+            <sequential>
+                <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2/>
+                </j2seproject3:testng-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customize>
+                </j2seproject3:test-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2>
+                        <syspropertyset>
+                            <propertyref prefix="test-sys-prop."/>
+                            <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                        </syspropertyset>
+                    </customize2>
+                </j2seproject3:testng-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
+    <!--
+                pre NB7.2 profiling section; consider it deprecated
+            -->
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
+    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
         <!-- Empty placeholder for easier customization. -->
         <!-- You can override this target in the ../build.xml file. -->
     </target>
-    <target name="-profile-post-init">
+    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
         <!-- Empty placeholder for easier customization. -->
         <!-- You can override this target in the ../build.xml file. -->
     </target>
-    <target name="-profile-init-macrodef-profile">
+    <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile">
         <macrodef name="resolve">
             <attribute name="name"/>
             <attribute name="value"/>
@@ -402,10 +703,13 @@ is divided into following sections:
             </sequential>
         </macrodef>
     </target>
-    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" name="-profile-init-check">
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check">
         <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
         <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
     </target>
+    <!--
+                end of pre NB7.2 profiling section
+            -->
     <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
         <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
             <attribute default="${main.class}" name="name"/>
@@ -463,6 +767,7 @@ is divided into following sections:
                     <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
                     <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
                     <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
                     <classpath>
                         <path path="@{classpath}"/>
                     </classpath>
@@ -479,6 +784,7 @@ is divided into following sections:
         <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
             <attribute default="${main.class}" name="classname"/>
             <attribute default="${run.classpath}" name="classpath"/>
+            <attribute default="jvm" name="jvm"/>
             <element name="customize" optional="true"/>
             <sequential>
                 <java classname="@{classname}" dir="${work.dir}" fork="true">
@@ -486,6 +792,7 @@ is divided into following sections:
                     <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
                     <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
                     <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
                     <classpath>
                         <path path="@{classpath}"/>
                     </classpath>
@@ -512,6 +819,9 @@ is divided into following sections:
                     <path path="${run.classpath.without.build.classes.dir}"/>
                     <chainedmapper>
                         <flattenmapper/>
+                        <filtermapper>
+                            <replacestring from=" " to="%20"/>
+                        </filtermapper>
                         <globmapper from="*" to="lib/*"/>
                     </chainedmapper>
                 </pathconvert>
@@ -557,7 +867,7 @@ is divided into following sections:
     <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
         <property name="ap.cmd.line.internal" value=""/>
     </target>
-    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
     <!--
                 ===================
                 COMPILATION SECTION
@@ -773,7 +1083,11 @@ is divided into following sections:
                 PROFILING SECTION
                 =================
             -->
-    <target depends="profile-init,compile" description="Profile a project in the IDE." if="netbeans.home" name="profile">
+    <!--
+                pre NB7.2 profiler integration
+            -->
+    <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
         <nbprofiledirect>
             <classpath>
                 <path path="${run.classpath}"/>
@@ -781,8 +1095,9 @@ is divided into following sections:
         </nbprofiledirect>
         <profile/>
     </target>
-    <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="netbeans.home" name="profile-single">
+    <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72">
         <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
         <nbprofiledirect>
             <classpath>
                 <path path="${run.classpath}"/>
@@ -790,12 +1105,8 @@ is divided into following sections:
         </nbprofiledirect>
         <profile classname="${profile.class}"/>
     </target>
-    <!--
-                =========================
-                APPLET PROFILING  SECTION
-                =========================
-            -->
-    <target depends="profile-init,compile-single" if="netbeans.home" name="profile-applet">
+    <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
         <nbprofiledirect>
             <classpath>
                 <path path="${run.classpath}"/>
@@ -807,12 +1118,8 @@ is divided into following sections:
             </customize>
         </profile>
     </target>
-    <!--
-                =========================
-                TESTS PROFILING  SECTION
-                =========================
-            -->
-    <target depends="profile-init,compile-test-single" if="netbeans.home" name="profile-test-single">
+    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
         <nbprofiledirect>
             <classpath>
                 <path path="${run.test.classpath}"/>
@@ -835,6 +1142,42 @@ is divided into following sections:
         </junit>
     </target>
     <!--
+                end of pre NB72 profiling section
+            -->
+    <target if="netbeans.home" name="-profile-check">
+        <condition property="profiler.configured">
+            <or>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
+            </or>
+        </condition>
+    </target>
+    <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
+        <startprofiler/>
+        <antcall target="run"/>
+    </target>
+    <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcall target="run-single"/>
+    </target>
+    <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/>
+    <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <startprofiler/>
+        <antcall target="test-single"/>
+    </target>
+    <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcal target="run-test-with-main"/>
+    </target>
+    <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <startprofiler/>
+        <antcall target="run-applet"/>
+    </target>
+    <!--
                 ===============
                 JAVADOC SECTION
                 ===============
@@ -877,7 +1220,7 @@ is divided into following sections:
     <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
     <!--
                 =========================
-                JUNIT COMPILATION SECTION
+                TEST COMPILATION SECTION
                 =========================
             -->
     <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
@@ -920,14 +1263,14 @@ is divided into following sections:
     <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
     <!--
                 =======================
-                JUNIT EXECUTION SECTION
+                TEST EXECUTION SECTION
                 =======================
             -->
     <target depends="init" if="have.tests" name="-pre-test-run">
         <mkdir dir="${build.test.results.dir}"/>
     </target>
     <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
-        <j2seproject3:junit testincludes="**/*Test.java"/>
+        <j2seproject3:test testincludes="**/*Test.java"/>
     </target>
     <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
         <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
@@ -940,39 +1283,40 @@ is divided into following sections:
     </target>
     <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
         <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
-        <j2seproject3:junit excludes="" includes="${test.includes}"/>
+        <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
     </target>
     <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
         <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
     </target>
     <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
+        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
     <!--
                 =======================
-                JUNIT DEBUGGING SECTION
+                TEST DEBUGGING SECTION
                 =======================
             -->
-    <target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
         <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
-        <property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
-        <delete file="${test.report.file}"/>
-        <mkdir dir="${build.test.results.dir}"/>
-        <j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
-            <customize>
-                <syspropertyset>
-                    <propertyref prefix="test-sys-prop."/>
-                    <mapper from="test-sys-prop.*" to="*" type="glob"/>
-                </syspropertyset>
-                <arg value="${test.class}"/>
-                <arg value="showoutput=true"/>
-                <arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
-                <arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
-            </customize>
-        </j2seproject3:debug>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
     </target>
     <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
         <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
     </target>
     <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
     <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
         <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
     </target>
@@ -1037,9 +1381,12 @@ is divided into following sections:
     <target name="-check-call-dep">
         <property file="${call.built.properties}" prefix="already.built."/>
         <condition property="should.call.dep">
-            <not>
-                <isset property="already.built.${call.subproject}"/>
-            </not>
+            <and>
+                <not>
+                    <isset property="already.built.${call.subproject}"/>
+                </not>
+                <available file="${call.script}"/>
+            </and>
         </condition>
     </target>
     <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">

Modified: river/jtsk/skunk/surrogate/nbproject/genfiles.properties
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/nbproject/genfiles.properties?rev=1421558&r1=1421557&r2=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/nbproject/genfiles.properties (original)
+++ river/jtsk/skunk/surrogate/nbproject/genfiles.properties Thu Dec 13 21:44:43 2012
@@ -4,8 +4,8 @@ build.xml.stylesheet.CRC32=28e38971@1.38
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
 nbproject/build-impl.xml.data.CRC32=092f50fa
-nbproject/build-impl.xml.script.CRC32=ddb15c4d
-nbproject/build-impl.xml.stylesheet.CRC32=fcddb364@1.50.2.46
+nbproject/build-impl.xml.script.CRC32=740e8a1a
+nbproject/build-impl.xml.stylesheet.CRC32=6ddba6b6@1.53.1.46
 nbproject/management-build-impl.xml.data.CRC32=318d2fde
 nbproject/management-build-impl.xml.script.CRC32=630dcf8f
 nbproject/management-build-impl.xml.stylesheet.CRC32=545273be@1.1

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java?rev=1421558&r1=1421557&r2=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java Thu Dec 13 21:44:43 2012
@@ -81,6 +81,7 @@ public class MessageNames {
             ILLEGAL_ARGUMENT_EXCEPTION="illegalArgumentException",
             ILLEGAL_ACCESS_EXCEPTION="illegalAccessException",
             INITIALIZATION_EXCEPTION="initializationException",
+            INTIALIZING_EVENT_TABLE="initializingEventTable",
             INVALID_CLASSPATH_ENTRY="invalidClasspathEntry",
             INVOCATION_TARGET_EXCEPTION="invocationTargetException",
             INIT_METHOD_HAS_PARAMETERS="initMethodHasParameters",

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties?rev=1421558&r1=1421557&r2=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties Thu Dec 13 21:44:43 2012
@@ -61,6 +61,7 @@ illegalArgumentException=An operation th
 illegalAccessException=An operation threw an IllegalAccessException.
 invalidClasspathEntry=Invalid classpath entry: {0}
 invocationTargetException=An operation threw an InvocationTargetException.
+initializingEventTable=Initializing event table for class ''{0}''.
 initializationException=An exception has occured while initializing the container.
 initMethodHasParameters=A method flagged as @Init must take no parameters.  \
 Method ''{1}'' on class ''{0}'' has parameters.

Added: river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceDeployerMXBean.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceDeployerMXBean.java?rev=1421558&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceDeployerMXBean.java (added)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceDeployerMXBean.java Thu Dec 13 21:44:43 2012
@@ -0,0 +1,26 @@
+/*
+ * 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. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.apache.river.container.deployer;
+
+/**
+ *
+ * @author trasukg
+ */
+public interface StarterServiceDeployerMXBean {
+    public String shutdown(String appId);
+}

Added: river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceLifeCycle.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceLifeCycle.java?rev=1421558&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceLifeCycle.java (added)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceLifeCycle.java Thu Dec 13 21:44:43 2012
@@ -0,0 +1,28 @@
+/*
+ * 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. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.apache.river.container.deployer;
+
+/**
+ * Life cycle state controller interface for a Starter Service application.
+ * @author trasukg
+ */
+public interface StarterServiceLifeCycle {
+    public void start();
+    
+    public void stop();
+}

Added: river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceLifeCycleSM.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceLifeCycleSM.java?rev=1421558&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceLifeCycleSM.java (added)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/deployer/StarterServiceLifeCycleSM.java Thu Dec 13 21:44:43 2012
@@ -0,0 +1,78 @@
+/*
+ * 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. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.apache.river.container.deployer;
+
+import java.util.logging.Logger;
+import org.apache.river.container.MessageNames;
+import org.apache.river.container.hsm.Controller;
+import org.apache.river.container.hsm.Initial;
+import org.apache.river.container.hsm.RootState;
+import org.apache.river.container.hsm.State;
+import org.apache.river.container.hsm.StateMachine;
+
+/**
+ * Life cycle controller for "service-starter" services.
+ * Idle --> Starting --> Running --> Stopping --> Idle
+ *                                              --> Zombie
+ */
+@RootState(StarterServiceLifeCycle.class)
+public class StarterServiceLifeCycleSM implements StarterServiceLifeCycle {
+    
+    private static final Logger logger=Logger.getLogger(StarterServiceLifeCycleSM.class.getName(),
+            MessageNames.BUNDLE_NAME);
+    
+    private ApplicationEnvironment appEnv=null;
+    private StarterServiceDeployer deployer=null;
+    
+    public StarterServiceLifeCycleSM(ApplicationEnvironment appEnv, StarterServiceDeployer deployer) {
+        this.appEnv=appEnv;
+        this.deployer=deployer;
+    }
+    
+    @State({Idle.class, Starting.class, Running.class, Stopping.class, Idle.class})
+    @Initial(Idle.class)
+    private Object state;
+    
+    @Controller
+    private StateMachine controller;
+
+    @Override
+    public void start() {
+    }
+
+    @Override
+    public void stop() {
+    }
+    
+    public class Idle {
+        
+    }
+    
+    public class Running {
+        
+    }
+    
+    public class Stopping {
+        
+    }
+    
+    public class Starting {
+        
+    }
+    
+}

Copied: river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeAndTransitionEvaluator.java (from r1408168, river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeEvaluator.java)
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeAndTransitionEvaluator.java?p2=river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeAndTransitionEvaluator.java&p1=river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeEvaluator.java&r1=1408168&r2=1421558&rev=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeEvaluator.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeAndTransitionEvaluator.java Thu Dec 13 21:44:43 2012
@@ -17,6 +17,7 @@
  */
 package org.apache.river.container.hsm;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -25,18 +26,20 @@ import java.util.logging.Logger;
  *
  * @author trasukg
  */
-class InvokeEvaluator implements Evaluator {
+class InvokeAndTransitionEvaluator implements Evaluator {
 
-    private static final Logger log = Logger.getLogger(InvokeEvaluator.class.getName());
+    private static final Logger log = Logger.getLogger(InvokeAndTransitionEvaluator.class.getName());
     Object instance;
     StateMachineImpl machine;
     Method targetMethod;
-
-    public InvokeEvaluator(StateMachineImpl machine,
-            Object instance, Method targetMethod) {
+    Class[] targetStates;
+    
+    public InvokeAndTransitionEvaluator(StateMachineImpl machine,
+            Object instance, Method targetMethod, Class[] targetStates) {
         this.machine = machine;
         this.instance = instance;
         this.targetMethod = targetMethod;
+        this.targetStates = targetStates;
     }
 
     public void eval(Object[] args) {
@@ -47,6 +50,8 @@ class InvokeEvaluator implements Evaluat
                             instance.getClass().getSimpleName()});
             }
             machine.output = targetMethod.invoke(instance, args);
+        } catch(InvocationTargetException e) {
+            machine.exception = e.getCause();
         } catch (Exception ex) {
             log.log(Level.SEVERE, "Applying event {0} to state {1} instance {2}",
                     new Object[]{targetMethod.getName(),
@@ -54,5 +59,9 @@ class InvokeEvaluator implements Evaluat
             log.log(Level.SEVERE,
                     "Error invoking target method on state instance", ex);
         }
+        // Execute the transitions
+        for (Class c:targetStates) {
+            machine.transition(c);
+        }
     }
 }

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeEvaluator.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeEvaluator.java?rev=1421558&r1=1421557&r2=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeEvaluator.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeEvaluator.java Thu Dec 13 21:44:43 2012
@@ -17,6 +17,7 @@
  */
 package org.apache.river.container.hsm;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -47,6 +48,8 @@ class InvokeEvaluator implements Evaluat
                             instance.getClass().getSimpleName()});
             }
             machine.output = targetMethod.invoke(instance, args);
+        } catch(InvocationTargetException e) {
+            machine.exception = e.getCause();
         } catch (Exception ex) {
             log.log(Level.SEVERE, "Applying event {0} to state {1} instance {2}",
                     new Object[]{targetMethod.getName(),

Copied: river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidAndTransitionEvaluator.java (from r1408168, river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidEvaluator.java)
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidAndTransitionEvaluator.java?p2=river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidAndTransitionEvaluator.java&p1=river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidEvaluator.java&r1=1408168&r2=1421558&rev=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidEvaluator.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidAndTransitionEvaluator.java Thu Dec 13 21:44:43 2012
@@ -18,6 +18,7 @@
 
 package org.apache.river.container.hsm;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -26,26 +27,34 @@ import java.util.logging.Logger;
  *
  * @author trasukg
  */
-class InvokeVoidEvaluator implements Evaluator {
-    private static final Logger log=Logger.getLogger(InvokeVoidEvaluator.class.getName());
+class InvokeVoidAndTransitionEvaluator implements Evaluator {
+    private static final Logger log=Logger.getLogger(InvokeVoidAndTransitionEvaluator.class.getName());
 
     Object instance;
     StateMachineImpl machine;
     Method targetMethod;
-
-    public InvokeVoidEvaluator(StateMachineImpl machine, 
-            Object instance, Method targetMethod) {
+    Class[] targetStates;
+    
+    public InvokeVoidAndTransitionEvaluator(StateMachineImpl machine, 
+            Object instance, Method targetMethod, Class[] targetStates) {
         this.machine=machine;
         this.instance=instance;
         this.targetMethod=targetMethod;
+        this.targetStates=targetStates;
     }
 
     public void eval(Object[] args) {
         try {
             targetMethod.invoke(instance, args);
+        } catch (InvocationTargetException e) {
+            machine.exception=e.getCause();
         } catch(Exception ex) {
             log.log(Level.SEVERE, "Error invoking target method on state instance", ex);
         }
+        // Execute transitions
+        for (Class c: targetStates) {
+            machine.transition(c);
+        }
     }
 
 }

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidEvaluator.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidEvaluator.java?rev=1421558&r1=1421557&r2=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidEvaluator.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/InvokeVoidEvaluator.java Thu Dec 13 21:44:43 2012
@@ -18,6 +18,7 @@
 
 package org.apache.river.container.hsm;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -43,6 +44,8 @@ class InvokeVoidEvaluator implements Eva
     public void eval(Object[] args) {
         try {
             targetMethod.invoke(instance, args);
+        } catch (InvocationTargetException e) {
+            machine.exception=e.getCause();
         } catch(Exception ex) {
             log.log(Level.SEVERE, "Error invoking target method on state instance", ex);
         }

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachine.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachine.java?rev=1421558&r1=1421557&r2=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachine.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachine.java Thu Dec 13 21:44:43 2012
@@ -15,18 +15,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.river.container.hsm;
 
+import java.util.List;
+
 /**
  *
  * @author trasukg
  */
 public interface StateMachine {
+
     /**
-     Initiate a transition to the target state.
-     @param targetState
+     * Initiate a transition to the target state.
+     *
+     * @param targetState
      */
     public void transition(Class targetState);
-    
+
+    /**
+     * Get all the states that are active in this state machine.
+     * @return
+     * @throws IllegalArgumentException
+     * @throws IllegalAccessException 
+     */
+    public List<Class> getActiveStates() throws IllegalArgumentException, IllegalAccessException;
 }

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachineFactory.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachineFactory.java?rev=1421558&r1=1421557&r2=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachineFactory.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachineFactory.java Thu Dec 13 21:44:43 2012
@@ -37,7 +37,7 @@ class StateMachineFactory {
     </p>
 
     <p>
-    The class must be annotated with the @HSMRoot annotation and supplied
+    The class must be annotated with the @RootState annotation and supplied
     event interface.
     </p>
 
@@ -49,17 +49,21 @@ class StateMachineFactory {
     @param aClass A class annotated with @HSMRoot.
     @return
      */
-    static Object createStateMachine(Class aClass) throws InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
+    public static Object createStateMachine(Class aClass) throws InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
         // Create a dynamic proxy for the given class.
 
         /* Check the annotation to find out the event interface.
          */
-        RootState ann = (RootState) aClass.getAnnotation(RootState.class);
-        Class eventInterface = ann.value();
         Object rootState = aClass.newInstance();
+        return createStateMachine(rootState);
+    }
+
+    public static Object createStateMachine(Object rootState) throws InvocationTargetException, IllegalAccessException, IllegalArgumentException, NoSuchMethodException, InstantiationException {
+        RootState ann = (RootState) rootState.getClass().getAnnotation(RootState.class);
+        Class eventInterface = ann.value();
         StateMachineImpl machine=new StateMachineImpl();
-        machine.initializeEventTable(aClass, eventInterface);
         machine.rootState=rootState;
+        machine.initializeEventTable(rootState.getClass(), eventInterface);
         machine.updateActiveStatesAndRunEntryMethods();
         Object proxy =
                 Proxy.newProxyInstance(eventInterface.getClassLoader(),

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachineImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachineImpl.java?rev=1421558&r1=1421557&r2=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachineImpl.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/StateMachineImpl.java Thu Dec 13 21:44:43 2012
@@ -26,7 +26,9 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import org.apache.river.container.hsm.Controller;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.river.container.MessageNames;
 
 /**
  *
@@ -34,8 +36,10 @@ import org.apache.river.container.hsm.Co
  */
 class StateMachineImpl implements StateMachine, InvocationHandler {
 
+    Logger log = Logger.getLogger(StateMachineImpl.class.getName(), MessageNames.BUNDLE_NAME);
     Object rootState;
     Object output = null;
+    Throwable exception = null;
     List<Class> transitions = new ArrayList<Class>(20);
     Map<Class, ClassInfo> classTable =
             new HashMap<Class, ClassInfo>();
@@ -49,11 +53,14 @@ class StateMachineImpl implements StateM
     }
 
     /**
-    Initialize the event table for a class, given an event interface.
-    @param aClass
-    @param eventInterface
+     * Initialize the event table for a class, given an event interface.
+     *
+     * @param aClass
+     * @param eventInterface
      */
     void initializeEventTable(Class aClass, Class eventInterface) throws InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
+        log.log(Level.FINE, MessageNames.INTIALIZING_EVENT_TABLE, aClass.getName());
+
         // Create the class info entry
         ClassInfo classInfo = new ClassInfo();
         // Store the class info in the overall table.
@@ -65,7 +72,7 @@ class StateMachineImpl implements StateM
         classInfo.setInstance(createInstance(aClass));
 
         /* Populate the substates, then initialize event table for all the
-        possible substates. */
+         possible substates. */
         populateClassInfo(classInfo);
         processSubstates(classInfo, eventInterface);
         buildMethodMap(eventInterface, classInfo);
@@ -81,8 +88,8 @@ class StateMachineImpl implements StateM
     private void buildMethodMap(Class eventInterface, ClassInfo classInfo) throws SecurityException {
         for (Method m : eventInterface.getMethods()) {
             /*
-            If there are substates, then the evaluator has to run the
-            event on each substate, then run our event handler.
+             If there are substates, then the evaluator has to run the
+             event on each substate, then run our event handler.
              */
             List<Evaluator> evaluators = new ArrayList<Evaluator>();
             for (SubstateInfo ssi : classInfo.getSubstateInfo()) {
@@ -111,13 +118,14 @@ class StateMachineImpl implements StateM
         Object initialInstance = classTable.get(ssi.getInitialState()).getInstance();
         ssi.getField().set(classInfo.getInstance(), initialInstance);
         /* If the state isn't supposed to be retained, add state setter to
-        entryEvaluator. */
+         entryEvaluator. */
         if (!ssi.isRetained()) {
             classInfo.onEntryEvaluator.add(new SetFieldEvaluator(ssi.getField(),
                     classInfo.instance, initialInstance));
         }
     }
 
+    @Override
     public synchronized Object invoke(Object proxy, Method method, Object[] args)
             throws Throwable {
         /* Lookup evaluator for this event on the root state's class */
@@ -125,16 +133,20 @@ class StateMachineImpl implements StateM
                 classTable.get(rootState.getClass()).getMethodMap().get(method);
 
         /* Run that evaluator, which will have been created with knowledge
-        of the output register. */
+         of the output register. */
         output = null;
+        exception = null;
         transitions.clear();
         evaluator.eval(args);
         applyTransitions();
+        if (exception != null) {
+            throw exception;
+        }
         return output;
     }
 
     /**
-    Apply the transitions that were accumulated during the event run.
+     * Apply the transitions that were accumulated during the event run.
      */
     private void applyTransitions() throws IllegalArgumentException, IllegalAccessException {
         while (!transitions.isEmpty()) {
@@ -199,23 +211,35 @@ class StateMachineImpl implements StateM
     }
 
     /**
-    Create the evaluator that runs the method on the class pointed to by
-    classInfo.
-    @param classInfo
-    @param m
-    @return
+     * Create the evaluator that runs the method on the class pointed to by
+     * classInfo.
+     *
+     * @param classInfo
+     * @param m
+     * @return
      */
     private Evaluator createEvaluator(ClassInfo classInfo, Method m) {
         try {
             Method targetMethod =
                     classInfo.getTargetClass().getMethod(m.getName(),
                     m.getParameterTypes());
-            if (targetMethod.getReturnType() == null) {
-                return new InvokeVoidEvaluator(this, classInfo.getInstance(),
-                        targetMethod);
+            Transition transition = targetMethod.getAnnotation(Transition.class);
+            if (transition == null) {
+                if (targetMethod.getReturnType() == Void.class) {
+                    return new InvokeVoidEvaluator(this, classInfo.getInstance(),
+                            targetMethod);
+                } else {
+                    return new InvokeEvaluator(this, classInfo.getInstance(),
+                            targetMethod);
+                }
             } else {
-                return new InvokeEvaluator(this, classInfo.getInstance(),
-                        targetMethod);
+               if (targetMethod.getReturnType() == Void.class) {
+                    return new InvokeVoidAndTransitionEvaluator(this, classInfo.getInstance(),
+                            targetMethod, transition.value());
+                } else {
+                    return new InvokeAndTransitionEvaluator(this, classInfo.getInstance(),
+                            targetMethod, transition.value());
+                }
             }
         } catch (NoSuchMethodException nsme) {
             return new NopEvaluator();
@@ -257,22 +281,27 @@ class StateMachineImpl implements StateM
     }
 
     /**
-    Create an instance of the a state class, even if it happens to be an
-    inner class of another state class.
-    <p>
-    A frequent pattern is to have the substate classes listed as inner classes
-    on their enclosing state's class, allowing sharing of attributes.  So we
-    need to allow an instance to be created, even if the class is not static.
-    </p>
-
-    <p>
-    The only requirement is that the enclosing class is also a class within
-    the state machine.
-    </p>
-    @param aClass
-    @return
+     * Create an instance of the a state class, even if it happens to be an
+     * inner class of another state class. <p> A frequent pattern is to have the
+     * substate classes listed as inner classes on their enclosing state's
+     * class, allowing sharing of attributes. So we need to allow an instance to
+     * be created, even if the class is not static. </p>
+     *
+     * <p> The only requirement is that the enclosing class is also a class
+     * within the state machine. </p>
+     *
+     * @param aClass
+     * @return
      */
     private Object createInstance(Class aClass) throws InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
+        /* Slightly ugly trap to allow the factory to include an initialized root state.
+         * If rootState is not null, and we're being asked for an instance of the same
+         * class, then use the current rootState value rather than creating a new
+         * instance.
+         */
+        if (rootState != null && aClass == rootState.getClass()) {
+            return rootState;
+        }
         Class enclosingClass = aClass.getEnclosingClass();
         if (enclosingClass == null) {
             return aClass.newInstance();
@@ -283,9 +312,11 @@ class StateMachineImpl implements StateM
     }
 
     /**
-    If the class mentioned has an @Controller annotation, set its reference
-    to the state machine implementation.
-    @param classInfo
+     * If the class mentioned has an
+     *
+     * @Controller annotation, set its reference to the state machine
+     * implementation.
+     * @param classInfo
      */
     private void handleControllerAnnotation(ClassInfo classInfo) throws IllegalArgumentException, IllegalAccessException {
         for (Field f : classInfo.getTargetClass().getDeclaredFields()) {

Copied: river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/Transition.java (from r1408168, river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/State.java)
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/Transition.java?p2=river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/Transition.java&p1=river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/State.java&r1=1408168&r2=1421558&rev=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/State.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/hsm/Transition.java Thu Dec 13 21:44:43 2012
@@ -15,7 +15,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.river.container.hsm;
 
 import java.lang.annotation.Documented;
@@ -25,19 +24,19 @@ import java.lang.annotation.RetentionPol
 import java.lang.annotation.Target;
 
 /**
- Annotation type to indicate a variable that stores a state in a
- hierarchical state machine.  To specify parallel state (AND-States as per
- Harel), simply include more than one field marked with @State.
- * @author trasukg
+ * Annotation type to indicate an unconditional  transition that is applied after an
+ * event method is executed.  
  */
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD)
-public @interface State {
+@Target(ElementType.METHOD)
+public @interface Transition {
+
     /**
-     An array of state classes that reflect the allowable states for this
-     state variable.
-     @return
+     * An array of state classes that reflect the target states for this
+     * state variable.
+     *
+     * @return
      */
     Class[] value();
 }

Added: river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedMachineTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedMachineTest.java?rev=1421558&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedMachineTest.java (added)
+++ river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedMachineTest.java Thu Dec 13 21:44:43 2012
@@ -0,0 +1,85 @@
+/*
+ * 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. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.apache.river.container.hsm;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author trasukg
+ */
+public class InitializedMachineTest {
+
+    public InitializedMachineTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+        Logger.getLogger("org.apache.river.container.hsm").setLevel(Level.FINEST);
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        UUT=new InitializedTestSM();
+        UUTI=(InitializedTestSMInterface) StateMachineFactory.createStateMachine(UUT);
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    InitializedTestSMInterface UUTI=null;
+    InitializedTestSM UUT=null;
+    
+    @Test(expected=IllegalStateException.class)
+    public void testLockedException() throws Exception {
+        UUTI.setValue(20);
+    }
+    
+    /**
+     * If we transition to unlocked, then that means the @Transition tag
+     * was interpreted and executed correctly.
+     */
+    @Test
+    public void testUnlocking() {
+        UUTI.unlock();
+        UUTI.setValue(20);
+    }
+    
+    /**
+     * Test that the methods are executing against the same instance that we
+     * created.
+     */
+    @Test
+    public void testSameInstance() {
+        UUTI.unlock();
+        UUTI.setValue(20);
+        assertEquals("Value through local instance", 20, UUT.getValue());
+    }
+}

Added: river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedTestSM.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedTestSM.java?rev=1421558&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedTestSM.java (added)
+++ river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedTestSM.java Thu Dec 13 21:44:43 2012
@@ -0,0 +1,59 @@
+/*
+ * 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. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.apache.river.container.hsm;
+
+/**
+ * State machine to test whether the state machine correctly uses the supplied
+ * root state object.
+ */
+@RootState(InitializedTestSMInterface.class)
+public class InitializedTestSM {
+        
+    private int value=0;
+    
+    @State({Locked.class, Unlocked.class})
+    @Initial(Locked.class)
+    Object lockedState;
+
+    public int getValue() {
+        return value;
+    }
+    
+    public class Locked {
+        
+        @Transition(Unlocked.class)
+        public void unlock() {
+            System.out.println("Locked.unlock()");
+        }
+        
+        public void setValue(int v) {
+            throw new IllegalStateException("Locked!");
+        }
+    }
+    
+    public class Unlocked {
+        @Transition(Locked.class)
+        public void lock() {
+            System.out.println("Unlocked.lock()");
+        }
+        
+        public void setValue(int v) {
+            value=v;
+        }
+    }
+}

Added: river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedTestSMInterface.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedTestSMInterface.java?rev=1421558&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedTestSMInterface.java (added)
+++ river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/InitializedTestSMInterface.java Thu Dec 13 21:44:43 2012
@@ -0,0 +1,32 @@
+/*
+ * 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. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.apache.river.container.hsm;
+
+/**
+ *
+ * Interface for test of initialized state machine.
+ */
+public interface InitializedTestSMInterface {
+    public void lock();
+    
+    public void unlock();
+    
+    public void setValue(int x);
+    
+    public int getValue();
+}

Added: river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/ReturnTypeTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/ReturnTypeTest.java?rev=1421558&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/ReturnTypeTest.java (added)
+++ river/jtsk/skunk/surrogate/test/org/apache/river/container/hsm/ReturnTypeTest.java Thu Dec 13 21:44:43 2012
@@ -0,0 +1,49 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.apache.river.container.hsm;
+
+import java.lang.reflect.Method;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+/**
+ *
+ * @author trasukg
+ */
+public class ReturnTypeTest {
+    
+    public ReturnTypeTest() {
+    }
+    
+    @BeforeClass
+    public static void setUpClass() {
+    }
+    
+    @AfterClass
+    public static void tearDownClass() {
+    }
+    
+    @Before
+    public void setUp() {
+    }
+    
+    @After
+    public void tearDown() {
+    }
+    
+    /**
+     * Expectation is that if a method is declared to return 'void', then the
+     * 'Method.getReturnType()' value should be null;
+     */
+    @Test
+    public void testVoidReturnType() throws Exception {
+        Method m=this.getClass().getMethod("testVoidReturnType", new Class[0]);
+        assertEquals("return type wasn't null", null, m.getReturnType());
+        
+    }
+}

Modified: river/jtsk/skunk/surrogate/test/org/apache/river/container/work/ContextualWorkManagerTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/test/org/apache/river/container/work/ContextualWorkManagerTest.java?rev=1421558&r1=1421557&r2=1421558&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/test/org/apache/river/container/work/ContextualWorkManagerTest.java (original)
+++ river/jtsk/skunk/surrogate/test/org/apache/river/container/work/ContextualWorkManagerTest.java Thu Dec 13 21:44:43 2012
@@ -26,8 +26,8 @@ import static org.junit.Assert.*;
 import org.junit.Test;
 
 /**
-
- @author trasukg
+ *
+ * @author trasukg
  */
 public class ContextualWorkManagerTest {
 
@@ -52,9 +52,9 @@ public class ContextualWorkManagerTest {
         wt.proceed = true;
     }
 
-    @Test 
+    @Test
     public void testChildThreadGroup() throws Exception {
-        WorkerRunnable wt=new WorkerRunnable();
+        WorkerRunnable wt = new WorkerRunnable();
         context.getWorkManager().queueTask(TaskClass.SYSTEM_TASK, null, wt);
         long start = System.currentTimeMillis();
         while (System.currentTimeMillis() - start < 2000 & context.getActiveThreadCount() < 1) {
@@ -64,10 +64,10 @@ public class ContextualWorkManagerTest {
         assertTrue("Thread group name '" + wt.getThreadGroupName() + "' doesn't start with ctx name",
                 wt.getThreadGroupName().startsWith("Test-ctx"));
     }
-    
-    /** Hold off on this -- not needed yet. 
-    
-    */
+
+    /**
+     * Hold off on this -- not needed yet. *
+     */
     @Test
     public void testThreadCountWithChildren() throws Exception {
         WorkerRunnable wt = new WorkerRunnable(2);
@@ -76,8 +76,9 @@ public class ContextualWorkManagerTest {
         while (System.currentTimeMillis() - start < 2000 & context.getActiveThreadCount() < 1) {
             Thread.yield();
         }
-        Thread.sleep(1000);
+        Thread.sleep(500);
         try {
+            System.out.println("Checking thread count.");
             assertEquals("thread count", 3, context.getActiveThreadCount());
         } finally {
             wt.proceed = true;
@@ -86,10 +87,12 @@ public class ContextualWorkManagerTest {
     }
 
     private class WorkerRunnable extends Thread {
-        String threadGroupName=Strings.UNKNOWN;
+
+        String threadGroupName = Strings.UNKNOWN;
         List<WorkerRunnable> children = new ArrayList<WorkerRunnable>();
         String id = "--";
         boolean proceed = false;
+        int nChildren = 0;
 
         public WorkerRunnable() {
         }
@@ -97,23 +100,38 @@ public class ContextualWorkManagerTest {
         public String getThreadGroupName() {
             return threadGroupName;
         }
-        
+
+        /**
+         * Hmm.. Is it possible that the thread group is assigned at thread
+         * creation time? Of course it is! Looks like the thread group id is
+         * assigned to the parent when the Thread instance is instantiated,
+         * rather than when the thread (i.e. the actual background thread) is
+         * launched.
+         *
+         * @param nChildren
+         */
         public WorkerRunnable(int nChildren) {
-            for (int x = 0; x < nChildren; x++) {
-                WorkerRunnable newWorker = new WorkerRunnable();
-                newWorker.id = "WorkerRunnable-" + x;
-                newWorker.start();
-                children.add(newWorker);
-            }
+            this.nChildren = nChildren;
         }
 
         public void run() {
-            threadGroupName=Thread.currentThread().getThreadGroup().getName();
-            
-            System.out.println("Worker " + id + " beginning.");
+            threadGroupName = Thread.currentThread().getThreadGroup().getName();
+
+            System.out.println("Worker " + id + " beginning in thread group "
+                    + Thread.currentThread().getThreadGroup().getName() + ".");
+            if (nChildren != 0) {
+                for (int x = 0; x < nChildren; x++) {
+                    WorkerRunnable newWorker = new WorkerRunnable();
+                    newWorker.id = "WorkerRunnable-" + (x + 1);
+                    children.add(newWorker);
+                }
+            }
             try {
+                for (WorkerRunnable worker : children) {
+                    worker.start();
+                }
                 while (!proceed) {
-                    Thread.sleep(500);
+                    Thread.sleep(1500);
                 }
             } catch (InterruptedException ex) {
                 Logger.getLogger(ContextualWorkManagerTest.class.getName()).log(Level.SEVERE, null, ex);