[jboss-svn-commits] JBL Code SVN: r23324 - in labs/jbossrules/trunk: drools-compiler/src/main/java/org/drools/compiler and 16 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Oct 6 09:07:47 EDT 2008


Author: KrisVerlaenen
Date: 2008-10-06 09:07:47 -0400 (Mon, 06 Oct 2008)
New Revision: 23324

Added:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/TriggerHandler.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessEventTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessStartTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/DefaultSignalManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/DefaultSignalManagerFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/SignalManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/SignalManagerFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Constrainable.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/ConstraintTrigger.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EventTrigger.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Trigger.java
Modified:
   labs/jbossrules/trunk/drools-compiler/.classpath
   labs/jbossrules/trunk/drools-compiler/.project
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/ProcessBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/ProcessSemanticModule.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/ConstraintHandler.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/EventFilterHandler.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/EventNodeHandler.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/StartNodeHandler.java
   labs/jbossrules/trunk/drools-compiler/src/main/resources/META-INF/drools-processes-4.0.xsd
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessHumanTaskTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessTimerTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java
   labs/jbossrules/trunk/drools-core/.classpath
   labs/jbossrules/trunk/drools-core/.project
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EventNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/HumanTaskNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/MilestoneNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/StartNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/WorkflowProcessInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceFactoryRegistry.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/WorkflowProcessInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/factory/CreateNewNodeFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SubProcessNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/TimerNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java
   labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/parser/ExternalSheetListenerTest.java
Log:
JBRULES-1792: Start node triggers
 - added start node triggers for rules and events
JBRULES-1793: Process instances can listen for external events
 - event nodes can be external and event correlation signals registered process instances

Modified: labs/jbossrules/trunk/drools-compiler/.classpath
===================================================================
--- labs/jbossrules/trunk/drools-compiler/.classpath	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/.classpath	2008-10-06 13:07:47 UTC (rev 23324)
@@ -1,22 +1,22 @@
-<classpath>
-  <classpathentry kind="src" path="src/main/java"/>
-  <classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
-  <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
-  <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
-  <classpathentry kind="output" path="target/classes"/>
-  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-  <classpathentry kind="var" path="M2_REPO/com/thoughtworks/xstream/xstream/1.3/xstream-1.3.jar"/>
-  <classpathentry kind="var" path="M2_REPO/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar"/>
-  <classpathentry kind="var" path="M2_REPO/janino/janino/2.5.15/janino-2.5.15.jar"/>
-  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/antlr/antlr-runtime/3.0.1/antlr-runtime-3.0.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/antlr/gunit/1.0.1/gunit-1.0.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/antlr/antlr/3.0.1/antlr-3.0.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/antlr/antlr/2.7.7/antlr-2.7.7.jar"/>
-  <classpathentry kind="src" path="/drools-core"/>
-  <classpathentry kind="var" path="M2_REPO/org/mvel/mvel/2.0M2/mvel-2.0M2.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/eclipse/jdt/core/3.4.2.v_883_R34x/core-3.4.2.v_883_R34x.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/jmock/jmock/2.5.0.1/jmock-2.5.0.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar"/>
+<classpath>
+  <classpathentry kind="src" path="src/main/java"/>
+  <classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
+  <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
+  <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
+  <classpathentry kind="output" path="target/classes"/>
+  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+  <classpathentry kind="var" path="M2_REPO/com/thoughtworks/xstream/xstream/1.3/xstream-1.3.jar"/>
+  <classpathentry kind="var" path="M2_REPO/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar"/>
+  <classpathentry kind="var" path="M2_REPO/janino/janino/2.5.15/janino-2.5.15.jar"/>
+  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/antlr/antlr-runtime/3.0.1/antlr-runtime-3.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/antlr/gunit/1.0.1/gunit-1.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/antlr/antlr/3.0.1/antlr-3.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/antlr/antlr/2.7.7/antlr-2.7.7.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/drools/drools-core/5.0.0.SNAPSHOT/drools-core-5.0.0.SNAPSHOT.jar" sourcepath="M2_REPO/org/drools/drools-core/5.0.0.SNAPSHOT/drools-core-5.0.0.SNAPSHOT-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/mvel/mvel/2.0-SNAPSHOT/mvel-2.0-SNAPSHOT.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/eclipse/jdt/core/3.4.2.v_883_R34x/core-3.4.2.v_883_R34x.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/jmock/jmock/2.5.0.1/jmock-2.5.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar"/>
 </classpath>
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-compiler/.project
===================================================================
--- labs/jbossrules/trunk/drools-compiler/.project	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/.project	2008-10-06 13:07:47 UTC (rev 23324)
@@ -1,15 +1,13 @@
-<projectDescription>
-  <name>drools-compiler</name>
-  <comment>A rule production system</comment>
-  <projects>
-    <project>drools-core</project>
-  </projects>
-  <buildSpec>
-    <buildCommand>
-      <name>org.eclipse.jdt.core.javabuilder</name>
-    </buildCommand>
-  </buildSpec>
-  <natures>
-    <nature>org.eclipse.jdt.core.javanature</nature>
-  </natures>
+<projectDescription>
+  <name>drools-compiler</name>
+  <comment>A rule production system</comment>
+  <projects/>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+  </natures>
 </projectDescription>
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -32,8 +32,6 @@
 import org.drools.base.ClassFieldAccessor;
 import org.drools.base.ClassFieldAccessorCache;
 import org.drools.base.ClassFieldAccessorStore;
-import org.drools.base.ClassFieldReader;
-import org.drools.base.ClassFieldWriter;
 import org.drools.common.InternalRuleBase;
 import org.drools.commons.jci.problems.CompilationProblem;
 import org.drools.factmodel.ClassBuilder;
@@ -59,14 +57,12 @@
 import org.drools.process.core.Process;
 import org.drools.reteoo.ReteooRuleBase;
 import org.drools.rule.CompositeClassLoader;
-import org.drools.rule.ImportDeclaration;
 import org.drools.rule.JavaDialectRuntimeData;
 import org.drools.rule.Package;
 import org.drools.rule.Rule;
 import org.drools.rule.TypeDeclaration;
 import org.drools.rule.builder.RuleBuildContext;
 import org.drools.rule.builder.RuleBuilder;
-import org.drools.rule.builder.dialect.java.JavaDialect;
 import org.drools.spi.InternalReadAccessor;
 import org.drools.xml.XmlPackageReader;
 import org.drools.xml.XmlProcessReader;

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/ProcessBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/ProcessBuilder.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/ProcessBuilder.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -21,7 +21,6 @@
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -47,8 +46,11 @@
 import org.drools.workflow.core.WorkflowProcess;
 import org.drools.workflow.core.impl.DroolsConsequenceAction;
 import org.drools.workflow.core.impl.WorkflowProcessImpl;
+import org.drools.workflow.core.node.ConstraintTrigger;
 import org.drools.workflow.core.node.MilestoneNode;
 import org.drools.workflow.core.node.Split;
+import org.drools.workflow.core.node.StartNode;
+import org.drools.workflow.core.node.Trigger;
 import org.drools.xml.XmlProcessReader;
 
 /**
@@ -60,7 +62,7 @@
 public class ProcessBuilder {
 
     private PackageBuilder packageBuilder;
-    private final List<DroolsError>     errors = new ArrayList<DroolsError>();
+    private final List<DroolsError> errors = new ArrayList<DroolsError>();
     private Map<String, ProcessValidator> processValidators = new HashMap<String, ProcessValidator>();;
 
     public ProcessBuilder(PackageBuilder packageBuilder) {
@@ -147,7 +149,8 @@
     	}
     }
     
-    public void buildNodes(WorkflowProcess process, ProcessBuildContext context) {
+    @SuppressWarnings("unchecked")
+	public void buildNodes(WorkflowProcess process, ProcessBuildContext context) {
     	ProcessNodeBuilderRegistry nodeBuilderRegistry = packageBuilder.getPackageBuilderConfiguration().getProcessNodeBuilderRegistry();
         processNodes(process.getNodes(), process, context.getProcessDescr(), context, nodeBuilderRegistry);
         if ( !context.getErrors().isEmpty() ) {
@@ -217,8 +220,7 @@
                 if ( nodes[i] instanceof Split ) {
                     Split split = (Split) nodes[i];
                     if ( split.getType() == Split.TYPE_XOR || split.getType() == Split.TYPE_OR ) {
-                        for ( Iterator iterator = split.getDefaultOutgoingConnections().iterator(); iterator.hasNext(); ) {
-                            Connection connection = (Connection) iterator.next();
+                        for ( Connection connection: split.getDefaultOutgoingConnections() ) {
                             Constraint constraint = split.getConstraint( connection );
                             if ( "rule".equals( constraint.getType() ) ) {
                                 builder.append( createSplitRule( process,
@@ -231,6 +233,17 @@
                     MilestoneNode milestone = (MilestoneNode) nodes[i];
                     builder.append( createMilestoneRule( process,
                                                          milestone ) );
+                } else if ( nodes[i] instanceof StartNode ) {
+                	StartNode startNode = (StartNode) nodes[i];
+                	List<Trigger> triggers = startNode.getTriggers();
+                	if (triggers != null) {
+                		for (Trigger trigger: triggers) {
+                			if (trigger instanceof ConstraintTrigger) {
+                				builder.append( createStartConstraintRule( process,
+            						(ConstraintTrigger) trigger ));
+                			}
+                		}
+                	}
                 }
             }
         }
@@ -248,4 +261,29 @@
                                        MilestoneNode milestone) {
         return "rule \"RuleFlow-Milestone-" + process.getId() + "-" + milestone.getId() + "\" \n" + "      ruleflow-group \"DROOLS_SYSTEM\" \n" + "    when \n" + "      " + milestone.getConstraint() + "\n" + "    then \n" + "end \n\n";
     }
+    
+    private String createStartConstraintRule(Process process,
+    										 ConstraintTrigger trigger) {
+    	String result =
+    		"rule \"RuleFlow-Start-" + process.getId() + "\" \n" +
+    		"    when\n" +
+			"        " + trigger.getConstraint() + "\n" +
+			"    then\n";
+    	Map<String, String> inMappings = trigger.getInMappings();
+    	if (inMappings != null && !inMappings.isEmpty()) {
+    		result += "        java.util.Map params = new java.util.HashMap();\n";
+    		for (Map.Entry<String, String> entry: inMappings.entrySet()) {
+	    		result += "        params.put(\"" + entry.getKey() + "\", " + entry.getValue() + ");\n";
+	    	}
+	    	result += 
+				"        drools.getWorkingMemory().startProcess(\"" + process.getId() + "\", params);\n" +
+			   	"end\n\n";
+    	} else {
+    		result += 
+				"        drools.getWorkingMemory().startProcess(\"" + process.getId() + "\");\n" +
+			   	"end\n\n";
+    	}
+		return result;
+    }
+    
 }

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/ProcessSemanticModule.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/ProcessSemanticModule.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/ProcessSemanticModule.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -27,6 +27,7 @@
 import org.drools.xml.processes.SwimlaneHandler;
 import org.drools.xml.processes.TimerHandler;
 import org.drools.xml.processes.TimerNodeHandler;
+import org.drools.xml.processes.TriggerHandler;
 import org.drools.xml.processes.TypeHandler;
 import org.drools.xml.processes.ValueHandler;
 import org.drools.xml.processes.VariableHandler;
@@ -101,5 +102,7 @@
 	   			   		   new ExceptionHandlerHandler() );        
         addHandler( "timer",
                 		   new TimerHandler() );
+        addHandler( "trigger",
+     		               new TriggerHandler() );
     }
 }

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/ConstraintHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/ConstraintHandler.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/ConstraintHandler.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -4,7 +4,7 @@
 
 import org.drools.workflow.core.Constraint;
 import org.drools.workflow.core.impl.ConstraintImpl;
-import org.drools.workflow.core.node.MilestoneNode;
+import org.drools.workflow.core.node.Constrainable;
 import org.drools.workflow.core.node.Split;
 import org.drools.xml.BaseAbstractHandler;
 import org.drools.xml.ExtensibleXmlParser;
@@ -20,7 +20,7 @@
         if ((this.validParents == null) && (this.validPeers == null)) {
             this.validParents = new HashSet<Class<?>>();
             this.validParents.add(Split.class);
-            this.validParents.add(MilestoneNode.class);
+            this.validParents.add(Constrainable.class);
 
             this.validPeers = new HashSet<Class<?>>();
             this.validPeers.add(null);
@@ -43,6 +43,7 @@
                       final ExtensibleXmlParser parser) throws SAXException {
         final Element element = parser.endElementBuilder();
         Object parent = parser.getParent();
+        // TODO use Constraintable interface
         if (parent instanceof Split) {
 	        Split splitNode = (Split) parser.getParent();
 	        
@@ -74,8 +75,8 @@
 	        }
 	        constraint.setConstraint(text);
 	        splitNode.internalSetConstraint(connectionRef, constraint);
-        } else if (parent instanceof MilestoneNode) {
-        	MilestoneNode milestoneNode = (MilestoneNode) parent;
+        } else if (parent instanceof Constrainable) {
+        	Constrainable constrainable = (Constrainable) parent;
 	        String text = ((Text)element.getChildNodes().item( 0 )).getWholeText();
 	        if (text != null) {
 	            text = text.trim();
@@ -83,7 +84,7 @@
 	                text = null;
 	            }
 	        }
-	        milestoneNode.setConstraint(text);
+	        constrainable.setConstraint(text);
         } else {
         	throw new SAXException("Invalid parent node " + parent);
         }

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/EventFilterHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/EventFilterHandler.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/EventFilterHandler.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -5,6 +5,7 @@
 import org.drools.process.core.event.EventFilter;
 import org.drools.process.core.event.EventTypeFilter;
 import org.drools.workflow.core.node.EventNode;
+import org.drools.workflow.core.node.EventTrigger;
 import org.drools.xml.BaseAbstractHandler;
 import org.drools.xml.ExtensibleXmlParser;
 import org.drools.xml.Handler;
@@ -16,10 +17,11 @@
     
     public EventFilterHandler() {
         if ((this.validParents == null) && (this.validPeers == null)) {
-            this.validParents = new HashSet();
+            this.validParents = new HashSet<Class<?>>();
             this.validParents.add(EventNode.class);
+            this.validParents.add(EventTrigger.class);
 
-            this.validPeers = new HashSet();
+            this.validPeers = new HashSet<Class<?>>();
             this.validPeers.add(null);
 
             this.allowNesting = false;
@@ -39,7 +41,7 @@
                       final String localName,
                       final ExtensibleXmlParser parser) throws SAXException {
         final Element element = parser.endElementBuilder();
-        EventNode eventNode = (EventNode) parser.getParent();
+        Object parent = parser.getParent();
         final String type = element.getAttribute("type");
         emptyAttributeCheck(localName, "type", type, parser);
         if ("eventType".equals(type)) {
@@ -47,7 +49,11 @@
             emptyAttributeCheck(localName, "eventType", eventType, parser);
             EventTypeFilter eventTypeFilter = new EventTypeFilter();
             eventTypeFilter.setType(eventType);
-            eventNode.addEventFilter(eventTypeFilter);
+            if (parent instanceof EventNode) {
+            	((EventNode) parent).addEventFilter(eventTypeFilter);
+            } else if (parent instanceof EventTrigger) {
+            	((EventTrigger) parent).addEventFilter(eventTypeFilter);
+            }
         } else {
         	throw new IllegalArgumentException(
     			"Unknown event filter type: " + type);
@@ -55,7 +61,8 @@
         return null;
     }
 
-    public Class generateNodeFor() {
+    @SuppressWarnings("unchecked")
+	public Class generateNodeFor() {
         return EventFilter.class;
     }    
 

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/EventNodeHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/EventNodeHandler.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/EventNodeHandler.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -14,7 +14,8 @@
         return new EventNode();
     }
     
-    public Class generateNodeFor() {
+    @SuppressWarnings("unchecked")
+	public Class generateNodeFor() {
         return EventNode.class;
     }
 
@@ -27,6 +28,10 @@
         if (variableName != null && variableName.length() != 0 ) {
             eventNode.setVariableName(variableName);
         }
+        String scope = element.getAttribute("scope");
+        if (scope != null && scope.length() != 0 ) {
+            eventNode.setScope(scope);
+        }
     }
     
     public void writeNode(Node node, StringBuffer xmlDump, boolean includeMeta) {
@@ -36,6 +41,10 @@
         if (variableName != null && variableName.length() != 0) {
             xmlDump.append("variableName=\"" + variableName + "\" ");
         }
+        String scope = eventNode.getScope();
+        if (scope != null && scope.length() != 0) {
+            xmlDump.append("scope=\"" + scope + "\" ");
+        }
         xmlDump.append(">" + EOL);
         xmlDump.append("      <eventFilters>" + EOL);
         for (EventFilter filter: eventNode.getEventFilters()) {

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/StartNodeHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/StartNodeHandler.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/StartNodeHandler.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -1,9 +1,16 @@
 package org.drools.xml.processes;
 
-import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 
+import org.drools.process.core.event.EventFilter;
+import org.drools.process.core.event.EventTypeFilter;
 import org.drools.workflow.core.Node;
+import org.drools.workflow.core.node.ConstraintTrigger;
+import org.drools.workflow.core.node.EventTrigger;
 import org.drools.workflow.core.node.StartNode;
+import org.drools.workflow.core.node.Trigger;
+import org.drools.xml.XmlDumper;
 
 public class StartNodeHandler extends AbstractNodeHandler {
     
@@ -11,14 +18,57 @@
         return new StartNode();
     }
     
-    public Class generateNodeFor() {
+    @SuppressWarnings("unchecked")
+	public Class generateNodeFor() {
         return StartNode.class;
     }
 
 	public void writeNode(Node node, StringBuffer xmlDump, boolean includeMeta) {
 		StartNode startNode = (StartNode) node;
 		writeNode("start", startNode, xmlDump, includeMeta);
-        endNode(xmlDump);
+		List<Trigger> triggers = startNode.getTriggers();
+		if (triggers == null || triggers.isEmpty()) {
+			endNode(xmlDump);
+		} else {
+			xmlDump.append(">" + EOL);
+			xmlDump.append("        <triggers>" + EOL);
+			for (Trigger trigger: triggers) {
+				if (trigger instanceof ConstraintTrigger) {
+					xmlDump.append("         <trigger type=\"constraint\" >" + EOL);
+					xmlDump.append("           <constraint type=\"rule\" dialect=\"mvel\" >"
+						+ ((ConstraintTrigger) trigger).getConstraint() + "</constraint>" + EOL);
+					Map<String, String> inMappings = trigger.getInMappings();
+			    	if (inMappings != null && !inMappings.isEmpty()) {
+			    		for (Map.Entry<String, String> entry: inMappings.entrySet()) {
+				    		xmlDump.append("          <mapping type=\"in\" from=\""
+			    				+ XmlDumper.replaceIllegalChars(entry.getKey())
+			    				+ "\" to=\"" + entry.getValue() + "\" />" + EOL);
+				    	}
+			    	}
+					xmlDump.append("         </trigger>" + EOL);
+				} else if (trigger instanceof EventTrigger) {
+					xmlDump.append("         <trigger type=\"event\" >" + EOL);
+			        xmlDump.append("           <eventFilters>" + EOL);
+					for (EventFilter filter: ((EventTrigger) trigger).getEventFilters()) {
+			        	if (filter instanceof EventTypeFilter) {
+			        		xmlDump.append("             <eventFilter "
+			                    + "type=\"eventType\" "
+			                    + "eventType=\"" + ((EventTypeFilter) filter).getType() + "\" />" + EOL);
+			        	} else {
+			        		throw new IllegalArgumentException(
+			    				"Unknown filter type: " + filter);
+			        	}
+			        }
+			        xmlDump.append("           </eventFilters>" + EOL);
+					xmlDump.append("         </trigger>" + EOL);
+				} else {
+					throw new IllegalArgumentException(
+						"Unknown trigger type " + trigger);
+				}
+			}
+			xmlDump.append("        </triggers>" + EOL);
+			endNode("start", xmlDump);
+		}
 	}
 
 }

Added: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/TriggerHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/TriggerHandler.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/xml/processes/TriggerHandler.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -0,0 +1,62 @@
+package org.drools.xml.processes;
+
+import java.util.HashSet;
+
+import org.drools.workflow.core.node.ConstraintTrigger;
+import org.drools.workflow.core.node.EventTrigger;
+import org.drools.workflow.core.node.StartNode;
+import org.drools.workflow.core.node.Trigger;
+import org.drools.xml.BaseAbstractHandler;
+import org.drools.xml.ExtensibleXmlParser;
+import org.drools.xml.Handler;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+public class TriggerHandler extends BaseAbstractHandler implements Handler {
+	
+    public TriggerHandler() {
+        if ( (this.validParents == null) && (this.validPeers == null) ) {
+            this.validParents = new HashSet<Class<?>>();
+            this.validParents.add( StartNode.class );
+
+            this.validPeers = new HashSet<Class<?>>();         
+            this.validPeers.add( null );
+
+            this.allowNesting = false;
+        }
+    }
+    
+    public Object start(final String uri,
+                        final String localName,
+                        final Attributes attrs,
+                        final ExtensibleXmlParser parser) throws SAXException {
+        parser.startElementBuilder( localName, attrs );
+        StartNode startNode = (StartNode) parser.getParent();
+        String type = attrs.getValue("type");
+        emptyAttributeCheck( localName, "type", type, parser );
+        
+        Trigger trigger = null;
+        if ("constraint".equals(type)) {
+        	trigger = new ConstraintTrigger();
+        } else if ("event".equals(type)) {
+        	trigger = new EventTrigger();
+        } else {
+        	throw new SAXException("Unknown trigger type " + type);
+        }
+        startNode.addTrigger(trigger);
+        return trigger;
+    }    
+    
+    public Object end(final String uri,
+                      final String localName,
+                      final ExtensibleXmlParser parser) throws SAXException {
+        parser.endElementBuilder();
+        return parser.getCurrent();
+    }
+
+    @SuppressWarnings("unchecked")
+	public Class generateNodeFor() {
+        return Trigger.class;
+    }    
+
+}

Modified: labs/jbossrules/trunk/drools-compiler/src/main/resources/META-INF/drools-processes-4.0.xsd
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/resources/META-INF/drools-processes-4.0.xsd	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/src/main/resources/META-INF/drools-processes-4.0.xsd	2008-10-06 13:07:47 UTC (rev 23324)
@@ -149,6 +149,9 @@
 	</xs:element>
 	<xs:element name="start">
 		<xs:complexType>
+			<xs:choice minOccurs="0" maxOccurs="1">
+				<xs:element ref="drools:triggers"/>
+			</xs:choice>
 			<xs:attribute name="id" type="xs:string" use="required"/>
 			<xs:attribute name="name" type="xs:string"/>
 			<xs:attribute name="x" type="xs:string"/>
@@ -157,6 +160,23 @@
 			<xs:attribute name="height" type="xs:string"/>
 		</xs:complexType>
 	</xs:element>
+	<xs:element name="triggers">
+		<xs:complexType>
+			<xs:choice minOccurs="0" maxOccurs="unbounded">
+				<xs:element ref="drools:trigger"/>
+			</xs:choice>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="trigger">
+		<xs:complexType>
+			<xs:choice minOccurs="0" maxOccurs="unbounded">
+				<xs:element ref="drools:constraint"/>
+				<xs:element ref="drools:eventFilters"/>
+				<xs:element ref="drools:mapping"/>
+			</xs:choice>
+			<xs:attribute name="type" type="xs:string" use="required"/>
+		</xs:complexType>
+	</xs:element>
 	<xs:element name="end">
 		<xs:complexType>
 			<xs:attribute name="id" type="xs:string" use="required"/>
@@ -448,6 +468,7 @@
 			<xs:attribute name="width" type="xs:string"/>
 			<xs:attribute name="height" type="xs:string"/>
 			<xs:attribute name="variableName" type="xs:string"/>
+			<xs:attribute name="scope" type="xs:string"/>
 		</xs:complexType>
 	</xs:element>
 	<xs:element name="eventFilters">

Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessEventTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessEventTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessEventTest.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -0,0 +1,476 @@
+package org.drools.integrationtests;
+
+import java.io.Reader;
+import java.io.StringReader;
+
+import junit.framework.TestCase;
+
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.StatefulSession;
+import org.drools.WorkingMemory;
+import org.drools.compiler.PackageBuilder;
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.instance.ProcessInstance;
+import org.drools.process.instance.context.variable.VariableScopeInstance;
+import org.drools.rule.Package;
+
+public class ProcessEventTest extends TestCase {
+    
+    public void testInternalNodeSignalEvent() {
+        PackageBuilder builder = new PackageBuilder();
+        Reader source = new StringReader(
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+            "<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+            "         xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+            "         xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+            "         type=\"RuleFlow\" name=\"flow\" id=\"org.drools.event\" package-name=\"org.drools\" version=\"1\" >\n" +
+            "\n" +
+            "  <header>\n" +
+    		"    <variables>\n" +
+    		"      <variable name=\"MyVar\" >\n" +
+    		"        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+    		"        <value>SomeText</value>\n" +
+    		"      </variable>\n" +
+    		"    </variables>\n" +
+            "  </header>\n" +
+            "\n" +
+            "  <nodes>\n" +
+            "    <start id=\"1\" name=\"Start\" />\n" +
+            "    <eventNode id=\"2\" name=\"Event\" variableName=\"MyVar\" >\n" +
+            "      <eventFilters>\n" +
+            "        <eventFilter type=\"eventType\" eventType=\"MyEvent\" />\n" +
+            "      </eventFilters>\n" +
+            "    </eventNode>\n" +
+            "    <actionNode id=\"3\" name=\"Signal Event\" >\n" +
+            "      <action type=\"expression\" dialect=\"java\" >context.getProcessInstance().signalEvent(\"MyEvent\", \"MyValue\");</action>\n" +
+            "    </actionNode>\n" +
+            "    <join id=\"4\" name=\"Join\" type=\"1\" />\n" +
+            "    <end id=\"5\" name=\"End\" />\n" +
+            "  </nodes>\n" +
+            "\n" +
+            "  <connections>\n" +
+            "    <connection from=\"1\" to=\"3\" />\n" +
+            "    <connection from=\"2\" to=\"4\" />\n" +
+            "    <connection from=\"3\" to=\"4\" />\n" +
+            "    <connection from=\"4\" to=\"5\" />\n" +
+            "  </connections>\n" +
+            "\n" +
+            "</process>");
+        builder.addRuleFlow(source);
+        Package pkg = builder.getPackage();
+        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage( pkg );
+        StatefulSession session = ruleBase.newStatefulSession();
+        ProcessInstance processInstance =
+            session.startProcess("org.drools.event");
+        assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
+        assertEquals("MyValue", ((VariableScopeInstance) processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE)).getVariable("MyVar"));
+    }
+    
+    public void testProcessInstanceSignalEvent() throws Exception {
+        PackageBuilder builder = new PackageBuilder();
+        Reader source = new StringReader(
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+            "<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+            "         xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+            "         xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+            "         type=\"RuleFlow\" name=\"flow\" id=\"org.drools.event\" package-name=\"org.drools\" version=\"1\" >\n" +
+            "\n" +
+            "  <header>\n" +
+    		"    <variables>\n" +
+    		"      <variable name=\"MyVar\" >\n" +
+    		"        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+    		"        <value>SomeText</value>\n" +
+    		"      </variable>\n" +
+    		"    </variables>\n" +
+            "  </header>\n" +
+            "\n" +
+            "  <nodes>\n" +
+            "    <start id=\"1\" name=\"Start\" />\n" +
+            "    <eventNode id=\"2\" name=\"Event\" variableName=\"MyVar\" >\n" +
+            "      <eventFilters>\n" +
+            "        <eventFilter type=\"eventType\" eventType=\"MyEvent\" />\n" +
+            "      </eventFilters>\n" +
+            "    </eventNode>\n" +
+            "    <join id=\"3\" name=\"Join\" type=\"1\" />\n" +
+            "    <end id=\"4\" name=\"End\" />\n" +
+            "  </nodes>\n" +
+            "\n" +
+            "  <connections>\n" +
+            "    <connection from=\"1\" to=\"3\" />\n" +
+            "    <connection from=\"2\" to=\"3\" />\n" +
+            "    <connection from=\"3\" to=\"4\" />\n" +
+            "  </connections>\n" +
+            "\n" +
+            "</process>");
+        builder.addRuleFlow(source);
+        Package pkg = builder.getPackage();
+        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage( pkg );
+        StatefulSession session = ruleBase.newStatefulSession();
+        ProcessInstance processInstance = session.startProcess("org.drools.event");
+        assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState());
+        
+        session = SerializationHelper.getSerialisedStatefulSession(session);
+        processInstance = session.getProcessInstance(processInstance.getId());
+        processInstance.signalEvent("MyEvent", "MyValue");
+        assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
+        assertEquals("MyValue", ((VariableScopeInstance) processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE)).getVariable("MyVar"));
+    }
+    
+    public void testExternalEventCorrelation() throws Exception {
+        PackageBuilder builder = new PackageBuilder();
+        Reader source = new StringReader(
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+            "<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+            "         xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+            "         xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+            "         type=\"RuleFlow\" name=\"flow\" id=\"org.drools.event\" package-name=\"org.drools\" version=\"1\" >\n" +
+            "\n" +
+            "  <header>\n" +
+    		"    <variables>\n" +
+    		"      <variable name=\"MyVar\" >\n" +
+    		"        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+    		"        <value>SomeText</value>\n" +
+    		"      </variable>\n" +
+    		"    </variables>\n" +
+            "  </header>\n" +
+            "\n" +
+            "  <nodes>\n" +
+            "    <start id=\"1\" name=\"Start\" />\n" +
+            "    <eventNode id=\"2\" name=\"Event\" variableName=\"MyVar\" scope=\"external\" >\n" +
+            "      <eventFilters>\n" +
+            "        <eventFilter type=\"eventType\" eventType=\"MyEvent\" />\n" +
+            "      </eventFilters>\n" +
+            "    </eventNode>\n" +
+            "    <join id=\"3\" name=\"Join\" type=\"1\" />\n" +
+            "    <end id=\"4\" name=\"End\" />\n" +
+            "  </nodes>\n" +
+            "\n" +
+            "  <connections>\n" +
+            "    <connection from=\"1\" to=\"3\" />\n" +
+            "    <connection from=\"2\" to=\"3\" />\n" +
+            "    <connection from=\"3\" to=\"4\" />\n" +
+            "  </connections>\n" +
+            "\n" +
+            "</process>");
+        builder.addRuleFlow(source);
+        Package pkg = builder.getPackage();
+        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage( pkg );
+        StatefulSession session = ruleBase.newStatefulSession();
+        ProcessInstance processInstance = session.startProcess("org.drools.event");
+        assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState());
+        assertEquals("SomeText", ((VariableScopeInstance) processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE)).getVariable("MyVar"));
+        
+        session = SerializationHelper.getSerialisedStatefulSession(session);
+        processInstance = session.getProcessInstance(processInstance.getId());
+        session.getSignalManager().signalEvent("MyEvent", "MyValue");
+        assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
+        assertEquals("MyValue", ((VariableScopeInstance) processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE)).getVariable("MyVar"));
+    }
+
+    public void testInternalEventCorrelation() throws Exception {
+        PackageBuilder builder = new PackageBuilder();
+        Reader source = new StringReader(
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+            "<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+            "         xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+            "         xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+            "         type=\"RuleFlow\" name=\"flow\" id=\"org.drools.event\" package-name=\"org.drools\" version=\"1\" >\n" +
+            "\n" +
+            "  <header>\n" +
+    		"    <variables>\n" +
+    		"      <variable name=\"MyVar\" >\n" +
+    		"        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+    		"        <value>SomeText</value>\n" +
+    		"      </variable>\n" +
+    		"    </variables>\n" +
+            "  </header>\n" +
+            "\n" +
+            "  <nodes>\n" +
+            "    <start id=\"1\" name=\"Start\" />\n" +
+            "    <eventNode id=\"2\" name=\"Event\" variableName=\"MyVar\" >\n" +
+            "      <eventFilters>\n" +
+            "        <eventFilter type=\"eventType\" eventType=\"MyEvent\" />\n" +
+            "      </eventFilters>\n" +
+            "    </eventNode>\n" +
+            "    <join id=\"3\" name=\"Join\" type=\"1\" />\n" +
+            "    <end id=\"4\" name=\"End\" />\n" +
+            "  </nodes>\n" +
+            "\n" +
+            "  <connections>\n" +
+            "    <connection from=\"1\" to=\"3\" />\n" +
+            "    <connection from=\"2\" to=\"3\" />\n" +
+            "    <connection from=\"3\" to=\"4\" />\n" +
+            "  </connections>\n" +
+            "\n" +
+            "</process>");
+        builder.addRuleFlow(source);
+        Package pkg = builder.getPackage();
+        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage( pkg );
+        StatefulSession session = ruleBase.newStatefulSession();
+        ProcessInstance processInstance = session.startProcess("org.drools.event");
+        assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState());
+        assertEquals("SomeText", ((VariableScopeInstance) processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE)).getVariable("MyVar"));
+
+        session = SerializationHelper.getSerialisedStatefulSession(session);
+        processInstance = session.getProcessInstance(processInstance.getId());
+        session.getSignalManager().signalEvent("MyEvent", "MyValue");
+        assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState());
+    }
+    
+    public void testInternalNodeSignalCompositeEvent() {
+        PackageBuilder builder = new PackageBuilder();
+        Reader source = new StringReader(
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+            "<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+            "         xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+            "         xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+            "         type=\"RuleFlow\" name=\"flow\" id=\"org.drools.event\" package-name=\"org.drools\" version=\"1\" >\n" +
+            "\n" +
+            "  <header>\n" +
+    		"    <variables>\n" +
+    		"      <variable name=\"MyVar\" >\n" +
+    		"        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+    		"        <value>SomeText</value>\n" +
+    		"      </variable>\n" +
+    		"    </variables>\n" +
+            "  </header>\n" +
+            "\n" +
+            "  <nodes>\n" +
+            "    <start id=\"1\" name=\"Start\" />\n" +
+            "    <composite id=\"2\" name=\"CompositeNode\" >\n" +
+            "      <nodes>\n" +
+            "        <actionNode id=\"1\" name=\"Signal Event\" >\n" +
+            "          <action type=\"expression\" dialect=\"java\" >context.getProcessInstance().signalEvent(\"MyEvent\", \"MyValue\");</action>\n" +
+            "        </actionNode>\n" +
+            "        <eventNode id=\"2\" name=\"Event\" variableName=\"MyVar\" >\n" +
+            "          <eventFilters>\n" +
+            "            <eventFilter type=\"eventType\" eventType=\"MyEvent\" />\n" +
+            "          </eventFilters>\n" +
+            "        </eventNode>\n" +
+            "        <join id=\"3\" name=\"Join\" type=\"1\" />\n" +
+            "      </nodes>\n" +
+            "      <connections>\n" +
+            "        <connection from=\"1\" to=\"3\" />\n" +
+            "        <connection from=\"2\" to=\"3\" />\n" +
+            "      </connections>\n" +
+            "      <in-ports>\n" +
+            "        <in-port type=\"DROOLS_DEFAULT\" nodeId=\"1\" nodeInType=\"DROOLS_DEFAULT\" />\n" +
+            "      </in-ports>\n" +
+            "      <out-ports>\n" +
+            "        <out-port type=\"DROOLS_DEFAULT\" nodeId=\"3\" nodeOutType=\"DROOLS_DEFAULT\" />\n" +
+            "      </out-ports>\n" +
+            "    </composite>\n" +
+            "    <end id=\"3\" name=\"End\" />\n" +
+            "  </nodes>\n" +
+            "\n" +
+            "  <connections>\n" +
+            "    <connection from=\"1\" to=\"2\" />\n" +
+            "    <connection from=\"2\" to=\"3\" />\n" +
+            "  </connections>\n" +
+            "\n" +
+            "</process>");
+        builder.addRuleFlow(source);
+        Package pkg = builder.getPackage();
+        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage( pkg );
+        WorkingMemory workingMemory = ruleBase.newStatefulSession();
+        ProcessInstance processInstance =
+            workingMemory.startProcess("org.drools.event");
+        assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
+        assertEquals("MyValue", ((VariableScopeInstance) processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE)).getVariable("MyVar"));
+    }
+    
+    public void testProcessInstanceSignalCompositeEvent() throws Exception {
+        PackageBuilder builder = new PackageBuilder();
+        Reader source = new StringReader(
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+            "<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+            "         xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+            "         xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+            "         type=\"RuleFlow\" name=\"flow\" id=\"org.drools.event\" package-name=\"org.drools\" version=\"1\" >\n" +
+            "\n" +
+            "  <header>\n" +
+    		"    <variables>\n" +
+    		"      <variable name=\"MyVar\" >\n" +
+    		"        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+    		"        <value>SomeText</value>\n" +
+    		"      </variable>\n" +
+    		"    </variables>\n" +
+            "  </header>\n" +
+            "\n" +
+            "  <nodes>\n" +
+            "    <start id=\"1\" name=\"Start\" />\n" +
+            "    <composite id=\"2\" name=\"CompositeNode\" >\n" +
+            "      <nodes>\n" +
+            "        <eventNode id=\"2\" name=\"Event\" variableName=\"MyVar\" >\n" +
+            "          <eventFilters>\n" +
+            "            <eventFilter type=\"eventType\" eventType=\"MyEvent\" />\n" +
+            "          </eventFilters>\n" +
+            "        </eventNode>\n" +
+            "        <join id=\"3\" name=\"Join\" type=\"1\" />\n" +
+            "      </nodes>\n" +
+            "      <connections>\n" +
+            "        <connection from=\"2\" to=\"3\" />\n" +
+            "      </connections>\n" +
+            "      <in-ports>\n" +
+            "        <in-port type=\"DROOLS_DEFAULT\" nodeId=\"3\" nodeInType=\"DROOLS_DEFAULT\" />\n" +
+            "      </in-ports>\n" +
+            "      <out-ports>\n" +
+            "        <out-port type=\"DROOLS_DEFAULT\" nodeId=\"3\" nodeOutType=\"DROOLS_DEFAULT\" />\n" +
+            "      </out-ports>\n" +
+            "    </composite>\n" +
+            "    <end id=\"3\" name=\"End\" />\n" +
+            "  </nodes>\n" +
+            "\n" +
+            "  <connections>\n" +
+            "    <connection from=\"1\" to=\"2\" />\n" +
+            "    <connection from=\"2\" to=\"3\" />\n" +
+            "  </connections>\n" +
+            "\n" +
+            "</process>");
+        builder.addRuleFlow(source);
+        Package pkg = builder.getPackage();
+        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage( pkg );
+        StatefulSession session = ruleBase.newStatefulSession();
+        ProcessInstance processInstance = session.startProcess("org.drools.event");
+        assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState());
+
+        session = SerializationHelper.getSerialisedStatefulSession(session);
+        processInstance = session.getProcessInstance(processInstance.getId());
+        processInstance.signalEvent("MyEvent", "MyValue");
+        assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
+        assertEquals("MyValue", ((VariableScopeInstance) processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE)).getVariable("MyVar"));
+    }
+    
+    public void testExternalCompositeEventCorrelation() throws Exception {
+        PackageBuilder builder = new PackageBuilder();
+        Reader source = new StringReader(
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+            "<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+            "         xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+            "         xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+            "         type=\"RuleFlow\" name=\"flow\" id=\"org.drools.event\" package-name=\"org.drools\" version=\"1\" >\n" +
+            "\n" +
+            "  <header>\n" +
+    		"    <variables>\n" +
+    		"      <variable name=\"MyVar\" >\n" +
+    		"        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+    		"        <value>SomeText</value>\n" +
+    		"      </variable>\n" +
+    		"    </variables>\n" +
+            "  </header>\n" +
+            "\n" +
+            "  <nodes>\n" +
+            "    <start id=\"1\" name=\"Start\" />\n" +
+            "    <composite id=\"2\" name=\"CompositeNode\" >\n" +
+            "      <nodes>\n" +
+            "        <eventNode id=\"2\" name=\"Event\" variableName=\"MyVar\" scope=\"external\" >\n" +
+            "          <eventFilters>\n" +
+            "            <eventFilter type=\"eventType\" eventType=\"MyEvent\" />\n" +
+            "          </eventFilters>\n" +
+            "        </eventNode>\n" +
+            "        <join id=\"3\" name=\"Join\" type=\"1\" />\n" +
+            "      </nodes>\n" +
+            "      <connections>\n" +
+            "        <connection from=\"2\" to=\"3\" />\n" +
+            "      </connections>\n" +
+            "      <in-ports>\n" +
+            "        <in-port type=\"DROOLS_DEFAULT\" nodeId=\"3\" nodeInType=\"DROOLS_DEFAULT\" />\n" +
+            "      </in-ports>\n" +
+            "      <out-ports>\n" +
+            "        <out-port type=\"DROOLS_DEFAULT\" nodeId=\"3\" nodeOutType=\"DROOLS_DEFAULT\" />\n" +
+            "      </out-ports>\n" +
+            "    </composite>\n" +
+            "    <end id=\"3\" name=\"End\" />\n" +
+            "  </nodes>\n" +
+            "\n" +
+            "  <connections>\n" +
+            "    <connection from=\"1\" to=\"2\" />\n" +
+            "    <connection from=\"2\" to=\"3\" />\n" +
+            "  </connections>\n" +
+            "\n" +
+            "</process>");
+        builder.addRuleFlow(source);
+        Package pkg = builder.getPackage();
+        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage( pkg );
+        StatefulSession session = ruleBase.newStatefulSession();
+        ProcessInstance processInstance = session.startProcess("org.drools.event");
+        assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState());
+
+        session = SerializationHelper.getSerialisedStatefulSession(session);
+        processInstance = session.getProcessInstance(processInstance.getId());
+        session.getSignalManager().signalEvent("MyEvent", "MyValue");
+        assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
+        assertEquals("MyValue", ((VariableScopeInstance) processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE)).getVariable("MyVar"));
+    }
+    
+    public void testInternalCompositeEventCorrelation() throws Exception {
+        PackageBuilder builder = new PackageBuilder();
+        Reader source = new StringReader(
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+            "<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+            "         xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+            "         xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+            "         type=\"RuleFlow\" name=\"flow\" id=\"org.drools.event\" package-name=\"org.drools\" version=\"1\" >\n" +
+            "\n" +
+            "  <header>\n" +
+    		"    <variables>\n" +
+    		"      <variable name=\"MyVar\" >\n" +
+    		"        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+    		"        <value>SomeText</value>\n" +
+    		"      </variable>\n" +
+    		"    </variables>\n" +
+            "  </header>\n" +
+            "\n" +
+            "  <nodes>\n" +
+            "    <start id=\"1\" name=\"Start\" />\n" +
+            "    <composite id=\"2\" name=\"CompositeNode\" >\n" +
+            "      <nodes>\n" +
+            "        <eventNode id=\"2\" name=\"Event\" variableName=\"MyVar\" >\n" +
+            "          <eventFilters>\n" +
+            "            <eventFilter type=\"eventType\" eventType=\"MyEvent\" />\n" +
+            "          </eventFilters>\n" +
+            "        </eventNode>\n" +
+            "        <join id=\"3\" name=\"Join\" type=\"1\" />\n" +
+            "      </nodes>\n" +
+            "      <connections>\n" +
+            "        <connection from=\"2\" to=\"3\" />\n" +
+            "      </connections>\n" +
+            "      <in-ports>\n" +
+            "        <in-port type=\"DROOLS_DEFAULT\" nodeId=\"3\" nodeInType=\"DROOLS_DEFAULT\" />\n" +
+            "      </in-ports>\n" +
+            "      <out-ports>\n" +
+            "        <out-port type=\"DROOLS_DEFAULT\" nodeId=\"3\" nodeOutType=\"DROOLS_DEFAULT\" />\n" +
+            "      </out-ports>\n" +
+            "    </composite>\n" +
+            "    <end id=\"3\" name=\"End\" />\n" +
+            "  </nodes>\n" +
+            "\n" +
+            "  <connections>\n" +
+            "    <connection from=\"1\" to=\"2\" />\n" +
+            "    <connection from=\"2\" to=\"3\" />\n" +
+            "  </connections>\n" +
+            "\n" +
+            "</process>");
+        builder.addRuleFlow(source);
+        Package pkg = builder.getPackage();
+        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage( pkg );
+        StatefulSession session = ruleBase.newStatefulSession();
+        ProcessInstance processInstance = session.startProcess("org.drools.event");
+        assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState());
+
+        session = SerializationHelper.getSerialisedStatefulSession(session);
+        processInstance = session.getProcessInstance(processInstance.getId());
+        session.getSignalManager().signalEvent("MyEvent", "MyValue");
+        assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState());
+    }
+    
+}

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessHumanTaskTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessHumanTaskTest.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessHumanTaskTest.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -2,11 +2,11 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
+import junit.framework.TestCase;
+
 import org.drools.RuleBase;
 import org.drools.RuleBaseFactory;
 import org.drools.WorkingMemory;
@@ -17,8 +17,6 @@
 import org.drools.process.instance.WorkItemManager;
 import org.drools.rule.Package;
 
-import junit.framework.TestCase;
-
 public class ProcessHumanTaskTest extends TestCase {
     
     public void testHumanTask() {

Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessStartTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessStartTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessStartTest.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -0,0 +1,168 @@
+package org.drools.integrationtests;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.drools.Message;
+import org.drools.Person;
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.StatefulSession;
+import org.drools.compiler.DroolsError;
+import org.drools.compiler.PackageBuilder;
+import org.drools.rule.Package;
+
+public class ProcessStartTest extends TestCase {
+    
+	public void testStartConstraintTrigger() throws Exception {
+		PackageBuilder builder = new PackageBuilder();
+		Reader source = new StringReader(
+			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+			"<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+			"         xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+			"         xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+			"         type=\"RuleFlow\" name=\"flow\" id=\"org.drools.start\" package-name=\"org.drools\" version=\"1\" >\n" +
+			"\n" +
+			"  <header>\n" +
+			"    <imports>\n" +
+			"      <import name=\"org.drools.Person\" />\n" +
+			"    </imports>\n" +
+			"    <globals>\n" +
+			"      <global identifier=\"myList\" type=\"java.util.List\" />\n" +
+			"    </globals>\n" +
+            "    <variables>\n" +
+            "      <variable name=\"SomeVar\" >\n" +
+            "        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+            "      </variable>\n" +
+            "      <variable name=\"SomeOtherVar\" >\n" +
+            "        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+            "      </variable>\n" +
+            "    </variables>\n" +
+			"  </header>\n" +
+			"\n" +
+			"  <nodes>\n" +
+			"    <start id=\"1\" name=\"Start\" >\n" +
+			"      <triggers>" +
+			"        <trigger type=\"constraint\" >\n" +
+			"          <constraint type=\"rule\" dialect=\"mvel\" >p:Person()</constraint>\n" +
+			"          <mapping type=\"in\" from=\"p.getName()\" to=\"SomeVar\" />\n" +
+			"          <mapping type=\"in\" from=\"&quot;SomeString&quot;\" to=\"SomeOtherVar\" />\n" +
+			"        </trigger>\n " +
+			"      </triggers>\n" +
+			"    </start>\n" +
+			"    <actionNode id=\"2\" name=\"Action\" >\n" +
+			"      <action type=\"expression\" dialect=\"java\" >myList.add(context.getVariable(\"SomeVar\"));\n" +
+			"myList.add(context.getVariable(\"SomeOtherVar\"));</action>\n" +
+			"    </actionNode>\n" + 
+			"    <end id=\"3\" name=\"End\" />\n" +
+			"  </nodes>\n" +
+			"\n" +
+			"  <connections>\n" +
+			"    <connection from=\"1\" to=\"2\" />\n" +
+			"    <connection from=\"2\" to=\"3\" />\n" +
+			"  </connections>\n" +
+			"\n" +
+			"</process>");
+		builder.addRuleFlow(source);
+		if (!builder.getErrors().isEmpty()) {
+			for (DroolsError error: builder.getErrors().getErrors()) {
+				System.err.println(error);
+			}
+			fail("Could not build process");
+		}
+		
+		Package pkg = builder.getPackage();
+		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+		ruleBase.addPackage( pkg );
+		StatefulSession session = ruleBase.newStatefulSession();
+		List<Message> myList = new ArrayList<Message>();
+		session.setGlobal("myList", myList);
+
+		assertEquals(0, myList.size());
+        
+		Person jack = new Person();
+        jack.setName("Jack");
+        session.insert(jack);
+        session.fireAllRules();
+        assertEquals(2, myList.size());
+        assertEquals("Jack", myList.get(0));
+        assertEquals("SomeString", myList.get(1));
+	}
+	
+	public void testStartEventTrigger() throws Exception {
+		PackageBuilder builder = new PackageBuilder();
+		Reader source = new StringReader(
+			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+			"<process xmlns=\"http://drools.org/drools-4.0/process\"\n" +
+			"         xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+			"         xs:schemaLocation=\"http://drools.org/drools-4.0/process drools-processes-4.0.xsd\"\n" +
+			"         type=\"RuleFlow\" name=\"flow\" id=\"org.drools.start\" package-name=\"org.drools\" version=\"1\" >\n" +
+			"\n" +
+			"  <header>\n" +
+			"    <globals>\n" +
+			"      <global identifier=\"myList\" type=\"java.util.List\" />\n" +
+			"    </globals>\n" +
+            "    <variables>\n" +
+            "      <variable name=\"SomeVar\" >\n" +
+            "        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+            "      </variable>\n" +
+            "      <variable name=\"SomeOtherVar\" >\n" +
+            "        <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n" +
+            "      </variable>\n" +
+            "    </variables>\n" +
+			"  </header>\n" +
+			"\n" +
+			"  <nodes>\n" +
+			"    <start id=\"1\" name=\"Start\" >\n" +
+			"      <triggers>" +
+			"        <trigger type=\"event\" >\n" +
+			"          <eventFilters>" +
+			"            <eventFilter type=\"eventType\" eventType=\"myEvent\" />\n" +
+			"          </eventFilters>" +
+			"          <mapping type=\"in\" from=\"event\" to=\"SomeVar\" />\n" +
+			"          <mapping type=\"in\" from=\"SomeString\" to=\"SomeOtherVar\" />\n" +
+			"        </trigger>\n " +
+			"      </triggers>\n" +
+			"    </start>\n" +
+			"    <actionNode id=\"2\" name=\"Action\" >\n" +
+			"      <action type=\"expression\" dialect=\"java\" >myList.add(context.getVariable(\"SomeVar\"));\n" +
+			"myList.add(context.getVariable(\"SomeOtherVar\"));</action>\n" +
+			"    </actionNode>\n" + 
+			"    <end id=\"3\" name=\"End\" />\n" +
+			"  </nodes>\n" +
+			"\n" +
+			"  <connections>\n" +
+			"    <connection from=\"1\" to=\"2\" />\n" +
+			"    <connection from=\"2\" to=\"3\" />\n" +
+			"  </connections>\n" +
+			"\n" +
+			"</process>");
+		builder.addRuleFlow(source);
+		if (!builder.getErrors().isEmpty()) {
+			for (DroolsError error: builder.getErrors().getErrors()) {
+				System.err.println(error);
+			}
+			fail("Could not build process");
+		}
+		
+		Package pkg = builder.getPackage();
+		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+		ruleBase.addPackage( pkg );
+		StatefulSession session = ruleBase.newStatefulSession();
+		List<Message> myList = new ArrayList<Message>();
+		session.setGlobal("myList", myList);
+
+		assertEquals(0, myList.size());
+        
+		session.getSignalManager().signalEvent("myEvent", "Jack");
+        session.fireAllRules();
+        assertEquals(2, myList.size());
+        assertEquals("Jack", myList.get(0));
+        assertEquals("SomeString", myList.get(1));
+	}
+	
+}

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessTimerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessTimerTest.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/ProcessTimerTest.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -126,9 +126,11 @@
 			"  <nodes>\n" +
 			"    <start id=\"1\" name=\"Start\" />\n" +
 			"    <milestone id=\"2\" name=\"Wait\" >\n" +
-			"      <timer id=\"1\" delay=\"300\" >\n" +
-			"        <action type=\"expression\" dialect=\"java\" >myList.add(\"Executing timer\");</action>\n" +
-			"      </timer>\n" +
+			"      <timers>\n" +
+			"        <timer id=\"1\" delay=\"300\" >\n" +
+			"          <action type=\"expression\" dialect=\"java\" >myList.add(\"Executing timer\");</action>\n" +
+			"        </timer>\n" +
+			"      </timers>\n" +
 			"      <constraint type=\"rule\" dialect=\"mvel\" >eval(false)</constraint>\n" +
 			"    </milestone>\n" +
 			"    <end id=\"3\" name=\"End\" />\n" +
@@ -187,9 +189,11 @@
 			"  <nodes>\n" +
 			"    <start id=\"1\" name=\"Start\" />\n" +
 			"    <milestone id=\"2\" name=\"Wait\" >\n" +
-			"      <timer id=\"1\" delay=\"300\" period =\"200\" >\n" +
-			"        <action type=\"expression\" dialect=\"java\" >myList.add(\"Executing timer\");</action>\n" +
-			"      </timer>\n" +
+			"      <timers>\n" +
+			"        <timer id=\"1\" delay=\"300\" period =\"200\" >\n" +
+			"          <action type=\"expression\" dialect=\"java\" >myList.add(\"Executing timer\");</action>\n" +
+			"        </timer>\n" +
+			"      </timers>\n" +
 			"      <constraint type=\"rule\" dialect=\"mvel\" >eval(false)</constraint>\n" +
 			"    </milestone>\n" +
 			"    <end id=\"3\" name=\"End\" />\n" +
@@ -248,12 +252,14 @@
 			"  <nodes>\n" +
 			"    <start id=\"1\" name=\"Start\" />\n" +
 			"    <milestone id=\"2\" name=\"Wait\" >\n" +
-			"      <timer id=\"1\" delay=\"600\" >\n" +
-			"        <action type=\"expression\" dialect=\"java\" >myList.add(\"Executing timer1\");</action>\n" +
-			"      </timer>\n" +
-			"      <timer id=\"2\" delay=\"200\" >\n" +
-			"        <action type=\"expression\" dialect=\"java\" >myList.add(\"Executing timer2\");</action>\n" +
-			"      </timer>\n" +
+			"      <timers>\n" +
+			"        <timer id=\"1\" delay=\"600\" >\n" +
+			"          <action type=\"expression\" dialect=\"java\" >myList.add(\"Executing timer1\");</action>\n" +
+			"        </timer>\n" +
+			"        <timer id=\"2\" delay=\"200\" >\n" +
+			"          <action type=\"expression\" dialect=\"java\" >myList.add(\"Executing timer2\");</action>\n" +
+			"        </timer>\n" +
+			"      </timers>\n" +
 			"      <constraint type=\"rule\" dialect=\"mvel\" >eval(false)</constraint>\n" +
 			"    </milestone>\n" +
 			"    <end id=\"3\" name=\"End\" />\n" +
@@ -321,9 +327,11 @@
 			"  <nodes>\n" +
 			"    <start id=\"1\" name=\"Start\" />\n" +
 			"    <milestone id=\"2\" name=\"Wait\" >\n" +
-			"      <timer id=\"1\" delay=\"2000\" >\n" +
-			"        <action type=\"expression\" dialect=\"java\" >myList.add(\"Executing timer\");</action>\n" +
-			"      </timer>\n" +
+			"      <timers>\n" +
+			"        <timer id=\"1\" delay=\"2000\" >\n" +
+			"          <action type=\"expression\" dialect=\"java\" >myList.add(\"Executing timer\");</action>\n" +
+			"        </timer>\n" +
+			"      </timers>\n" +
 			"      <constraint type=\"rule\" dialect=\"mvel\" >org.drools.Message( )</constraint>\n" +
 			"    </milestone>\n" +
 			"    <end id=\"3\" name=\"End\" />\n" +

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/testframework/MockWorkingMemory.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -1,5 +1,8 @@
 package org.drools.testframework;
 
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -7,18 +10,23 @@
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.locks.Lock;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 import org.drools.Agenda;
-import org.drools.WorkingMemoryEntryPoint;
 import org.drools.FactException;
 import org.drools.FactHandle;
 import org.drools.ObjectFilter;
 import org.drools.QueryResults;
 import org.drools.RuleBase;
-import org.drools.common.*;
+import org.drools.WorkingMemoryEntryPoint;
+import org.drools.common.InternalFactHandle;
+import org.drools.common.InternalRuleBase;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.common.NodeMemory;
+import org.drools.common.ObjectStore;
+import org.drools.common.ObjectTypeConfigurationRegistry;
+import org.drools.common.RuleBasePartitionId;
+import org.drools.common.TruthMaintenanceSystem;
+import org.drools.common.WorkingMemoryAction;
 import org.drools.concurrent.ExecutorService;
 import org.drools.event.AgendaEventListener;
 import org.drools.event.AgendaEventSupport;
@@ -31,6 +39,7 @@
 import org.drools.process.instance.ProcessInstanceFactory;
 import org.drools.process.instance.ProcessInstanceManager;
 import org.drools.process.instance.WorkItemManager;
+import org.drools.process.instance.event.SignalManager;
 import org.drools.process.instance.timer.TimerManager;
 import org.drools.reteoo.LIANodePropagation;
 import org.drools.reteoo.ObjectTypeConf;
@@ -550,4 +559,9 @@
 		
 	}
 
+	public SignalManager getSignalManager() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
 }

Modified: labs/jbossrules/trunk/drools-core/.classpath
===================================================================
--- labs/jbossrules/trunk/drools-core/.classpath	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/.classpath	2008-10-06 13:07:47 UTC (rev 23324)
@@ -1,15 +1,15 @@
-<classpath>
-  <classpathentry kind="src" path="src/main/java"/>
-  <classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
-  <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
-  <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
-  <classpathentry kind="output" path="target/classes"/>
-  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-  <classpathentry kind="var" path="M2_REPO/com/thoughtworks/xstream/xstream/1.3/xstream-1.3.jar"/>
-  <classpathentry kind="var" path="M2_REPO/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar"/>
-  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/jmock/jmock/2.5.0.1/jmock-2.5.0.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/mvel/mvel/2.0M2/mvel-2.0M2.jar"/>
+<classpath>
+  <classpathentry kind="src" path="src/main/java"/>
+  <classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
+  <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
+  <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
+  <classpathentry kind="output" path="target/classes"/>
+  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+  <classpathentry kind="var" path="M2_REPO/com/thoughtworks/xstream/xstream/1.3/xstream-1.3.jar"/>
+  <classpathentry kind="var" path="M2_REPO/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar"/>
+  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/jmock/jmock/2.5.0.1/jmock-2.5.0.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/mvel/mvel/2.0-SNAPSHOT/mvel-2.0-SNAPSHOT.jar"/>
 </classpath>
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/.project
===================================================================
--- labs/jbossrules/trunk/drools-core/.project	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/.project	2008-10-06 13:07:47 UTC (rev 23324)
@@ -1,20 +1,20 @@
-<projectDescription>
-  <name>drools-core</name>
-  <comment>A rule production system</comment>
-  <projects/>
-  <buildSpec>
-    <buildCommand>
-      <name>org.eclipse.jdt.core.javabuilder</name>
-    </buildCommand>
-    <buildCommand>
-      <name>org.drools.eclipse.droolsbuilder</name>
-    </buildCommand>
-    <buildCommand>
-      <name>org.devzuz.q.maven.jdt.core.mavenIncrementalBuilder</name>
-    </buildCommand>
-  </buildSpec>
-  <natures>
-    <nature>org.eclipse.jdt.core.javanature</nature>
-    <nature>org.devzuz.q.maven.jdt.core.mavenNature</nature>
-  </natures>
+<projectDescription>
+  <name>drools-core</name>
+  <comment>A rule production system</comment>
+  <projects/>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+    </buildCommand>
+    <buildCommand>
+      <name>org.drools.eclipse.droolsbuilder</name>
+    </buildCommand>
+    <buildCommand>
+      <name>org.devzuz.q.maven.jdt.core.mavenIncrementalBuilder</name>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+    <nature>org.devzuz.q.maven.jdt.core.mavenNature</nature>
+  </natures>
 </projectDescription>
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -43,6 +43,7 @@
 import org.drools.process.instance.ProcessInstanceManagerFactory;
 import org.drools.process.instance.WorkItemHandler;
 import org.drools.process.instance.WorkItemManagerFactory;
+import org.drools.process.instance.event.SignalManagerFactory;
 import org.drools.process.instance.impl.ContextInstanceFactory;
 import org.drools.process.instance.impl.ContextInstanceFactoryRegistry;
 import org.drools.spi.ConflictResolver;
@@ -134,6 +135,7 @@
     private ProcessInstanceFactoryRegistry processInstanceFactoryRegistry;
     private NodeInstanceFactoryRegistry    processNodeInstanceFactoryRegistry;
     private ProcessInstanceManagerFactory  processInstanceManagerFactory;
+    private SignalManagerFactory           processSignalManagerFactory;
     private WorkItemManagerFactory         workItemManagerFactory;
 
     private transient ClassLoader          classLoader;
@@ -831,6 +833,43 @@
         }
     }
 
+    public SignalManagerFactory getSignalManagerFactory() {
+        if ( this.processSignalManagerFactory == null ) {
+            initSignalManagerFactory();
+        }
+        return this.processSignalManagerFactory;
+    }
+
+    @SuppressWarnings("unchecked")
+	private void initSignalManagerFactory() {
+        String className = this.chainedProperties.getProperty( "processSignalManagerFactory",
+                                                               "org.drools.process.instance.event.DefaultSignalManagerFactory" );
+        Class<SignalManagerFactory> clazz = null;
+        try {
+            clazz = (Class<SignalManagerFactory>)
+            	Thread.currentThread().getContextClassLoader().loadClass( className );
+        } catch ( ClassNotFoundException e ) {
+        }
+
+        if ( clazz == null ) {
+            try {
+                clazz = (Class<SignalManagerFactory>)
+                	RuleBaseConfiguration.class.getClassLoader().loadClass( className );
+            } catch ( ClassNotFoundException e ) {
+            }
+        }
+
+        if ( clazz != null ) {
+            try {
+                this.processSignalManagerFactory = clazz.newInstance();
+            } catch ( Exception e ) {
+                throw new IllegalArgumentException( "Unable to instantiate signal manager factory '" + className + "'" );
+            }
+        } else {
+            throw new IllegalArgumentException( "Signal manager factory '" + className + "' not found" );
+        }
+    }
+
     public WorkItemManagerFactory getWorkItemManagerFactory() {
         if ( this.workItemManagerFactory == null ) {
             initWorkItemManagerFactory();

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -22,6 +22,7 @@
 
 import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.WorkItemManager;
+import org.drools.process.instance.event.SignalManager;
 import org.drools.process.instance.timer.TimerManager;
 import org.drools.spi.AgendaFilter;
 import org.drools.spi.AsyncExceptionHandler;
@@ -279,6 +280,8 @@
 
     public TimerManager getTimerManager();
     
+    public SignalManager getSignalManager();
+    
     /**
      * Stops rule firing after the currect rule finishes executing
      *

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -62,6 +62,9 @@
 import org.drools.event.WorkingMemoryEventSupport;
 import org.drools.process.core.Process;
 import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.core.event.EventFilter;
+import org.drools.process.core.event.EventTypeFilter;
+import org.drools.process.instance.EventListener;
 import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.ProcessInstanceFactory;
 import org.drools.process.instance.ProcessInstanceFactoryRegistry;
@@ -69,6 +72,7 @@
 import org.drools.process.instance.WorkItemHandler;
 import org.drools.process.instance.WorkItemManager;
 import org.drools.process.instance.context.variable.VariableScopeInstance;
+import org.drools.process.instance.event.SignalManager;
 import org.drools.process.instance.timer.TimerManager;
 import org.drools.reteoo.EntryPointNode;
 import org.drools.reteoo.InitialFactHandle;
@@ -81,6 +85,7 @@
 import org.drools.rule.EntryPoint;
 import org.drools.rule.Rule;
 import org.drools.rule.TimeMachine;
+import org.drools.ruleflow.core.RuleFlowProcess;
 import org.drools.spi.Activation;
 import org.drools.spi.AgendaFilter;
 import org.drools.spi.AsyncExceptionHandler;
@@ -90,6 +95,9 @@
 import org.drools.time.SessionClock;
 import org.drools.time.TimerService;
 import org.drools.time.TimerServiceFactory;
+import org.drools.workflow.core.node.EventTrigger;
+import org.drools.workflow.core.node.StartNode;
+import org.drools.workflow.core.node.Trigger;
 
 /**
  * Implementation of <code>WorkingMemory</code>.
@@ -174,6 +182,8 @@
 
     private TimerManager                                     timerManager;
 
+    private SignalManager									 signalManager;
+
     private TimeMachine                                      timeMachine;
 
     protected transient ObjectTypeConfigurationRegistry      typeConfReg;
@@ -259,6 +269,7 @@
         TimerService timerService = TimerServiceFactory.getTimerService( this.config.getClockType() );
         this.timerManager = new TimerManager( this,
                                               timerService );
+        this.signalManager = conf.getSignalManagerFactory().createSignalManager( this );
 
         this.nodeMemories = new ConcurrentNodeMemories( this.ruleBase );
 
@@ -288,6 +299,7 @@
         this.firing = new AtomicBoolean( false );
         this.modifyContexts = new HashMap<InternalFactHandle, PropagationContext>();
 
+		initProcessEventListeners();
         initPartitionManagers();
         initTransient();
     }
@@ -1572,6 +1584,66 @@
         return workItemManager;
     }
 
+    public SignalManager getSignalManager() {
+    	return signalManager;
+    }
+
+	private void initProcessEventListeners() {
+		for (Process process: ruleBase.getProcesses()) {
+			if (process instanceof RuleFlowProcess) {
+				StartNode startNode = ((RuleFlowProcess) process).getStart();
+				List<Trigger> triggers = startNode.getTriggers();
+				if (triggers != null) {
+					for (Trigger trigger: triggers) {
+						if (trigger instanceof EventTrigger) {
+							final List<EventFilter> filters = ((EventTrigger) trigger).getEventFilters();
+							String type = null;
+							for (EventFilter filter: filters) {
+								if (filter instanceof EventTypeFilter) {
+									type = ((EventTypeFilter) filter).getType();
+								}
+							}
+							getSignalManager().addEventListener(type, new StartProcessEventListener(process.getId(), filters, trigger.getInMappings()));
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	private class StartProcessEventListener implements EventListener {
+		private String processId;
+		private List<EventFilter> eventFilters;
+		private Map<String, String> inMappings;
+		public StartProcessEventListener(String processId, List<EventFilter> eventFilters, Map<String, String> inMappings) {
+			this.processId = processId;
+			this.eventFilters = eventFilters;
+			this.inMappings = inMappings;
+		}
+		public String[] getEventTypes() {
+			return null;
+		}
+		public void signalEvent(String type, Object event) {
+			for (EventFilter filter: eventFilters) {
+				if (!filter.acceptsEvent(type, event)) {
+					return;
+				}
+			}
+			Map<String, Object> params = null;
+			if (inMappings != null && !inMappings.isEmpty()) {
+				 params = new HashMap<String, Object>();
+				 for (Map.Entry<String, String> entry: inMappings.entrySet()) {
+					 if ("event".equals(entry.getValue())) {
+						 params.put(entry.getKey(), event);
+					 } else {
+						 params.put(entry.getKey(), entry.getValue());
+					 }
+				 }
+			}
+			startProcess(processId, params);
+		}
+	}
+
     public TimerManager getTimerManager() {
         return timerManager;
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -105,6 +105,8 @@
     
     public Process getProcess(String id);
     
+    public Process[] getProcesses();
+    
     /**
      * Returns true if clazz represents an Event class. False otherwise.
      *  

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/DefaultSignalManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/DefaultSignalManager.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/DefaultSignalManager.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -0,0 +1,46 @@
+package org.drools.process.instance.event;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.drools.process.instance.EventListener;
+
+public class DefaultSignalManager implements SignalManager {
+	
+	private Map<String, List<EventListener>> processEventListeners;
+
+	public void addEventListener(String type, EventListener eventListener) {
+		if (processEventListeners == null) {
+			processEventListeners = new HashMap<String, List<EventListener>>();
+		}
+		List<EventListener> eventListeners = processEventListeners.get(type);
+		if (eventListeners == null) {
+			eventListeners = new CopyOnWriteArrayList<EventListener>();
+			processEventListeners.put(type, eventListeners);
+		}
+		eventListeners.add(eventListener);
+	}
+	
+	public void removeEventListener(String type, EventListener eventListener) {
+		if (processEventListeners != null) {
+			List<EventListener> eventListeners = processEventListeners.get(type);
+			if (eventListeners != null) {
+				eventListeners.remove(eventListener);
+			}
+		}
+	}
+	
+	public void signalEvent(String type, Object event) {
+		if (processEventListeners != null) {
+			List<EventListener> eventListeners = processEventListeners.get(type);
+			if (eventListeners != null) {
+				for (EventListener eventListener: eventListeners) {
+					eventListener.signalEvent(type, event);
+				}
+			}
+		}
+	}
+	
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/DefaultSignalManagerFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/DefaultSignalManagerFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/DefaultSignalManagerFactory.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -0,0 +1,11 @@
+package org.drools.process.instance.event;
+
+import org.drools.WorkingMemory;
+
+public class DefaultSignalManagerFactory implements SignalManagerFactory {
+
+	public SignalManager createSignalManager(WorkingMemory workingMemory) {
+		return new DefaultSignalManager();
+	}
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/SignalManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/SignalManager.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/SignalManager.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -0,0 +1,13 @@
+package org.drools.process.instance.event;
+
+import org.drools.process.instance.EventListener;
+
+public interface SignalManager {
+	
+	void signalEvent(String type, Object event);
+	
+	void addEventListener(String type, EventListener eventListener);
+	
+	void removeEventListener(String type, EventListener eventListener);
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/SignalManagerFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/SignalManagerFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/event/SignalManagerFactory.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -0,0 +1,9 @@
+package org.drools.process.instance.event;
+
+import org.drools.WorkingMemory;
+
+public interface SignalManagerFactory {
+	
+	SignalManager createSignalManager(WorkingMemory workingMemory);
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeNode.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeNode.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -240,56 +240,64 @@
     
     public void validateRemoveIncomingConnection(final String type, final Connection connection) {
         CompositeNode.NodeAndType nodeAndType = internalGetLinkedIncomingNode(type);
-        for (Connection inConnection: nodeAndType.getNode().getIncomingConnections(nodeAndType.getType())) {
-            if (((CompositeNodeStart) inConnection.getFrom()).getInNodeId() == connection.getFrom().getId()) {
-                ((NodeImpl) nodeAndType.getNode()).validateRemoveIncomingConnection(nodeAndType.getType(), inConnection);
-                return;
-            }
+        if (nodeAndType != null) {
+	        for (Connection inConnection: nodeAndType.getNode().getIncomingConnections(nodeAndType.getType())) {
+	            if (((CompositeNodeStart) inConnection.getFrom()).getInNodeId() == connection.getFrom().getId()) {
+	                ((NodeImpl) nodeAndType.getNode()).validateRemoveIncomingConnection(nodeAndType.getType(), inConnection);
+	                return;
+	            }
+	        }
+	        throw new IllegalArgumentException(
+	        	"Could not find internal incoming connection for node");
         }
-        throw new IllegalArgumentException(
-            "Could not find internal incoming connection for node");
     }
     
     public void removeIncomingConnection(String type, Connection connection) {
         super.removeIncomingConnection(type, connection);
         CompositeNode.NodeAndType nodeAndType = internalGetLinkedIncomingNode(type);
-        for (Connection inConnection: nodeAndType.getNode().getIncomingConnections(nodeAndType.getType())) {
-            if (((CompositeNodeStart) inConnection.getFrom()).getInNodeId() == connection.getFrom().getId()) {
-                Node compositeNodeStart = inConnection.getFrom();
-                ((ConnectionImpl) inConnection).terminate();
-                internalRemoveNode(compositeNodeStart);
-                return;
-            }
+        if (nodeAndType != null) {
+	        for (Connection inConnection: nodeAndType.getNode().getIncomingConnections(nodeAndType.getType())) {
+	            if (((CompositeNodeStart) inConnection.getFrom()).getInNodeId() == connection.getFrom().getId()) {
+	                Node compositeNodeStart = inConnection.getFrom();
+	                ((ConnectionImpl) inConnection).terminate();
+	                internalRemoveNode(compositeNodeStart);
+	                return;
+	            }
+	        }
+	        throw new IllegalArgumentException(
+	        	"Could not find internal incoming connection for node");
         }
-        throw new IllegalArgumentException(
-            "Could not find internal incoming connection for node");
     }
     
     public void validateRemoveOutgoingConnection(final String type, final Connection connection) {
         CompositeNode.NodeAndType nodeAndType = internalGetLinkedOutgoingNode(type);
-        for (Connection outConnection: nodeAndType.getNode().getOutgoingConnections(nodeAndType.getType())) {
-            if (((CompositeNodeEnd) outConnection.getTo()).getOutNodeId() == connection.getTo().getId()) {
-                ((NodeImpl) nodeAndType.getNode()).validateRemoveOutgoingConnection(nodeAndType.getType(), outConnection);
-                return;
-            }
+        if (nodeAndType != null) {
+	        for (Connection outConnection: nodeAndType.getNode().getOutgoingConnections(nodeAndType.getType())) {
+	            if (((CompositeNodeEnd) outConnection.getTo()).getOutNodeId() == connection.getTo().getId()) {
+	                ((NodeImpl) nodeAndType.getNode()).validateRemoveOutgoingConnection(nodeAndType.getType(), outConnection);
+	                return;
+	            }
+	        }
+	        throw new IllegalArgumentException(
+	            "Could not find internal outgoing connection for node");
         }
-        throw new IllegalArgumentException(
-            "Could not find internal outgoing connection for node");
     }
     
     public void removeOutgoingConnection(String type, Connection connection) {
         super.removeOutgoingConnection(type, connection);
         CompositeNode.NodeAndType nodeAndType = internalGetLinkedOutgoingNode(type);
-        for (Connection outConnection: nodeAndType.getNode().getOutgoingConnections(nodeAndType.getType())) {
-            if (((CompositeNodeEnd) outConnection.getTo()).getOutNodeId() == connection.getTo().getId()) {
-                Node compositeNodeEnd = outConnection.getTo();
-                ((ConnectionImpl) outConnection).terminate();
-                internalRemoveNode(compositeNodeEnd);
-                return;
-            }
+        if (nodeAndType != null) {
+	        for (Connection outConnection: nodeAndType.getNode().getOutgoingConnections(nodeAndType.getType())) {
+	            if (((CompositeNodeEnd) outConnection.getTo()).getOutNodeId() == connection.getTo().getId()) {
+	                Node compositeNodeEnd = outConnection.getTo();
+	                ((ConnectionImpl) outConnection).terminate();
+	                internalRemoveNode(compositeNodeEnd);
+	                return;
+	            }
+	        }
+	        throw new IllegalArgumentException(
+	            "Could not find internal outgoing connection for node");
         }
-        throw new IllegalArgumentException(
-            "Could not find internal outgoing connection for node");
     }
     
     public class NodeAndType {

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Constrainable.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Constrainable.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Constrainable.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -0,0 +1,7 @@
+package org.drools.workflow.core.node;
+
+public interface Constrainable {
+	
+	public void setConstraint(String constraint);
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/ConstraintTrigger.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/ConstraintTrigger.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/ConstraintTrigger.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -0,0 +1,15 @@
+package org.drools.workflow.core.node;
+
+public class ConstraintTrigger extends Trigger implements Constrainable {
+
+	private String constraint;
+
+	public String getConstraint() {
+		return constraint;
+	}
+
+	public void setConstraint(String constraint) {
+		this.constraint = constraint;
+	}
+	
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EventNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EventNode.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EventNode.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -5,6 +5,7 @@
 
 import org.drools.process.core.event.EventFilter;
 import org.drools.process.core.event.EventTransformer;
+import org.drools.process.core.event.EventTypeFilter;
 import org.drools.workflow.core.Connection;
 import org.drools.workflow.core.Node;
 import org.drools.workflow.core.impl.NodeImpl;
@@ -16,6 +17,7 @@
 	private List<EventFilter> filters = new ArrayList<EventFilter>();
 	private EventTransformer transformer;
 	private String variableName;
+	private String scope; 
 
 	public String getVariableName() {
 		return variableName;
@@ -40,6 +42,15 @@
 	public void setEventFilters(List<EventFilter> filters) {
 		this.filters = filters;
 	}
+	
+	public String getType() {
+		for (EventFilter filter: filters) {
+    		if (filter instanceof EventTypeFilter) {
+    			return ((EventTypeFilter) filter).getType();
+    		}
+    	}
+    	return null;
+	}
 		
 	public boolean acceptsEvent(String type, Object event) {
     	for (EventFilter filter: filters) {
@@ -58,6 +69,15 @@
 		return transformer;
 	}
 	
+	
+	public String getScope() {
+		return scope;
+	}
+
+	public void setScope(String scope) {
+		this.scope = scope;
+	}
+
 	public void validateAddIncomingConnection(final String type, final Connection connection) {
         throw new UnsupportedOperationException(
             "An event node does not have an incoming connection!");

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EventTrigger.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EventTrigger.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EventTrigger.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -0,0 +1,28 @@
+package org.drools.workflow.core.node;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.process.core.event.EventFilter;
+
+public class EventTrigger extends Trigger {
+
+	private List<EventFilter> filters = new ArrayList<EventFilter>();
+	
+	public void addEventFilter(EventFilter eventFilter) {
+		filters.add(eventFilter);
+	}
+	
+	public void removeEventFilter(EventFilter eventFilter) {
+		filters.remove(eventFilter);
+	}
+	
+	public List<EventFilter> getEventFilters() {
+		return filters;
+	}
+		
+	public void setEventFilters(List<EventFilter> filters) {
+		this.filters = filters;
+	}
+	
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/HumanTaskNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/HumanTaskNode.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/HumanTaskNode.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -23,6 +23,13 @@
         parameterDefinitions.add(new ParameterDefinitionImpl("ActorId", new StringDataType()));
         parameterDefinitions.add(new ParameterDefinitionImpl("Priority", new StringDataType()));
         parameterDefinitions.add(new ParameterDefinitionImpl("Comment", new StringDataType()));
+        parameterDefinitions.add(new ParameterDefinitionImpl("Skippable", new StringDataType()));
+        // TODO: initiator
+        // TODO: attachments
+        // TODO: deadlines
+        // TODO: delegates
+        // TODO: recipients
+        // TODO: ...
         work.setParameterDefinitions(parameterDefinitions);
         setWork(work);
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/MilestoneNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/MilestoneNode.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/MilestoneNode.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -22,7 +22,7 @@
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class MilestoneNode extends EventBasedNode {
+public class MilestoneNode extends EventBasedNode implements Constrainable {
 
 	private static final long serialVersionUID = 8552568488755348247L;
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/StartNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/StartNode.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/StartNode.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -16,6 +16,9 @@
  * limitations under the License.
  */
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.drools.workflow.core.Connection;
 
 /**
@@ -26,7 +29,30 @@
 public class StartNode extends SequenceNode {
 
     private static final long serialVersionUID = 400L;
+    
+    private List<Trigger> triggers;
 
+	public void addTrigger(Trigger trigger) {
+		if (triggers == null) {
+			triggers = new ArrayList<Trigger>();
+		}
+		triggers.add(trigger);
+	}
+	
+	public void removeTrigger(Trigger trigger) {
+		if (triggers != null) {
+			triggers.remove(trigger);
+		}
+	}
+	
+	public List<Trigger> getTriggers() {
+		return triggers;
+	}
+		
+	public void setTriggers(List<Trigger> triggers) {
+		this.triggers = triggers;
+	}
+		
     public void validateAddIncomingConnection(final String type, final Connection connection) {
         throw new UnsupportedOperationException(
             "A start node does not have an incoming connection!");
@@ -36,5 +62,5 @@
         throw new UnsupportedOperationException(
             "A start node does not have an incoming connection!");
     }
-
+    
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Trigger.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Trigger.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Trigger.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -0,0 +1,49 @@
+package org.drools.workflow.core.node;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.drools.process.core.context.variable.Mappable;
+
+public class Trigger implements Mappable {
+	
+    private Map<String, String> inMapping = new HashMap<String, String>();
+
+    public void addInMapping(String subVariableName, String variableName) {
+        inMapping.put(subVariableName, variableName);
+    }
+    
+    public void setInMappings(Map<String, String> inMapping) {
+        this.inMapping = inMapping;
+    }
+    
+    public String getInMapping(String parameterName) {
+        return inMapping.get(parameterName);
+    }
+
+    public Map<String, String> getInMappings() {
+        return Collections.unmodifiableMap(inMapping);
+    }
+    
+    public void addOutMapping(String subVariableName, String variableName) {
+        throw new IllegalArgumentException(
+    		"A trigger does not support out mappings");
+    }
+    
+    public void setOutMappings(Map<String, String> outMapping) {
+        throw new IllegalArgumentException(
+			"A trigger does not support out mappings");
+    }
+    
+    public String getOutMapping(String parameterName) {
+        throw new IllegalArgumentException(
+			"A trigger does not support out mappings");
+    }
+
+    public Map<String, String> getOutMappings() {
+        throw new IllegalArgumentException(
+        	"A trigger does not support out mappings");
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/WorkflowProcessInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/WorkflowProcessInstance.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/WorkflowProcessInstance.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -31,8 +31,8 @@
 
     WorkflowProcess getWorkflowProcess();
     
-    void addEventListener(String type, EventListener eventListener);
+    void addEventListener(String type, EventListener eventListener, boolean external);
     
-    void removeEventListener(String type, EventListener eventListener);
+    void removeEventListener(String type, EventListener eventListener, boolean external);
 
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceFactoryRegistry.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceFactoryRegistry.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceFactoryRegistry.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -89,6 +89,14 @@
     }
 
     public NodeInstanceFactory getProcessNodeInstanceFactory(Node node) {
-        return this.registry.get( node.getClass() );
+    	Class<?> clazz = node.getClass();
+        while (clazz != null) {
+        	NodeInstanceFactory result = this.registry.get( clazz );
+        	if (result != null) {
+        		return result;
+        	}
+        	clazz = clazz.getSuperclass();
+        }
+        return null;
     }
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/WorkflowProcessInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/WorkflowProcessInstanceImpl.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/WorkflowProcessInstanceImpl.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -26,25 +26,23 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.drools.Agenda;
-import org.drools.WorkingMemory;
 import org.drools.common.EventSupport;
 import org.drools.common.InternalRuleBase;
 import org.drools.common.InternalWorkingMemory;
-import org.drools.event.DefaultRuleFlowEventListener;
-import org.drools.event.RuleFlowCompletedEvent;
-import org.drools.event.RuleFlowEventListener;
 import org.drools.process.instance.EventListener;
 import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.impl.ProcessInstanceImpl;
 import org.drools.workflow.core.Node;
 import org.drools.workflow.core.NodeContainer;
 import org.drools.workflow.core.WorkflowProcess;
+import org.drools.workflow.core.node.EventNode;
 import org.drools.workflow.core.node.EventNodeInterface;
 import org.drools.workflow.instance.NodeInstance;
 import org.drools.workflow.instance.NodeInstanceContainer;
 import org.drools.workflow.instance.WorkflowProcessInstance;
 import org.drools.workflow.instance.node.EventBasedNodeInstance;
 import org.drools.workflow.instance.node.EventBasedNodeInstanceInterface;
+import org.drools.workflow.instance.node.EventNodeInstance;
 import org.drools.workflow.instance.node.EventNodeInstanceInterface;
 
 /**
@@ -60,7 +58,7 @@
     private final List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>();;
     private long nodeInstanceCounter = 0;
     private Map<String, List<EventListener>> eventListeners = new HashMap<String, List<EventListener>>();
-    private transient RuleFlowEventListener processInstanceEventListener;
+    private Map<String, List<EventListener>> externalEventListeners = new HashMap<String, List<EventListener>>();
 
     public NodeContainer getNodeContainer() {
         return getWorkflowProcess();
@@ -154,11 +152,6 @@
         return (WorkflowProcess) getProcess();
     }
     
-    public void start() {
-    	addEventListeners();
-    	super.start();
-    }
-
     public void setState(final int state) {
         super.setState( state );
         // TODO move most of this to ProcessInstanceImpl
@@ -176,6 +169,9 @@
             workingMemory.removeProcessInstance( this );
             ((EventSupport) workingMemory).getRuleFlowEventSupport()
                 .fireAfterRuleFlowProcessCompleted( this, workingMemory );
+            
+			String type = "processInstanceCompleted:" + getId();
+			workingMemory.getSignalManager().signalEvent(type, this);
         }
     }
 
@@ -210,71 +206,100 @@
         return sb.toString();
     }
     
+    public void start() {
+    	registerExternalEventNodeListeners();
+    	super.start();
+    }
+    
+    private void registerExternalEventNodeListeners() {
+    	for (Node node: getWorkflowProcess().getNodes()) {
+			if (node instanceof EventNode) {
+				if ("external".equals(((EventNode) node).getScope())) {
+					addEventListener(((EventNode) node).getType(), new EventListener() {
+						public String[] getEventTypes() {
+							return null;
+						}
+						public void signalEvent(String type, Object event) {
+						}
+					}, true);
+				}
+			}
+    	}
+    }
+    
     public void signalEvent(String type, Object event) {
     	List<EventListener> listeners = eventListeners.get(type);
     	if (listeners != null) {
     		for (EventListener listener: listeners) {
     			listener.signalEvent(type, event);
     		}
-    	} else {
-    		for (Node node: getWorkflowProcess().getNodes()) {
-    			if (node instanceof EventNodeInterface) {
-    				if (((EventNodeInterface) node).acceptsEvent(type, event)) {
+    	}
+    	listeners = externalEventListeners.get(type);
+    	if (listeners != null) {
+    		for (EventListener listener: listeners) {
+    			listener.signalEvent(type, event);
+    		}
+    	}
+    	for (Node node: getWorkflowProcess().getNodes()) {
+			if (node instanceof EventNodeInterface) {
+				if (((EventNodeInterface) node).acceptsEvent(type, event)) {
+					if (node instanceof EventNode) {
+    					EventNodeInstance eventNodeInstance = (EventNodeInstance) getNodeInstance(node);
+    					eventNodeInstance.signalEvent(type, event);
+					} else {
     					List<NodeInstance> nodeInstances = getNodeInstances(node.getId());
     					if (nodeInstances != null && !nodeInstances.isEmpty()) {
     						for (NodeInstance nodeInstance: nodeInstances) {
     							((EventNodeInstanceInterface) nodeInstance).signalEvent(type, event);
     						}
-    					} else {
-	    					EventNodeInstanceInterface eventNodeInstance = (EventNodeInstanceInterface) getNodeInstance(node);
-	    					eventNodeInstance.signalEvent(type, event);
     					}
-    				}
-    			}
-    		}
-    	}
-    }
+					}
+				}
+			}
+		}
+	}
     
-    public void addEventListener(String type, EventListener listener) {
+    public void addEventListener(String type, EventListener listener, boolean external) {
+    	Map<String, List<EventListener>> eventListeners =
+    		external ? this.externalEventListeners : this.eventListeners;
     	List<EventListener> listeners = eventListeners.get(type);
     	if (listeners == null) {
     		listeners = new CopyOnWriteArrayList<EventListener>();
     		eventListeners.put(type, listeners);
+    		if (external) {
+    			getWorkingMemory().getSignalManager().addEventListener(type, this);
+    		}
     	}
         listeners.add(listener);
     }
     
-    public void removeEventListener(String type, EventListener listener) {
+    public void removeEventListener(String type, EventListener listener, boolean external) {
+    	Map<String, List<EventListener>> eventListeners =
+    		external ? this.externalEventListeners : this.eventListeners;
     	List<EventListener> listeners = eventListeners.get(type);
     	if (listeners != null) {
     		listeners.remove(listener);
+    		if (listeners.isEmpty()) {
+    			eventListeners.remove(type);
+    			if (external) {
+    				getWorkingMemory().getSignalManager().removeEventListener(type, this);
+    			}
+    		}
     	}
     }
     
 	private void addEventListeners() {
-		// TODO enable ruleflow event listener only when there is a sub-process node instance
-		// actively waiting for the completion of a process instance ?
-    	processInstanceEventListener = new DefaultRuleFlowEventListener() {
-    		public void afterRuleFlowCompleted(RuleFlowCompletedEvent event, WorkingMemory workingMemory) {
-    			ProcessInstance processInstance = event.getProcessInstance();
-    			String type = "processInstanceCompleted:" + processInstance.getId();
-    			List<EventListener> listeners = eventListeners.get(type);
-    	    	if (listeners != null) {
-    	    		for (EventListener listener: listeners) {
-    	    			listener.signalEvent(type, processInstance);
-    	    		}
-    	    	}
-    		}
-    	};
-        getWorkingMemory().addEventListener(processInstanceEventListener);
+		registerExternalEventNodeListeners();
     }
     
     private void removeEventListeners() {
-    	getWorkingMemory().removeEventListener(processInstanceEventListener);
+    	for (String type: externalEventListeners.keySet()) {
+			getWorkingMemory().getSignalManager().removeEventListener(type, this);
+		}
     }
     
     public String[] getEventTypes() {
-    	return eventListeners.keySet().toArray(new String[eventListeners.size()]);
+    	return externalEventListeners.keySet().toArray(new String[externalEventListeners.size()]);
     }
     
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/factory/CreateNewNodeFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/factory/CreateNewNodeFactory.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/factory/CreateNewNodeFactory.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -23,6 +23,7 @@
             nodeInstance.setProcessInstance(processInstance);
             return nodeInstance;
         } catch (Exception e) {
+        	e.printStackTrace();
             throw new RuntimeException("Unable to instantiate node: '"
                 + this.cls.getName() + "':" + e.getMessage());
         }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -23,13 +23,16 @@
 import java.util.List;
 
 import org.drools.common.InternalRuleBase;
+import org.drools.process.instance.EventListener;
 import org.drools.workflow.core.Connection;
 import org.drools.workflow.core.Node;
 import org.drools.workflow.core.NodeContainer;
 import org.drools.workflow.core.node.CompositeNode;
+import org.drools.workflow.core.node.EventNode;
 import org.drools.workflow.core.node.EventNodeInterface;
 import org.drools.workflow.instance.NodeInstance;
 import org.drools.workflow.instance.NodeInstanceContainer;
+import org.drools.workflow.instance.WorkflowProcessInstance;
 import org.drools.workflow.instance.impl.NodeInstanceFactory;
 import org.drools.workflow.instance.impl.NodeInstanceFactoryRegistry;
 import org.drools.workflow.instance.impl.NodeInstanceImpl;
@@ -46,6 +49,27 @@
     private final List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>();;
     private long nodeInstanceCounter = 0;
     
+    public void setProcessInstance(WorkflowProcessInstance processInstance) {
+    	super.setProcessInstance(processInstance);
+    	registerExternalEventNodeListeners();
+    }
+    
+    private void registerExternalEventNodeListeners() {
+    	for (Node node: getCompositeNode().getNodes()) {
+			if (node instanceof EventNode) {
+				if ("external".equals(((EventNode) node).getScope())) {
+					getProcessInstance().addEventListener(((EventNode) node).getType(), new EventListener() {
+						public String[] getEventTypes() {
+							return null;
+						}
+						public void signalEvent(String type, Object event) {
+						}
+					}, true);
+				}
+			}
+    	}
+    }
+    
     protected CompositeNode getCompositeNode() {
         return (CompositeNode) getNode();
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstance.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventBasedNodeInstance.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -11,7 +11,6 @@
 import org.drools.spi.KnowledgeHelper;
 import org.drools.workflow.core.DroolsAction;
 import org.drools.workflow.core.Node;
-import org.drools.workflow.core.impl.ExtendedNodeImpl;
 import org.drools.workflow.core.node.EventBasedNode;
 import org.drools.workflow.instance.NodeInstance;
 import org.drools.workflow.instance.impl.ExtendedNodeInstanceImpl;
@@ -84,11 +83,11 @@
     }
     
     protected void addTimerListener() {
-    	getProcessInstance().addEventListener("timerTriggered", this);
+    	getProcessInstance().addEventListener("timerTriggered", this, false);
     }
     
     public void removeEventListeners() {
-        getProcessInstance().removeEventListener("timerTriggered", this);
+        getProcessInstance().removeEventListener("timerTriggered", this, false);
     }
 
 	protected void triggerCompleted(String type, boolean remove) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SubProcessNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SubProcessNodeInstance.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SubProcessNodeInstance.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -105,12 +105,12 @@
     }
     
     private void addProcessListener() {
-        getProcessInstance().addEventListener("processInstanceCompleted:" + processInstanceId, this);
+        getProcessInstance().addEventListener("processInstanceCompleted:" + processInstanceId, this, true);
     }
 
     public void removeEventListeners() {
         super.removeEventListeners();
-        getProcessInstance().removeEventListener("processInstanceCompleted:" + processInstanceId, this);
+        getProcessInstance().removeEventListener("processInstanceCompleted:" + processInstanceId, this, true);
     }
 
 	public void signalEvent(String type, Object event) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/TimerNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/TimerNodeInstance.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/TimerNodeInstance.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -73,13 +73,13 @@
     public void addEventListeners() {
         super.addEventListeners();
         if (getTimerInstances() == null) {
-        	getProcessInstance().addEventListener("timerTriggered", this);
+        	getProcessInstance().addEventListener("timerTriggered", this, false);
         }
     }
     
     public void removeEventListeners() {
         super.removeEventListeners();
-        getProcessInstance().removeEventListener("timerTriggered", this);
+        getProcessInstance().removeEventListener("timerTriggered", this, false);
     }
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -176,14 +176,14 @@
     }
     
     private void addWorkItemListener() {
-        getProcessInstance().addEventListener("workItemCompleted", this);
-        getProcessInstance().addEventListener("workItemAborted", this);
+        getProcessInstance().addEventListener("workItemCompleted", this, false);
+        getProcessInstance().addEventListener("workItemAborted", this, false);
     }
     
     public void removeEventListeners() {
         super.removeEventListeners();
-        getProcessInstance().removeEventListener("workItemCompleted", this);
-        getProcessInstance().removeEventListener("workItemAborted", this);
+        getProcessInstance().removeEventListener("workItemCompleted", this, false);
+        getProcessInstance().removeEventListener("workItemAborted", this, false);
     }
     
     public void signalEvent(String type, Object event) {

Modified: labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/parser/ExternalSheetListenerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/parser/ExternalSheetListenerTest.java	2008-10-06 12:53:52 UTC (rev 23323)
+++ labs/jbossrules/trunk/drools-templates/src/test/java/org/drools/template/parser/ExternalSheetListenerTest.java	2008-10-06 13:07:47 UTC (rev 23324)
@@ -24,6 +24,7 @@
 import org.drools.event.WorkingMemoryEventListener;
 import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.WorkItemManager;
+import org.drools.process.instance.event.SignalManager;
 import org.drools.process.instance.timer.TimerManager;
 import org.drools.spi.AgendaFilter;
 import org.drools.spi.AgendaGroup;
@@ -409,6 +410,11 @@
                     return null;
                 }
 
+				public SignalManager getSignalManager() {
+					// TODO Auto-generated method stub
+					return null;
+				}
+
 				public void fireUntilHalt() {
 					// TODO Auto-generated method stub
 					




More information about the jboss-svn-commits mailing list