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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sun Apr 6 19:46:49 EDT 2008


Author: KrisVerlaenen
Date: 2008-04-06 19:46:49 -0400 (Sun, 06 Apr 2008)
New Revision: 19430

Added:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Context.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ContextContainer.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Contextable.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ParameterDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Work.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinitionExtension.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkEditor.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/datatype/impl/type/DateDataType.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/ContextContainerImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/timer/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/timer/Timer.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextInstanceContainer.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextableInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/AbstractContextInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/exception/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/exception/ExceptionHandlerInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/exception/ExceptionScopeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/variable/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/variable/VariableScopeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ContextInstanceFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ContextInstanceFactoryRegistry.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/factory/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/factory/ReuseContextInstanceFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/humantask/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/humantask/HumanTaskDialog.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/humantask/HumanTaskHandler.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerListener.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeExtension.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeContextNode.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/TimerNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/context/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/context/WorkflowContextInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/context/WorkflowReuseContextInstanceFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/TimerNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/WorkDefinitions.conf
   labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf
Removed:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ParameterDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Variable.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/VariableScope.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Work.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinitionExtension.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/VariableImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/VariableScopeImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/VariableScopeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/VariableScopeInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf
Modified:
   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/audit/WorkingMemoryFileLogger.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/DroolsMVELFactory.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/InternalWorkingMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Process.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/ProcessImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/WorkImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ProcessInstanceImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcess.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/RuleFlowGroup.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/Connection.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/Node.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeContainer.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/ConnectionImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeContainerImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EndNode.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/RuleSetNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Split.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/SubProcessNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/WorkItemNode.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/NodeInstanceImpl.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/impl/factory/ReuseNodeFactory.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/MilestoneNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/RuleSetNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SplitInstance.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/WorkItemNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/RuleFlowGroupTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/workflow/instance/node/MockNodeInstanceFactory.java
Log:
JBRULES-1548: ePDL: XML-based process definition language 
 - Ruleflow processes now stored using nicer XML format
JBRULES-1549: Workflow Context
 - Context as the basis for grouping nodes
JBRULES-1550: Workflow timer
 - Timer node + service
JBRULES-1551: Workflow human tasks
 - Added initial implementation for integration human tasks

Modified: labs/jbossrules/trunk/drools-core/.classpath
===================================================================
--- labs/jbossrules/trunk/drools-core/.classpath	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/.classpath	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,12 +1,12 @@
-<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/org/mvel/mvel/2.0-alpha2-dp3-java1.5/mvel-2.0-alpha2-dp3-java1.5.jar"/>
-  <classpathentry kind="var" path="M2_REPO/com/thoughtworks/xstream/xstream/1.2.2/xstream-1.2.2.jar"/>
-  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/xpp3/xpp3_min/1.1.3.4.O/xpp3_min-1.1.3.4.O.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.2.2/xstream-1.2.2.jar"/>
+  <classpathentry kind="var" path="M2_REPO/xpp3/xpp3_min/1.1.3.4.O/xpp3_min-1.1.3.4.O.jar"/>
+  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/.project	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,16 +1,16 @@
-<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>
-  </buildSpec>
-  <natures>
-    <nature>org.eclipse.jdt.core.javanature</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>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -22,14 +22,24 @@
 import java.io.ObjectOutput;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 import java.util.Map.Entry;
 
 import org.drools.common.AgendaGroupFactory;
 import org.drools.common.ArrayAgendaGroupFactory;
 import org.drools.common.PriorityQueueAgendaGroupFactory;
+import org.drools.process.core.Context;
+import org.drools.process.core.ParameterDefinition;
+import org.drools.process.core.WorkDefinition;
+import org.drools.process.core.datatype.DataType;
+import org.drools.process.core.impl.ParameterDefinitionImpl;
+import org.drools.process.core.impl.WorkDefinitionExtensionImpl;
+import org.drools.process.instance.impl.ContextInstanceFactory;
+import org.drools.process.instance.impl.ContextInstanceFactoryRegistry;
 import org.drools.spi.ConflictResolver;
 import org.drools.spi.ConsequenceExceptionHandler;
 import org.drools.temporal.SessionClock;
@@ -114,6 +124,8 @@
     private boolean                        useStaticObjenesis;
 
     private static final String            STAR             = "*";
+    private ContextInstanceFactoryRegistry processContextInstanceFactoryRegistry;
+    private Map<String, WorkDefinition> workDefinitions;
 
     private NodeInstanceFactoryRegistry    processNodeInstanceFactoryRegistry;
 
@@ -571,6 +583,117 @@
         }
     }
 
+    public Map<String, WorkDefinition> getProcessWorkDefinitions() {
+        if ( this.workDefinitions == null ) {
+            initWorkDefinitions();
+        }
+        return this.workDefinitions;
+
+    }
+
+    private void initWorkDefinitions() {
+        this.workDefinitions = new HashMap<String, WorkDefinition>();
+
+        // split on each space
+        String locations[] = this.chainedProperties.getProperty( "drools.workDefinitions",
+                                                                 "" ).split( "\\s" );
+
+        // load each SemanticModule
+        for ( String factoryLocation : locations ) {
+            // trim leading/trailing spaces and quotes
+            factoryLocation = factoryLocation.trim();
+            if ( factoryLocation.startsWith( "\"" ) ) {
+                factoryLocation = factoryLocation.substring( 1 );
+            }
+            if ( factoryLocation.endsWith( "\"" ) ) {
+                factoryLocation = factoryLocation.substring( 0,
+                                                             factoryLocation.length() - 1 );
+            }
+            if ( !factoryLocation.equals( "" ) ) {
+                loadWorkItems( factoryLocation );
+            }
+        }
+    }
+
+    private void loadWorkItems(String location) {
+        String content = ConfFileUtils.URLContentsToString( ConfFileUtils.getURL( location,
+                                                                                  null,
+                                                                                  RuleBaseConfiguration.class ) );
+        List<Map<String, Object>> workDefinitionsMap = (List<Map<String, Object>>) MVEL.eval(content, new HashMap());
+        for (Map<String, Object> workDefinitionMap: workDefinitionsMap) {
+            WorkDefinitionExtensionImpl workDefinition = new WorkDefinitionExtensionImpl();
+            workDefinition.setName((String) workDefinitionMap.get("name"));
+            workDefinition.setDisplayName((String) workDefinitionMap.get("displayName"));
+            workDefinition.setIcon((String) workDefinitionMap.get("icon"));
+            workDefinition.setCustomEditor((String) workDefinitionMap.get("customEditor"));
+            Set<ParameterDefinition> parameters = new HashSet<ParameterDefinition>();
+            Map<String, DataType> parameterMap = (Map<String, DataType>) workDefinitionMap.get("parameters");
+            if (parameterMap != null) {
+                for (Map.Entry<String, DataType> entry: parameterMap.entrySet()) {
+                    parameters.add(new ParameterDefinitionImpl(entry.getKey(), entry.getValue()));
+                }
+            }
+            workDefinition.setParameters(parameters);
+            Set<ParameterDefinition> results = new HashSet<ParameterDefinition>();
+            Map<String, DataType> resultMap = (Map<String, DataType>) workDefinitionMap.get("results");
+            if (resultMap != null) {
+                for (Map.Entry<String, DataType> entry: resultMap.entrySet()) {
+                    results.add(new ParameterDefinitionImpl(entry.getKey(), entry.getValue()));
+                }
+            }
+            workDefinition.setResults(results);
+            this.workDefinitions.put(workDefinition.getName(), workDefinition);
+        }
+    }
+
+    public ContextInstanceFactoryRegistry getProcessContextInstanceFactoryRegistry() {
+        if ( this.processContextInstanceFactoryRegistry == null ) {
+            initProcessContextInstanceFactoryRegistry();
+        }
+        return this.processContextInstanceFactoryRegistry;
+
+    }
+
+    private void initProcessContextInstanceFactoryRegistry() {
+        this.processContextInstanceFactoryRegistry = new ContextInstanceFactoryRegistry();
+
+        // split on each space
+        String locations[] = this.chainedProperties.getProperty( "processContextInstanceFactoryRegistry",
+                                                                 "" ).split( "\\s" );
+
+        int i = 0;
+        // load each SemanticModule
+        for ( String factoryLocation : locations ) {
+            // trim leading/trailing spaces and quotes
+            factoryLocation = factoryLocation.trim();
+            if ( factoryLocation.startsWith( "\"" ) ) {
+                factoryLocation = factoryLocation.substring( 1 );
+            }
+            if ( factoryLocation.endsWith( "\"" ) ) {
+                factoryLocation = factoryLocation.substring( 0,
+                                                             factoryLocation.length() - 1 );
+            }
+            if ( !factoryLocation.equals( "" ) ) {
+                loadProcessContextInstanceFactoryRegistry( factoryLocation );
+            }
+        }
+    }
+
+    private void loadProcessContextInstanceFactoryRegistry(String factoryLocation) {
+        String content = ConfFileUtils.URLContentsToString( ConfFileUtils.getURL( factoryLocation,
+                                                                                  null,
+                                                                                  RuleBaseConfiguration.class ) );
+        
+        Map<Class< ? extends Context>, ContextInstanceFactory> map = (Map<Class< ? extends Context>, ContextInstanceFactory>) MVEL.eval( content, new HashMap() );
+
+        if ( map != null ) {
+            for ( Entry<Class< ? extends Context>, ContextInstanceFactory> entry : map.entrySet() ) {
+                this.processContextInstanceFactoryRegistry.register( entry.getKey(),
+                                                                     entry.getValue() );
+            }
+        }
+    }
+
     private boolean determineShadowProxy(String userValue) {
         if ( this.isSequential() ) {
             // sequential never needs shadowing, so always override

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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -23,6 +23,7 @@
 
 import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.WorkItemManager;
+import org.drools.process.instance.timer.TimerManager;
 import org.drools.spi.AgendaFilter;
 import org.drools.spi.AgendaGroup;
 import org.drools.spi.AsyncExceptionHandler;
@@ -281,7 +282,7 @@
      * This list is unmodifiable.
      * @return the list of process instances
      */
-    public Collection getProcessInstances();
+    public Collection<ProcessInstance> getProcessInstances();
 
     /**
      * Returns the process instance with the given id.
@@ -291,6 +292,8 @@
 
     public WorkItemManager getWorkItemManager();
 
+    public TimerManager getTimerManager();
+    
     /**
      * Stops rule firing after the currect rule finishes executing
      *

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryFileLogger.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryFileLogger.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/audit/WorkingMemoryFileLogger.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -109,7 +109,7 @@
         }
         FileWriter fileWriter = null;
         try {
-            fileWriter = new FileWriter(this.fileName + (this.nbOfFile == 0 ? ".log" : this.nbOfFile + ".log"), !split );
+            fileWriter = new FileWriter(this.fileName + (this.nbOfFile == 0 ? ".log" : this.nbOfFile + ".log"), true );
             final XStream xstream = new XStream();
             for (LogEvent event : this.events) {
                 fileWriter.write(xstream.toXML(event) + "\n");

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/DroolsMVELFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/DroolsMVELFactory.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/DroolsMVELFactory.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -188,6 +188,9 @@
 
     public void setLocalValue(final String identifier,
                               final Object value) {
+        if (this.localVariables == null) {
+            this.localVariables = new HashMap();
+        }
         this.localVariables.put( identifier,
                                  value );
     }

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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -63,9 +63,14 @@
 import org.drools.event.WorkingMemoryEventListener;
 import org.drools.event.WorkingMemoryEventSupport;
 import org.drools.process.core.Process;
+import org.drools.process.core.context.variable.Variable;
+import org.drools.process.core.context.variable.VariableScope;
 import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.ProcessInstanceFactory;
 import org.drools.process.instance.WorkItemManager;
+import org.drools.process.instance.context.variable.VariableScopeInstance;
+import org.drools.process.instance.timer.TimerManager;
+import org.drools.reteoo.ClassObjectTypeConf;
 import org.drools.reteoo.EntryPointNode;
 import org.drools.reteoo.LIANodePropagation;
 import org.drools.reteoo.ObjectTypeConf;
@@ -167,8 +172,10 @@
 
     private WorkItemManager                             workItemManager;
 
-    private Map<String, ProcessInstanceFactory>         processInstanceFactories                      = new HashMap();
+    private TimerManager                                 timerManager;
 
+    private Map<String, ProcessInstanceFactory>          processInstanceFactories                      = new HashMap();
+
     private TimeMachine                                 timeMachine                                   = new TimeMachine();
 
     protected transient ObjectTypeConfigurationRegistry typeConfReg;
@@ -222,7 +229,6 @@
             this.discardOnLogicalOverride = false;
         }
 
-        this.workItemManager = new WorkItemManager( this );
         this.processInstanceFactories.put( RuleFlowProcess.RULEFLOW_TYPE,
                                            new RuleFlowProcessInstanceFactory() );        
         this.entryPoints = new ConcurrentHashMap();
@@ -1452,6 +1458,9 @@
 
     public ProcessInstance startProcess(String processId,
                                         Map<String, Object> parameters) {
+        if ( !this.actionQueue.isEmpty() ) {
+            executeQueuedActions();
+        }
         final Process process = ((InternalRuleBase) getRuleBase()).getProcess( processId );
         if ( process == null ) {
             throw new IllegalArgumentException( "Unknown process ID: " + processId );
@@ -1466,12 +1475,29 @@
         processInstance.setId( ++processCounter );
         processInstances.put( new Long( processInstance.getId() ),
                               processInstance );
-        if ( parameters != null ) {
-            for ( Map.Entry<String, Object> entry : parameters.entrySet() ) {
-                processInstance.setVariable( entry.getKey(),
-                                             entry.getValue() );
+        // set variable default values
+        // TODO: should be part of processInstanceImpl?
+        VariableScope variableScope = (VariableScope)
+            process.getDefaultContext(VariableScope.VARIABLE_SCOPE);
+        VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+            processInstance.getContextInstance(VariableScope.VARIABLE_SCOPE);
+        if (variableScope != null) {
+            for (Variable variable: variableScope.getVariables()) {
+                variableScopeInstance.setVariable(variable.getName(), variable.getValue());
             }
         }
+        // set input parameters
+        if (parameters != null) {
+            if (variableScope != null) {
+                for (Map.Entry<String, Object> entry: parameters.entrySet()) {
+                    variableScopeInstance.setVariable(entry.getKey(), entry.getValue());
+                }
+            } else {
+                throw new IllegalArgumentException(
+                    "This process does not support parameters!");
+            }
+        }
+        // start
         getRuleFlowEventSupport().fireBeforeRuleFlowProcessStarted( processInstance,
                                                                     this );
         processInstance.start();
@@ -1489,8 +1515,12 @@
         return (ProcessInstance) processInstances.get( new Long( id ) );
     }
 
+    public void addProcessInstance(ProcessInstance processInstance) {
+        processInstances.put( processInstance.getId(), processInstance );
+    }
+    
     public void removeProcessInstance(ProcessInstance processInstance) {
-        processInstances.remove( processInstance );
+        processInstances.remove( processInstance.getId() );
     }
 
     public void registerProcessInstanceFactory(String type,
@@ -1500,9 +1530,19 @@
     }
 
     public WorkItemManager getWorkItemManager() {
+        if (workItemManager == null) {
+            workItemManager = new WorkItemManager( this );
+        }
         return workItemManager;
     }
 
+    public TimerManager getTimerManager() {
+        if (timerManager == null) {
+            timerManager = new TimerManager(this);
+        }
+        return timerManager;
+    }
+
     public List iterateObjectsToList() {
         List result = new ArrayList();
         Iterator iterator = iterateObjects();

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -84,6 +84,8 @@
 	public TimeMachine getTimeMachine();
 
 	public void setTimeMachine(TimeMachine tm);
+	
+    public void addProcessInstance(ProcessInstance processInstance);
     
     public void removeProcessInstance(ProcessInstance processInstance);
        

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Context.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Context.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Context.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,17 @@
+package org.drools.process.core;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface Context {
+
+    String getType();
+    
+    long getId();
+    
+    void setId(long id);
+    
+    Context resolveContext(Object param);
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ContextContainer.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ContextContainer.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ContextContainer.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,20 @@
+package org.drools.process.core;
+
+import java.util.List;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface ContextContainer {
+
+    List<Context> getContexts(String contextType);
+    
+    void addContext(Context context);
+    
+    Context getContext(String contextType, long id);
+    
+    void setDefaultContext(Context context);
+    
+    Context getDefaultContext(String contextType);
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Contextable.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Contextable.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Contextable.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,13 @@
+package org.drools.process.core;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface Contextable {
+
+    void setContext(String contextType, Context context);
+    
+    Context getContext(String contextType);
+    
+}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ParameterDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ParameterDefinition.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ParameterDefinition.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,17 +0,0 @@
-package org.drools.process.core;
-
-import org.drools.process.core.datatype.DataType;
-
-/**
- * 
- * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
- */
-public interface ParameterDefinition {
-    
-    String getName();
-    void setName(String name);
-    
-    DataType getType();
-    void setType(DataType type);
-    
-}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ParameterDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ParameterDefinition.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/ParameterDefinition.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,17 @@
+package org.drools.process.core;
+
+import org.drools.process.core.datatype.DataType;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface ParameterDefinition {
+    
+    String getName();
+    void setName(String name);
+    
+    DataType getType();
+    void setType(DataType type);
+    
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Process.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Process.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Process.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,6 +1,7 @@
 package org.drools.process.core;
 
 
+
 /*
  * Copyright 2005 JBoss Inc
  * 
@@ -26,7 +27,7 @@
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public interface Process extends VariableScope {
+public interface Process extends ContextContainer {
 
     /**
      * Sets the id of this process.
@@ -92,5 +93,9 @@
      * @return	the package name of this RuleFlow process
      */
     String getPackageName();
+    
+    void setMetaData(String name, Object value);
+    
+    Object getMetaData(String name);
 
 }

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Variable.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Variable.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Variable.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,44 +0,0 @@
-package org.drools.process.core;
-
-/*
- * Copyright 2005 JBoss Inc
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.Serializable;
-
-import org.drools.process.core.datatype.DataType;
-
-/**
- * Represents a global variable used in a RuleFlow.
- * A variable has a name (should be unique for this process), a datatype
- * and possibly an initial value.  
- * 
- * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
- */
-public interface Variable {
-
-    String getName();
-
-    void setName(String name);
-
-    DataType getType();
-
-    void setType(DataType type);
-
-    Serializable getValue();
-
-    void setValue(Serializable value);
-
-}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/VariableScope.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/VariableScope.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/VariableScope.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,34 +0,0 @@
-package org.drools.process.core;
-
-import java.util.List;
-
-
-/**
- * 
- * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
- */
-public interface VariableScope {
-
-    /**
-     * Returns the variables used in this scope
-     * 
-     * @return  a list of variables of this scope
-     */
-    List<Variable> getVariables();
-
-    /**
-     * Returns the names of the variables used in this scope
-     * 
-     * @return  the variable names of this scope
-     */
-    String[] getVariableNames();
-    
-    /**
-     * Sets the variables used in this scope
-     * 
-     * @param variables the variables
-     * @throws IllegalArugmentException if <code>variables</code> is null
-     */
-    void setVariables(List<Variable> variables);
-    
-}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Work.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Work.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Work.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,19 +0,0 @@
-package org.drools.process.core;
-
-import java.util.Map;
-
-/**
- * 
- * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
- */
-public interface Work {
-
-    void setName(String name);
-    String getName();
-    
-    void setParameter(String name, Object value);
-    void setParameters(Map<String, Object> parameters);
-    Object getParameter(String name);
-    Map<String, Object> getParameters();
-
-}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Work.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Work.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/Work.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,27 @@
+package org.drools.process.core;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface Work {
+
+    void setName(String name);
+    String getName();
+    
+    void setParameter(String name, Object value);
+    void setParameters(Map<String, Object> parameters);
+    Object getParameter(String name);
+    Map<String, Object> getParameters();
+    
+    void addParameterDefinition(ParameterDefinition parameterDefinition);
+    void setParameterDefinitions(Set<ParameterDefinition> parameterDefinitions);
+    Set<ParameterDefinition> getParameterDefinitions();
+    String[] getParameterNames();
+    ParameterDefinition getParameterDefinition(String name);
+    
+}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinition.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinition.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,21 +0,0 @@
-package org.drools.process.core;
-
-import java.util.Set;
-
-/**
- * 
- * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
- */
-public interface WorkDefinition {
-    
-    String getName();
-    
-    Set<ParameterDefinition> getParameters();
-    String[] getParameterNames();
-    ParameterDefinition getParameter(String name);
-    
-    Set<ParameterDefinition> getResults();
-    String[] getResultNames();
-    ParameterDefinition getResult(String name);
-    
-}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinition.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinition.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,21 @@
+package org.drools.process.core;
+
+import java.util.Set;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface WorkDefinition {
+    
+    String getName();
+    
+    Set<ParameterDefinition> getParameters();
+    String[] getParameterNames();
+    ParameterDefinition getParameter(String name);
+    
+    Set<ParameterDefinition> getResults();
+    String[] getResultNames();
+    ParameterDefinition getResult(String name);
+    
+}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinitionExtension.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinitionExtension.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinitionExtension.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,17 +0,0 @@
-package org.drools.process.core;
-
-/**
- * 
- * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
- */
-public interface WorkDefinitionExtension {
-    
-    String getDisplayName();
-    
-    String getExplanationText();
-    
-    String getIcon();
-    
-    String getCustomEditor();
-
-}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinitionExtension.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinitionExtension.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkDefinitionExtension.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,17 @@
+package org.drools.process.core;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface WorkDefinitionExtension {
+    
+    String getDisplayName();
+    
+    String getExplanationText();
+    
+    String getIcon();
+    
+    String getCustomEditor();
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkEditor.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkEditor.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/WorkEditor.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,16 @@
+package org.drools.process.core;
+
+import org.drools.process.core.Work;
+import org.drools.process.core.WorkDefinition;
+
+public interface WorkEditor {
+    
+    void setWorkDefinition(WorkDefinition definition);
+    
+    void setWork(Work work);
+    
+    void show();
+    
+    Work getWork();
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/datatype/impl/type/DateDataType.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/datatype/impl/type/DateDataType.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/datatype/impl/type/DateDataType.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,47 @@
+package org.drools.process.core.datatype.impl.type;
+
+/*
+ * Copyright 2005 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Date;
+
+import org.drools.process.core.datatype.DataType;
+
+/**
+ * Representation of a date datatype.
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public final class DateDataType implements DataType {
+
+    private static final long serialVersionUID = 400L;
+
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+    }
+
+    public boolean verifyDataType(final Object value) {
+        if ( value instanceof Date ) {
+            return true;
+        }
+        return false;
+    }
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/ContextContainerImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/ContextContainerImpl.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/ContextContainerImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,60 @@
+package org.drools.process.core.impl;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.process.core.Context;
+import org.drools.process.core.ContextContainer;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class ContextContainerImpl implements Serializable, ContextContainer {
+
+    private static final long serialVersionUID = 400L;
+
+    private Map<String, Context> defaultContexts = new HashMap<String, Context>();
+    private Map<String, List<Context>> subContexts = new HashMap<String, List<Context>>();
+    private long lastContextId;
+
+    public List<Context> getContexts(String contextType) {
+        return this.subContexts.get(contextType);
+    }
+    
+    public void addContext(Context context) {
+        List<Context> list = this.subContexts.get(context.getType());
+        if (list == null) {
+            list = new ArrayList<Context>();
+            this.subContexts.put(context.getType(), list);
+        }
+        if (!list.contains(context)) {
+            list.add(context);
+            context.setId(++lastContextId);
+        }
+    }
+    
+    public Context getContext(String contextType, long id) {
+        List<Context> list = this.subContexts.get(contextType);
+        if (list != null) {
+            for (Context context: list) {
+                if (context.getId() == id) {
+                    return context;
+                }
+            }
+        }
+        return null;
+    }
+
+    public void setDefaultContext(Context context) {
+        this.defaultContexts.put(context.getType(), context);
+    }
+    
+    public Context getDefaultContext(String contextType) {
+        return defaultContexts.get(contextType);
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/ProcessImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/ProcessImpl.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/ProcessImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -17,11 +17,13 @@
  */
 
 import java.io.Serializable;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import org.drools.process.core.Context;
+import org.drools.process.core.ContextContainer;
 import org.drools.process.core.Process;
-import org.drools.process.core.Variable;
-import org.drools.process.core.VariableScope;
 
 /**
  * Default implementation of a Process
@@ -32,13 +34,14 @@
     
     private static final long serialVersionUID = 400L;
 
-    private String            id;
-    private String            name;
-    private String            version;
-    private String            type;
-    private String			  packageName;
-    private VariableScope     variableScope = new VariableScopeImpl();
-
+    private String id;
+    private String name;
+    private String version;
+    private String type;
+    private String packageName;
+    private ContextContainer contextContainer = new ContextContainerImpl();
+    private Map<String, Object> metaData = new HashMap<String, Object>();
+    
     public void setId(final String id) {
         this.id = id;
     }
@@ -79,17 +82,25 @@
 		this.packageName = packageName;
 	}
 
-    public List<Variable> getVariables() {
-        return variableScope.getVariables();
+	public List<Context> getContexts(String contextType) {
+	    return this.contextContainer.getContexts(contextType);
+	}
+    
+    public void addContext(Context context) {
+        this.contextContainer.addContext(context);
     }
-
-    public void setVariables(final List<Variable> variables) {
-        variableScope.setVariables(variables);
+    
+    public Context getContext(String contextType, long id) {
+        return this.contextContainer.getContext(contextType, id);
     }
 
-    public String[] getVariableNames() {
-        return variableScope.getVariableNames();
+    public void setDefaultContext(Context context) {
+        this.contextContainer.setDefaultContext(context);
     }
+    
+    public Context getDefaultContext(String contextType) {
+        return this.contextContainer.getDefaultContext(contextType);
+    }
 
     public boolean equals(final Object o) {
         if ( o instanceof ProcessImpl ) {
@@ -101,4 +112,24 @@
     public int hashCode() {
         return this.name.hashCode() + 3 * this.version.hashCode();
     }
+
+    public Context resolveContext(String contextId, Object param) {
+        Context context = getDefaultContext(contextId);
+        if (context != null) {
+            context = context.resolveContext(param);
+            if (context != null) {
+                return context;
+            }
+        }
+        return null;
+    }
+    
+    public void setMetaData(String name, Object data) {
+        this.metaData.put(name, data);
+    }
+    
+    public Object getMetaData(String name) {
+        return this.metaData.get(name);
+    }
+    
 }
\ No newline at end of file

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/VariableImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/VariableImpl.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/VariableImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,81 +0,0 @@
-package org.drools.process.core.impl;
-
-/*
- * Copyright 2005 JBoss Inc
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.Serializable;
-
-import org.drools.process.core.Variable;
-import org.drools.process.core.datatype.DataType;
-import org.drools.process.core.datatype.impl.type.UndefinedDataType;
-
-/**
- * Default implementation of a variable.
- * 
- * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
- */
-public class VariableImpl implements Variable, Serializable {
-
-    private static final long serialVersionUID = 400L;
-
-    private String            name;
-    private DataType         type;
-    private Serializable      value;
-
-    public VariableImpl() {
-        this.type = UndefinedDataType.getInstance();
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(final String name) {
-        this.name = name;
-    }
-
-    public DataType getType() {
-        return this.type;
-    }
-
-    public void setType(final DataType type) {
-        if ( type == null ) {
-            throw new IllegalArgumentException( "type is null" );
-        }
-        this.type = type;
-    }
-
-    public Serializable getValue() {
-        return this.value;
-    }
-
-    public void setValue(final Serializable value) {
-        if ( this.type.verifyDataType( value ) ) {
-            this.value = value;
-        } else {
-            final StringBuffer sb = new StringBuffer();
-            sb.append( "Value <" );
-            sb.append( value );
-            sb.append( "> is not valid for datatype: " );
-            sb.append( this.type );
-            throw new IllegalArgumentException( sb.toString() );
-        }
-    }
-
-    public String toString() {
-        return this.name;
-    }
-}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/VariableScopeImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/VariableScopeImpl.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/VariableScopeImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,45 +0,0 @@
-package org.drools.process.core.impl;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.drools.process.core.Variable;
-import org.drools.process.core.VariableScope;
-
-/**
- * 
- * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
- */
-public class VariableScopeImpl implements VariableScope, Serializable {
-
-    private static final long serialVersionUID = 400L;
-    
-    private List<Variable> variables;
-    
-    public VariableScopeImpl() {
-        this.variables = new ArrayList<Variable>();
-    }
-
-    public List<Variable> getVariables() {
-        return this.variables;
-    }
-
-    public void setVariables(final List<Variable> variables) {
-        if ( variables == null ) {
-            throw new IllegalArgumentException( "Variables is null" );
-        }
-        this.variables = variables;
-    }
-
-    public String[] getVariableNames() {
-        final String[] result = new String[this.variables.size()];
-        if (this.variables != null) {
-            for ( int i = 0; i < this.variables.size(); i++ ) {
-                result[i] = ((Variable) this.variables.get( i )).getName();
-            }
-        }
-        return result;
-    }
-
-}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/WorkImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/WorkImpl.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/impl/WorkImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -3,8 +3,12 @@
 import java.io.Serializable;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
+import org.drools.process.core.ParameterDefinition;
 import org.drools.process.core.Work;
 
 /**
@@ -17,6 +21,7 @@
     
     private String name;
     private Map<String, Object> parameters = new HashMap<String, Object>();
+    private Map<String, ParameterDefinition> parameterDefinitions = new HashMap<String, ParameterDefinition>();
     
     public void setName(String name) {
         this.name = name;
@@ -54,4 +59,27 @@
     public String toString() {
         return "Work " + name;
     }
+
+    public void setParameterDefinitions(Set<ParameterDefinition> parameterDefinitions) {
+        this.parameterDefinitions.clear();
+        for (ParameterDefinition parameterDefinition: parameterDefinitions) {
+            addParameterDefinition(parameterDefinition);
+        }        
+    }
+
+    public void addParameterDefinition(ParameterDefinition parameterDefinition) {
+        this.parameterDefinitions.put(parameterDefinition.getName(), parameterDefinition);
+    }
+
+    public Set<ParameterDefinition> getParameterDefinitions() {
+        return new HashSet<ParameterDefinition>(parameterDefinitions.values());        
+    }
+
+    public String[] getParameterNames() {
+        return parameterDefinitions.keySet().toArray(new String[parameterDefinitions.size()]);
+    }
+
+    public ParameterDefinition getParameterDefinition(String name) {
+        return parameterDefinitions.get(name);
+    }
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/timer/Timer.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/timer/Timer.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/timer/Timer.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,33 @@
+package org.drools.process.core.timer;
+
+public class Timer {
+
+    private long id;
+    private long delay;
+    private long period;
+    
+    public long getId() {
+        return id;
+    }
+    
+    public void setId(long id) {
+        this.id = id;
+    }
+    
+    public long getDelay() {
+        return delay;
+    }
+    
+    public void setDelay(long delay) {
+        this.delay = delay;
+    }
+    
+    public long getPeriod() {
+        return period;
+    }
+    
+    public void setPeriod(long period) {
+        this.period = period;
+    }
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextInstance.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,19 @@
+package org.drools.process.instance;
+
+import org.drools.process.core.Context;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface ContextInstance {
+    
+    String getContextType();
+    
+    long getContextId();
+    
+    ContextInstanceContainer getContextInstanceContainer();
+    
+    Context getContext();
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextInstanceContainer.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextInstanceContainer.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextInstanceContainer.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,27 @@
+package org.drools.process.instance;
+
+import java.util.List;
+
+import org.drools.process.core.Context;
+import org.drools.process.core.ContextContainer;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface ContextInstanceContainer {
+    
+    List<ContextInstance> getContextInstances(String contextId);
+    
+    void addContextInstance(String contextId, ContextInstance contextInstance);
+    
+    // TODO: does it make sense to have more than one contextInstance
+    // with the same contextId (e.g. multiple variable scope instances
+    // sharing the same context instance container?
+    ContextInstance getContextInstance(String contextId, long id);
+    
+    ContextInstance getContextInstance(Context context);
+    
+    ContextContainer getContextContainer();
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextableInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextableInstance.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ContextableInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,12 @@
+package org.drools.process.instance;
+
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface ContextableInstance {
+    
+    ContextInstance getContextInstance(String contextId);
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstance.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/ProcessInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -16,8 +16,11 @@
  * limitations under the License.
  */
 
+import org.drools.Agenda;
+import org.drools.WorkingMemory;
 import org.drools.common.InternalWorkingMemory;
 import org.drools.process.core.Process;
+import org.drools.process.instance.timer.TimerListener;
 
 /**
  * A process instance is the representation of a process during its execution.
@@ -26,7 +29,7 @@
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public interface ProcessInstance extends VariableScopeInstance, WorkItemListener {
+public interface ProcessInstance extends ContextInstanceContainer, ContextableInstance, WorkItemListener, TimerListener {
 
     int STATE_PENDING   = 0;
     int STATE_ACTIVE    = 1;
@@ -41,6 +44,8 @@
     void setProcess(Process process);
 
     Process getProcess();
+    
+    String getProcessId();
 
     void setState(int state);
 
@@ -48,6 +53,10 @@
     
     void setWorkingMemory(InternalWorkingMemory workingMemory);
     
+    WorkingMemory getWorkingMemory();
+
+    Agenda getAgenda();
+    
     void start();
 
 }

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/VariableScopeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/VariableScopeInstance.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/VariableScopeInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,17 +0,0 @@
-package org.drools.process.instance;
-
-import java.util.Map;
-
-/**
- * 
- * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
- */
-public interface VariableScopeInstance {
-
-    Map<String, Object> getVariables();
-    
-    Object getVariable(String name);
-    
-    void setVariable(String name, Object value);
-
-}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManager.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/WorkItemManager.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -47,7 +47,7 @@
         out.writeObject(workItemHandlers);
     }
 
-	public void executeWorkItem(WorkItem workItem) {
+	public void internalExecuteWorkItem(WorkItem workItem) {
 	    ((WorkItemImpl) workItem).setId(++workItemCounter);
 	    workItems.put(new Long(workItem.getId()), workItem);
 	    WorkItemHandler handler = (WorkItemHandler) this.workItemHandlers.get(workItem.getName());
@@ -58,6 +58,19 @@
 	    }
 	}
 
+    public void internalAbortWorkItem(long id) {
+        WorkItemImpl workItem = (WorkItemImpl) workItems.get(new Long(id));
+        // work item may have been aborted
+        if (workItem != null) {
+            WorkItemHandler handler = (WorkItemHandler) this.workItemHandlers.get(workItem.getName());
+            if (handler != null) {
+                handler.abortWorkItem(workItem, this);
+            } else {
+                System.err.println("Could not find work item handler for " + workItem.getName());
+            }
+        }
+    }
+    
 	public Set<WorkItem> getWorkItems() {
 	    return new HashSet<WorkItem>(workItems.values());
 
@@ -65,35 +78,31 @@
 
     public void completeWorkItem(long id, Map<String, Object> results) {
         WorkItemImpl workItem = (WorkItemImpl) workItems.get(new Long(id));
-        if (workItem == null) {
-            throw new IllegalArgumentException(
-                "Could not find work item with id " + id);
+        // work item may have been aborted
+        if (workItem != null) {
+            workItem.setResults(results);
+            ProcessInstance processInstance = workingMemory.getProcessInstance(workItem.getProcessInstanceId());
+            workItem.setState(WorkItem.COMPLETED);
+            // process instance may have finished already
+            if (processInstance != null) {
+                processInstance.workItemCompleted(workItem);
+            }
+            workItems.remove(new Long(id));
         }
-        workItem.setResults(results);
-        ProcessInstance processInstance = workingMemory.getProcessInstance(workItem.getProcessInstanceId());
-        if (processInstance == null) {
-            throw new IllegalArgumentException(
-                "Could not find processInstance with id " + workItem.getProcessInstanceId());
-        }
-        workItem.setState(WorkItem.COMPLETED);
-        processInstance.workItemCompleted(workItem);
-        workItems.remove(new Long(id));
     }
 
     public void abortWorkItem(long id) {
         WorkItemImpl workItem = (WorkItemImpl) workItems.get(new Long(id));
-        if (workItem == null) {
-            throw new IllegalArgumentException(
-                "Could not find work item with id " + id);
+        // work item may have been aborted
+        if (workItem != null) {
+            ProcessInstance processInstance = workingMemory.getProcessInstance(workItem.getProcessInstanceId());
+            workItem.setState(WorkItem.ABORTED);
+            // process instance may have finished already
+            if (processInstance != null) {
+                processInstance.workItemAborted(workItem);
+            }
+            workItems.remove(new Long(id));
         }
-        ProcessInstance processInstance = workingMemory.getProcessInstance(workItem.getProcessInstanceId());
-        if (processInstance == null) {
-            throw new IllegalArgumentException(
-                "Could not find processInstance with id " + workItem.getProcessInstanceId());
-        }
-        workItem.setState(WorkItem.ABORTED);
-        processInstance.workItemAborted(workItem);
-        workItems.remove(new Long(id));
     }
 
     public void registerWorkItemHandler(String workItemName, WorkItemHandler handler) {

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/AbstractContextInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/AbstractContextInstance.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/AbstractContextInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,34 @@
+package org.drools.process.instance.context;
+
+import java.io.Serializable;
+
+import org.drools.process.core.Context;
+import org.drools.process.instance.ContextInstance;
+import org.drools.process.instance.ContextInstanceContainer;
+
+public abstract class AbstractContextInstance implements ContextInstance, Serializable {
+
+    private long contextId;
+    private ContextInstanceContainer contextInstanceContainer;
+    
+    public long getContextId() {
+        return contextId;
+    }
+
+    public void setContextId(long contextId) {
+        this.contextId = contextId;
+    }
+
+    public ContextInstanceContainer getContextInstanceContainer() {
+        return contextInstanceContainer;
+    }
+
+    public void setContextInstanceContainer(ContextInstanceContainer contextInstanceContainer) {
+        this.contextInstanceContainer = contextInstanceContainer;
+    }
+    
+    public Context getContext() {
+        return getContextInstanceContainer().getContextContainer().getContext(getContextType(), getContextId());
+    }
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/exception/ExceptionHandlerInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/exception/ExceptionHandlerInstance.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/exception/ExceptionHandlerInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,7 @@
+package org.drools.process.instance.context.exception;
+
+public interface ExceptionHandlerInstance {
+
+    void handleException(String exception, Object param);
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/exception/ExceptionScopeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/exception/ExceptionScopeInstance.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/exception/ExceptionScopeInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,35 @@
+package org.drools.process.instance.context.exception;
+
+import org.drools.process.core.context.exception.ExceptionHandler;
+import org.drools.process.core.context.exception.ExceptionScope;
+import org.drools.process.instance.context.AbstractContextInstance;
+
+public abstract class ExceptionScopeInstance extends AbstractContextInstance {
+
+    private static final long serialVersionUID = 400L;
+
+    public String getContextType() {
+        return ExceptionScope.EXCEPTION_SCOPE;
+    }
+    
+    public ExceptionScope getExceptionScope() {
+        return (ExceptionScope) getContext();
+    }
+    
+    protected abstract ExceptionHandlerInstance getExceptionHandlerInstance(ExceptionHandler exceptionHandler);
+
+    public void handleException(String exception, Object params) {
+        ExceptionHandler handler = getExceptionScope().getExceptionHandler(exception);
+        if (handler == null) {
+            throw new IllegalArgumentException(
+                "Could not find ExceptionHandler for " + exception);
+        }
+        ExceptionHandlerInstance handlerInstance = getExceptionHandlerInstance(handler);
+        if (handlerInstance == null) {
+            throw new IllegalArgumentException(
+                "Could not find ExceptionHandler instance for " + exception);
+        }
+        handlerInstance.handleException(exception, params);
+    }
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/variable/VariableScopeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/variable/VariableScopeInstance.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/context/variable/VariableScopeInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,40 @@
+package org.drools.process.instance.context.variable;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.instance.context.AbstractContextInstance;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class VariableScopeInstance extends AbstractContextInstance {
+
+    private static final long serialVersionUID = 400L;
+    
+    private Map<String, Object> variables = new HashMap<String, Object>();
+
+    public String getContextType() {
+        return VariableScope.VARIABLE_SCOPE;
+    }
+
+    public Object getVariable(String name) {
+        return variables.get(name);
+    }
+
+    public Map<String, Object> getVariables() {
+        return Collections.unmodifiableMap(variables);
+    }
+
+    public void setVariable(String name, Object value) {
+        if (name == null) {
+            throw new IllegalArgumentException(
+                "The name of a variable may not be null!");
+        }
+        variables.put(name, value);
+    }
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ContextInstanceFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ContextInstanceFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ContextInstanceFactory.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,11 @@
+package org.drools.process.instance.impl;
+
+import org.drools.process.core.Context;
+import org.drools.process.instance.ContextInstance;
+import org.drools.process.instance.ContextInstanceContainer;
+
+public interface ContextInstanceFactory {
+    
+	ContextInstance getContextInstance(Context context, ContextInstanceContainer contextInstanceContainer);
+	
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ContextInstanceFactoryRegistry.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ContextInstanceFactoryRegistry.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ContextInstanceFactoryRegistry.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,34 @@
+package org.drools.process.instance.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.drools.process.core.Context;
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.instance.context.variable.VariableScopeInstance;
+import org.drools.process.instance.impl.factory.ReuseContextInstanceFactory;
+
+public class ContextInstanceFactoryRegistry {
+    
+    public static final ContextInstanceFactoryRegistry INSTANCE = 
+        new ContextInstanceFactoryRegistry();
+
+    private Map<Class<? extends Context>, ContextInstanceFactory> registry;
+
+    public ContextInstanceFactoryRegistry() {
+        this.registry = new HashMap<Class<? extends Context>, ContextInstanceFactory>();
+
+        // hard wired contexts:
+        register(VariableScope.class, new ReuseContextInstanceFactory(
+                 VariableScopeInstance.class));
+    }
+
+    public void register(Class<? extends Context> cls,
+            ContextInstanceFactory factory) {
+        this.registry.put(cls, factory);
+    }
+
+    public ContextInstanceFactory getContextInstanceFactory(Context context) {
+        return this.registry.get(context.getClass());
+    }
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ProcessInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ProcessInstanceImpl.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/ProcessInstanceImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -17,11 +17,20 @@
  */
 
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
+import org.drools.WorkingMemory;
+import org.drools.common.InternalRuleBase;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.process.core.Context;
+import org.drools.process.core.ContextContainer;
 import org.drools.process.core.Process;
+import org.drools.process.core.timer.Timer;
+import org.drools.process.instance.ContextInstance;
 import org.drools.process.instance.ProcessInstance;
-import org.drools.process.instance.VariableScopeInstance;
 import org.drools.process.instance.WorkItem;
 
 /**
@@ -32,9 +41,12 @@
 public abstract class ProcessInstanceImpl implements ProcessInstance, Serializable {
 
     private long id;
-    private Process process;
+    private String processId;
+    private transient Process process;
     private int state = STATE_PENDING;
-    private VariableScopeInstance variableScopeInstance = new VariableScopeInstanceImpl();
+    private Map<String, ContextInstance> contextInstances = new HashMap<String, ContextInstance>();
+    private Map<String, List<ContextInstance>> subContextInstances = new HashMap<String, List<ContextInstance>>();
+    private InternalWorkingMemory workingMemory;
 
     public void setId(final long id) {
         this.id = id;
@@ -45,12 +57,21 @@
     }
 
     public void setProcess(final Process process) {
+        this.processId = process.getId();
         this.process = process;
     }
 
     public Process getProcess() {
+        if (this.process == null) {
+            this.process = ((InternalRuleBase) workingMemory.getRuleBase())
+                .getProcess(processId);
+        }
         return this.process;
     }
+    
+    public String getProcessId() {
+        return processId;
+    }
 
     public void setState(final int state) {
         this.state = state;
@@ -60,24 +81,88 @@
         return this.state;
     }
     
-    public void workItemCompleted(WorkItem taskInstance) {
+    public void setWorkingMemory(final InternalWorkingMemory workingMemory) {
+        if ( this.workingMemory != null ) {
+            throw new IllegalArgumentException( "A working memory can only be set once." );
+        }
+        this.workingMemory = workingMemory;
     }
 
-    public void workItemAborted(WorkItem taskInstance) {
+    public WorkingMemory getWorkingMemory() {
+        return this.workingMemory;
     }
+    
+    public ContextContainer getContextContainer() {
+        return getProcess();
+    }
+    
+    public void setContextInstance(String contextId, ContextInstance contextInstance) {
+        this.contextInstances.put(contextId, contextInstance);
+    }
+    
+    public ContextInstance getContextInstance(String contextId) {
+        ContextInstance contextInstance = this.contextInstances.get(contextId);
+        if (contextInstance != null) {
+            return contextInstance;
+        }
+        Context context = getProcess().getDefaultContext(contextId);
+        if (context != null) {
+            contextInstance = getContextInstance(context);
+            addContextInstance(contextId, contextInstance);
+            return contextInstance;
+        }
+        return null;
+    }
+    
+    public List<ContextInstance> getContextInstances(String contextId) {
+        return this.subContextInstances.get(contextId);
+    }
+    
+    public void addContextInstance(String contextId, ContextInstance contextInstance) {
+        List<ContextInstance> list = this.subContextInstances.get(contextId);
+        if (list == null) {
+            list = new ArrayList<ContextInstance>();
+            this.subContextInstances.put(contextId, list);
+        }
+        list.add(contextInstance);
+    }
 
-    public Object getVariable(String name) {
-        return variableScopeInstance.getVariable(name);
+    public ContextInstance getContextInstance(String contextId, long id) {
+        List<ContextInstance> contextInstances = subContextInstances.get(contextId);
+        if (contextInstances != null) {
+            for (ContextInstance contextInstance: contextInstances) {
+                if (contextInstance.getContextId() == id) {
+                    return contextInstance;
+                }
+            }
+        }
+        return null;
     }
 
-    public Map<String, Object> getVariables() {
-        return variableScopeInstance.getVariables();
+    public ContextInstance getContextInstance(final Context context) {
+        ContextInstanceFactoryRegistry contextRegistry =
+            ((InternalRuleBase) getWorkingMemory().getRuleBase())
+                .getConfiguration().getProcessContextInstanceFactoryRegistry();
+        ContextInstanceFactory conf = contextRegistry.getContextInstanceFactory(context);
+        if (conf == null) {
+            throw new IllegalArgumentException("Illegal context type (registry not found): " + context.getClass());
+        }
+        ContextInstance contextInstance = (ContextInstance) conf.getContextInstance(context, this);
+        if (contextInstance == null) {
+            throw new IllegalArgumentException("Illegal context type (instance not found): " + context.getClass());
+        }
+        return contextInstance;
     }
 
-    public void setVariable(String name, Object value) {
-        variableScopeInstance.setVariable(name, value);
+    public void workItemCompleted(WorkItem taskInstance) {
     }
-    
+
+    public void workItemAborted(WorkItem taskInstance) {
+    }
+
+    public void timerTriggered(Timer timer) {
+    }
+
     public void start() {
         if ( getState() != ProcessInstanceImpl.STATE_PENDING ) {
             throw new IllegalArgumentException( "A process instance can only be started once" );
@@ -87,6 +172,16 @@
     }
     
     protected abstract void internalStart();
+    
+    public void disconnect() {
+        workingMemory.removeProcessInstance(this);
+        process = null;
+        workingMemory = null;
+    }
+    
+    public void reconnect() {
+        workingMemory.addProcessInstance(this);
+    }
 
     public String toString() {
         final StringBuffer b = new StringBuffer( "ProcessInstance " );

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/VariableScopeInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/VariableScopeInstanceImpl.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/VariableScopeInstanceImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,36 +0,0 @@
-package org.drools.process.instance.impl;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.drools.process.instance.VariableScopeInstance;
-
-/**
- * 
- * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
- */
-public class VariableScopeInstanceImpl implements VariableScopeInstance, Serializable {
-
-    private static final long serialVersionUID = 400L;
-    
-    private Map<String, Object> variables = new HashMap<String, Object>();
-
-    public Object getVariable(String name) {
-        return variables.get(name);
-    }
-
-    public Map<String, Object> getVariables() {
-        return Collections.unmodifiableMap(variables);
-    }
-
-    public void setVariable(String name, Object value) {
-        if (name == null) {
-            throw new IllegalArgumentException(
-                "The name of a variable may not be null!");
-        }
-        variables.put(name, value);
-    }
-    
-}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/factory/ReuseContextInstanceFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/factory/ReuseContextInstanceFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/factory/ReuseContextInstanceFactory.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,33 @@
+package org.drools.process.instance.impl.factory;
+
+import org.drools.process.core.Context;
+import org.drools.process.instance.ContextInstance;
+import org.drools.process.instance.ContextInstanceContainer;
+import org.drools.process.instance.context.AbstractContextInstance;
+import org.drools.process.instance.impl.ContextInstanceFactory;
+
+public class ReuseContextInstanceFactory implements ContextInstanceFactory {
+    
+    public final Class<? extends ContextInstance> cls;
+    
+    public ReuseContextInstanceFactory(Class<? extends ContextInstance> cls){
+        this.cls = cls;
+    }
+
+	public ContextInstance getContextInstance(Context context, ContextInstanceContainer contextInstanceContainer) {    	
+        ContextInstance result = contextInstanceContainer.getContextInstance( context.getType(), context.getId() );
+        if (result != null) {
+            return result;
+        }
+        try {
+            AbstractContextInstance contextInstance = (AbstractContextInstance) cls.newInstance();
+            contextInstance.setContextId(context.getId());
+            contextInstance.setContextInstanceContainer(contextInstanceContainer);
+            return contextInstance;
+        } catch (Exception e) {
+            throw new RuntimeException("Unable to instantiate context '"
+                + this.cls.getName() + "': " + e.getMessage());
+        }
+	}
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/humantask/HumanTaskDialog.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/humantask/HumanTaskDialog.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/humantask/HumanTaskDialog.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,322 @@
+package org.drools.process.instance.impl.humantask;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.drools.process.instance.WorkItem;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class HumanTaskDialog extends JDialog {
+    
+    private static final long serialVersionUID = 400L;
+    
+    private HumanTaskHandler handler;
+    private WorkItem workItem;
+    private JTextField resultNameField;
+    private JTextField resultValueField;
+    private List<Result> results = new ArrayList<Result>();
+    private JList resultList;
+    private JButton removeResultButton;
+    private JButton completeButton;
+    private JButton abortButton;
+    
+    public HumanTaskDialog(HumanTaskHandler handler, WorkItem workItem) {
+        super(handler, "Execute Human Task", true);
+        this.handler = handler;
+        this.workItem = workItem;
+        setSize(new Dimension(400, 400));
+        initializeComponent();
+    }
+    
+    private void initializeComponent() {
+        JPanel panel = new JPanel();
+        panel.setLayout(new GridBagLayout());
+        getRootPane().setLayout(new BorderLayout());
+        getRootPane().add(panel, BorderLayout.CENTER);
+        
+        // Parameters
+        JLabel nameLabel = new JLabel("Name");
+        GridBagConstraints c = new GridBagConstraints();
+        c.anchor = GridBagConstraints.WEST;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(nameLabel, c);
+        String taskName = (String) workItem.getParameter("TaskName");
+        JTextField nameField = new JTextField(
+            taskName == null ? "" : taskName);
+        nameField.setEditable(false);
+        c = new GridBagConstraints();
+        c.weightx = 1;
+        c.fill = GridBagConstraints.HORIZONTAL;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(nameField, c);
+        
+        JLabel priorityLabel = new JLabel("Priority");
+        c = new GridBagConstraints();
+        c.gridy = 1;
+        c.anchor = GridBagConstraints.WEST;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(priorityLabel, c);
+        String priority = (String) workItem.getParameter("Priority");
+        JTextField priorityField = new JTextField(
+            priority == null ? "" : priority);
+        priorityField.setEditable(false);
+        c = new GridBagConstraints();
+        c.gridy = 1;
+        c.weightx = 1;
+        c.fill = GridBagConstraints.HORIZONTAL;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(priorityField, c);
+        
+        JLabel commentLabel = new JLabel("Comment");
+        c = new GridBagConstraints();
+        c.gridy = 2;
+        c.anchor = GridBagConstraints.WEST;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(commentLabel, c);
+        String comment = (String) workItem.getParameter("Comment");
+        JTextArea params = new JTextArea(
+            comment == null ? "" : comment);
+        params.setEditable(false);
+        c = new GridBagConstraints();
+        c.gridy = 2;
+        c.weightx = 1;
+        c.weighty = 1;
+        c.fill = GridBagConstraints.BOTH;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(params, c);
+        
+        int additionalParameters = 0;
+        for (Map.Entry<String, Object> entry: workItem.getParameters().entrySet()) {
+            String name = entry.getKey();
+            if (!"TaskName".equals(name)
+                    && !"Priority".equals(name)
+                    && !"Comment".equals(name)
+                    && !"ActorId".equals(name)) {
+                additionalParameters++;
+                JLabel label = new JLabel(name);
+                c = new GridBagConstraints();
+                c.gridy = 2 + additionalParameters;
+                c.anchor = GridBagConstraints.WEST;
+                c.insets = new Insets(5, 5, 5, 5);
+                panel.add(label, c);
+                JTextField field = new JTextField(
+                    workItem.getParameter(name).toString());
+                field.setEditable(false);
+                c = new GridBagConstraints();
+                c.gridy = 2 + additionalParameters;
+                c.weightx = 1;
+                c.fill = GridBagConstraints.HORIZONTAL;
+                c.insets = new Insets(5, 5, 5, 5);
+                panel.add(field, c);
+            }
+        }
+        
+        // Result Panel
+        JPanel resultPanel = new JPanel();
+        resultPanel.setLayout(new GridBagLayout());
+        resultPanel.setBorder(new TitledBorder("Results"));
+        
+        JLabel resultNameLabel = new JLabel("Name");
+        c = new GridBagConstraints();
+        c.insets = new Insets(5, 5, 5, 5);
+        resultPanel.add(resultNameLabel, c);
+        resultNameField = new JTextField();
+        c = new GridBagConstraints();
+        c.weightx = 1;
+        c.fill = GridBagConstraints.HORIZONTAL;
+        c.insets = new Insets(5, 5, 5, 5);
+        resultPanel.add(resultNameField, c);
+        JLabel resultValueLabel = new JLabel("Value");
+        c = new GridBagConstraints();
+        c.insets = new Insets(5, 5, 5, 5);
+        resultPanel.add(resultValueLabel, c);
+        resultValueField = new JTextField();
+        c = new GridBagConstraints();
+        c.weightx = 1;
+        c.fill = GridBagConstraints.HORIZONTAL;
+        c.insets = new Insets(5, 5, 5, 5);
+        resultPanel.add(resultValueField, c);
+        JButton addResultButton = new JButton("Add");
+        addResultButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                addResult();
+            }
+        });
+        c = new GridBagConstraints();
+        c.fill = GridBagConstraints.HORIZONTAL;
+        c.insets = new Insets(5, 5, 5, 5);
+        resultPanel.add(addResultButton, c);
+        
+        resultList = new JList();
+        resultList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        resultList.addListSelectionListener(new ListSelectionListener() {
+            public void valueChanged(ListSelectionEvent e) {
+                removeResultButton.setEnabled(resultList.getSelectedIndex() != -1);
+            }
+        });
+        c = new GridBagConstraints();
+        c.gridy = 1;
+        c.gridwidth = 4;
+        c.weightx = 1;
+        c.weighty = 1;
+        c.fill = GridBagConstraints.BOTH;
+        c.insets = new Insets(5, 5, 5, 5);
+        JScrollPane scrollPane = new JScrollPane();
+        scrollPane.setViewportView(resultList);
+        resultPanel.add(scrollPane, c);
+        removeResultButton = new JButton("Remove");
+        removeResultButton.setEnabled(false);
+        removeResultButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                removeResult();
+            }
+        });
+        c = new GridBagConstraints();
+        c.gridy = 1;
+        c.anchor = GridBagConstraints.NORTH;
+        c.insets = new Insets(5, 5, 5, 5);
+        resultPanel.add(removeResultButton, c);
+        
+        c = new GridBagConstraints();
+        c.gridy = 3 + additionalParameters;
+        c.gridwidth = 2;
+        c.weighty = 1;
+        c.fill = GridBagConstraints.BOTH;
+        panel.add(resultPanel, c);
+        
+        
+        // Buttom Panel
+        JPanel bottomPanel = new JPanel();
+        bottomPanel.setLayout(new GridBagLayout());
+        completeButton = new JButton("Complete");
+        completeButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                complete();
+            }
+        });
+        c = new GridBagConstraints();
+        c.weightx = 1;
+        c.anchor = GridBagConstraints.EAST;
+        c.insets = new Insets(5, 5, 5, 5);
+        bottomPanel.add(completeButton, c);
+
+        abortButton = new JButton("Abort");
+        abortButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                abort();
+            }
+        });
+        c = new GridBagConstraints();
+        c.insets = new Insets(5, 5, 5, 5);
+        bottomPanel.add(abortButton, c);
+        
+        c = new GridBagConstraints();
+        c.gridy = 4 + additionalParameters;
+        c.gridwidth = 2;
+        c.fill = GridBagConstraints.BOTH;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(bottomPanel, c);
+    }
+    
+    private void addResult() {
+        String name = resultNameField.getText();
+        String value = resultValueField.getText();
+        if ("".equals(name) || "".equals(value)) {
+            JOptionPane.showMessageDialog(this,
+                "Name or value of result may not be null!", "Error", JOptionPane.ERROR_MESSAGE);
+            return;
+        }
+        Result result = new Result(name, value);
+        if (results.contains(result)) {
+            JOptionPane.showMessageDialog(this,
+                "Cannot add result more than once!", "Error", JOptionPane.ERROR_MESSAGE);
+            return;
+        }
+        results.add(result);
+        reloadResultList();
+        resultNameField.setText("");
+        resultValueField.setText("");
+    }
+    
+    private void reloadResultList() {
+        resultList.setListData(results.toArray());
+    }
+    
+    private void removeResult() {
+        int index = resultList.getSelectedIndex();
+        if (index != -1) {
+            results.remove(index);
+            reloadResultList();
+        }
+    }
+    
+    private void complete() {
+        Map<String, Object> resultMap = null;
+        if (results.size() > 0) {
+            resultMap = new HashMap<String, Object>();
+            for (Result result: results) {
+                resultMap.put(result.getName(), result.getValue());
+            }
+        }
+        handler.complete(workItem, resultMap);
+        dispose();
+    }
+    
+    private void abort() {
+        handler.abort(workItem);
+        dispose();
+    }
+    
+    public static class Result {
+        private String name;
+        private Object value;
+        public Result(String name, Object value) {
+            this.name = name;
+            this.value = value;
+        }
+        public String getName() {
+            return this.name;
+        }
+        public Object getValue() {
+            return this.value;
+        }
+        public String toString() {
+            return this.name + " = " + this.value;
+        }
+        public boolean equals(Object o) {
+            if (o instanceof Result) {
+                return ((Result) o).getName().equals(this.name);
+            }
+            return false;
+        }
+        public int hashCode() {
+            return this.name.hashCode();
+        }
+    }
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/humantask/HumanTaskHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/humantask/HumanTaskHandler.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/impl/humantask/HumanTaskHandler.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,203 @@
+package org.drools.process.instance.impl.humantask;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.WindowConstants;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.drools.process.instance.WorkItem;
+import org.drools.process.instance.WorkItemHandler;
+import org.drools.process.instance.WorkItemManager;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class HumanTaskHandler extends JFrame implements WorkItemHandler {
+
+    private static final long serialVersionUID = 400L;
+    
+    private Map<WorkItem, WorkItemManager> workItems = new HashMap<WorkItem, WorkItemManager>();
+    private JTextField actorTextField; 
+    private JList workItemsList;
+    private JButton selectButton;
+    
+    public HumanTaskHandler() {
+        setSize(new Dimension(400, 300));
+        setTitle("Work Items");
+        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+        initializeComponent();
+    }
+    
+    private void initializeComponent() {
+        JPanel panel = new JPanel();
+        panel.setLayout(new GridBagLayout());
+        getRootPane().setLayout(new BorderLayout());
+        getRootPane().add(panel, BorderLayout.CENTER);
+        
+        JLabel label = new JLabel("Actor");
+        GridBagConstraints c = new GridBagConstraints();
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(label, c);
+        actorTextField = new JTextField();
+        c = new GridBagConstraints();
+        c.weightx = 1;
+        c.fill = GridBagConstraints.HORIZONTAL;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(actorTextField, c);
+        JButton updateButton = new JButton("Update");
+        updateButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                update();
+            }
+        });
+        c = new GridBagConstraints();
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(updateButton, c);
+        
+        workItemsList = new JList();
+        workItemsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        workItemsList.addMouseListener(new MouseAdapter() {
+            public void mouseClicked(MouseEvent e) {
+                if (e.getClickCount() == 2) {
+                    select();
+                }
+            }
+        });
+        workItemsList.addListSelectionListener(new ListSelectionListener() {
+            public void valueChanged(ListSelectionEvent e) {
+                selectButton.setEnabled(getSelectedWorkItem() != null);
+            }
+        });
+        c = new GridBagConstraints();
+        c.gridy = 1;
+        c.weightx = 1;
+        c.weighty = 1;
+        c.gridwidth = 3;
+        c.fill = GridBagConstraints.BOTH;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(workItemsList, c);
+        
+        selectButton = new JButton("Select");
+        selectButton.setEnabled(false);
+        selectButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                select();
+            }
+        });
+        c = new GridBagConstraints();
+        c.gridy = 2;
+        c.weightx = 1;
+        c.gridwidth = 3;
+        c.anchor = GridBagConstraints.EAST;
+        c.insets = new Insets(5, 5, 5, 5);
+        panel.add(selectButton, c);
+    }
+    
+    private void update() {
+        String actor = actorTextField.getText();
+        if ("".equals(actor)) {
+            actor = null;
+        }
+        reloadWorkItemsList(actor);
+    }
+    
+    private void select() {
+        WorkItem workItem = getSelectedWorkItem();
+        if (workItem != null) {
+            HumanTaskDialog dialog = new HumanTaskDialog(HumanTaskHandler.this, workItem);
+            dialog.setVisible(true);
+        }
+    }
+    
+    public WorkItem getSelectedWorkItem() {
+        int index = workItemsList.getSelectedIndex();
+        if (index != -1) {
+            Object selected = workItemsList.getModel().getElementAt(index);
+            if (selected instanceof WorkItemWrapper) {
+                return ((WorkItemWrapper) selected).getWorkItem();
+            }
+        }
+        return null;
+    }
+    
+    private void reloadWorkItemsList(String actor) {
+        List<WorkItemWrapper> result = new ArrayList<WorkItemWrapper>();
+        for (Iterator<WorkItem> iterator = workItems.keySet().iterator(); iterator.hasNext(); ) {
+            WorkItem workItem = iterator.next();
+            if (actor == null
+                    || workItem.getParameter("ActorId") == null 
+                    || actor.equals(workItem.getParameter("ActorId"))) {
+                result.add(new WorkItemWrapper(workItem));
+            }
+        }
+        workItemsList.setListData(result.toArray());
+    }
+    
+    public void complete(WorkItem workItem, Map<String, Object> results) {
+        WorkItemManager manager = workItems.get(workItem);
+        if (manager != null) {
+            manager.completeWorkItem(workItem.getId(), results);
+        }
+        workItems.remove(workItem);
+        update();
+        selectButton.setEnabled(getSelectedWorkItem() != null);
+    }
+    
+    public void abort(WorkItem workItem) {
+        WorkItemManager manager = workItems.get(workItem);
+        if (manager != null) {
+            manager.abortWorkItem(workItem.getId());
+        }
+        workItems.remove(workItem);
+        update();
+        selectButton.setEnabled(getSelectedWorkItem() != null);
+    }
+    
+    public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
+        workItems.remove(workItem);
+    }
+
+    public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
+        workItems.put(workItem, manager);
+    }
+
+    private class WorkItemWrapper {
+        
+        private WorkItem workItem;
+        
+        public WorkItemWrapper(WorkItem workItem) {
+            this.workItem = workItem;
+        }
+        
+        public WorkItem getWorkItem() {
+            return workItem;
+        }
+        
+        public String toString() {
+            return "[" + workItem.getId() + "] " + workItem.getParameter("TaskName");
+        }
+    }
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerListener.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerListener.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,9 @@
+package org.drools.process.instance.timer;
+
+import org.drools.process.core.timer.Timer;
+
+public interface TimerListener {
+    
+    void timerTriggered(Timer timer);
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,67 @@
+package org.drools.process.instance.timer;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimerTask;
+
+import org.drools.WorkingMemory;
+import org.drools.process.core.timer.Timer;
+import org.drools.process.instance.ProcessInstance;
+
+public class TimerManager {
+    
+    private Map<Timer, Long> timers = new HashMap<Timer, Long>();
+    private Map<Timer, java.util.Timer> utilTimers = new HashMap<Timer, java.util.Timer>();
+    private long timerId = 0;
+    
+    private WorkingMemory workingMemory;
+    
+    public TimerManager(WorkingMemory workingMemory) {
+        this.workingMemory = workingMemory;
+    }
+    
+    public void registerTimer(final Timer timer, ProcessInstance processInstance) {
+        timer.setId(++timerId);
+        timers.put(timer, processInstance.getId());
+        TimerTask timerTask = new TimerTask() {
+            public void run() {
+                timerTriggered(timer);
+            }
+        };
+        java.util.Timer utilTimer = new java.util.Timer();
+        utilTimers.put(timer, utilTimer);
+        utilTimer.schedule(
+            timerTask, 
+            timer.getDelay(), 
+            timer.getPeriod());
+    }
+    
+    public void cancelTimer(Timer timer) {
+        java.util.Timer utilTimer = utilTimers.get(timer);
+        if (utilTimer == null) {
+            throw new IllegalArgumentException(
+                "Could not find timer implementation for timer " + timer);
+        }
+        utilTimer.cancel();
+        utilTimers.remove(timer);
+        timers.remove(timer);
+    }
+    
+    public void timerTriggered(Timer timer) {
+        Long processInstanceId = timers.get(timer);
+        if (processInstanceId == null) {
+            throw new IllegalArgumentException(
+                "Could not find process instance for timer " + timer);
+        }
+        ProcessInstance processInstance = workingMemory.getProcessInstance(processInstanceId);
+        // process instance may have finished already
+        if (processInstance != null) {
+            processInstance.timerTriggered(timer);
+        }
+        if (timer.getPeriod() == 0) {
+            utilTimers.remove(timer);
+            timers.remove(timer);
+        }
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcess.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcess.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcess.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,5 +1,6 @@
 package org.drools.ruleflow.core;
 
+import org.drools.process.core.context.variable.VariableScope;
 import org.drools.workflow.core.Node;
 import org.drools.workflow.core.NodeContainer;
 import org.drools.workflow.core.impl.NodeContainerImpl;
@@ -14,7 +15,14 @@
     
     public RuleFlowProcess() {
         setType(RULEFLOW_TYPE);
+        VariableScope variableScope = new VariableScope();
+        addContext(variableScope);
+        setDefaultContext(variableScope);
     }
+    
+    public VariableScope getVariableScope() {
+        return (VariableScope) getDefaultContext(VariableScope.VARIABLE_SCOPE);
+    }
 
     protected NodeContainer createNodeContainer() {
         return new WorkflowProcessNodeContainer();

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -23,8 +23,8 @@
 import java.util.Map;
 
 import org.drools.process.core.Process;
-import org.drools.process.core.Variable;
 import org.drools.process.core.Work;
+import org.drools.process.core.context.variable.Variable;
 import org.drools.process.core.validation.ProcessValidationError;
 import org.drools.process.core.validation.ProcessValidator;
 import org.drools.process.core.validation.impl.ProcessValidationErrorImpl;
@@ -263,7 +263,7 @@
             errors.add(new ProcessValidationErrorImpl(process,
                 "Process has no end node."));
         }
-        for (final Iterator<Variable> it = process.getVariables().iterator(); it.hasNext(); ) {
+        for (final Iterator<Variable> it = process.getVariableScope().getVariables().iterator(); it.hasNext(); ) {
             final Variable variable = it.next();
             if (variable.getType() == null) {
                 errors.add(new ProcessValidationErrorImpl(process,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/RuleFlowGroup.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/RuleFlowGroup.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/RuleFlowGroup.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -19,11 +19,13 @@
 import java.io.Externalizable;
 import java.util.Iterator;
 
+import org.drools.common.RuleFlowGroupNode;
+
 public interface RuleFlowGroup extends Externalizable {
 
     String getName();
 
-    public Iterator iterator();
+    public Iterator<RuleFlowGroupNode> iterator();
 
     boolean isEmpty();
 
@@ -40,4 +42,4 @@
      * activations when it was activated, it will be deactivated immediately.
      */
     void setAutoDeactivate(boolean autoDeactivate);
-}
\ No newline at end of file
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/Connection.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/Connection.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/Connection.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -49,4 +49,8 @@
      */
     String getToType();
 
+    void setMetaData(String name, Object value);
+    
+    Object getMetaData(String name);
+    
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/Node.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/Node.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/Node.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -20,12 +20,14 @@
 import java.util.List;
 import java.util.Map;
 
+import org.drools.process.core.Contextable;
+
 /**
  * Represents a node in a RuleFlow. 
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public interface Node extends Serializable {
+public interface Node extends Contextable, Serializable {
 
     static final String CONNECTION_DEFAULT_TYPE = "DROOLS_DEFAULT";
     
@@ -86,4 +88,9 @@
     NodeContainer getNodeContainer();
     
     void setNodeContainer(NodeContainer nodeContainer);
+    
+    void setMetaData(String name, Object value);
+    
+    Object getMetaData(String name);
+    
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeContainer.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeContainer.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeContainer.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,5 +1,8 @@
 package org.drools.workflow.core;
 
+import org.drools.process.core.Context;
+
+
 /**
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
@@ -41,4 +44,6 @@
      */
     void removeNode(Node node);
     
+    Context resolveContext(String contextId, Object param);
+    
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeExtension.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeExtension.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeExtension.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,9 @@
+package org.drools.workflow.core;
+
+public interface NodeExtension {
+    
+    String getDefaultName();
+    
+    String getIcon();
+    
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/ConnectionImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/ConnectionImpl.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/ConnectionImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -17,6 +17,8 @@
  */
 
 import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.drools.workflow.core.Connection;
 import org.drools.workflow.core.Node;
@@ -34,6 +36,7 @@
     private Node to;
     private String fromType;
     private String toType;
+    private Map<String, Object> metaData = new HashMap<String, Object>();
     
     ConnectionImpl() {
     }
@@ -97,6 +100,14 @@
         return this.toType;
     }
 
+    public void setMetaData(String name, Object value) {
+        this.metaData.put(name, value);
+    }
+    
+    public Object getMetaData(String name) {
+        return this.metaData.get(name);
+    }
+    
     public String toString() {
         final StringBuffer sb = new StringBuffer("Connection ");
         sb.append(getFrom());

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeContainerImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeContainerImpl.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeContainerImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -4,6 +4,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.drools.process.core.Context;
 import org.drools.workflow.core.Node;
 import org.drools.workflow.core.NodeContainer;
 
@@ -17,8 +18,6 @@
 
     private Map<Long, Node> nodes;
 
-    private long lastNodeId;
-
     public NodeContainerImpl() {
         this.nodes = new HashMap<Long, Node>();
     }
@@ -26,7 +25,6 @@
     public void addNode(final Node node) {
         validateAddNode(node);
         if (!this.nodes.containsValue(node)) {
-            node.setId(++this.lastNodeId);
             this.nodes.put(new Long(node.getId()), node);
         }
     }
@@ -64,4 +62,8 @@
         }
     }
 
+    public Context resolveContext(String contextId, Object param) {
+        return null;
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeImpl.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -23,6 +23,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.drools.process.core.Context;
 import org.drools.workflow.core.Connection;
 import org.drools.workflow.core.Node;
 import org.drools.workflow.core.NodeContainer;
@@ -42,6 +43,8 @@
     private Map<String, List<Connection>> incomingConnections;
     private Map<String, List<Connection>> outgoingConnections;
     private NodeContainer nodeContainer;
+    private Map<String, Context> contexts = new HashMap<String, Context>();
+    private Map<String, Object> metaData = new HashMap<String, Object>();
 
     public NodeImpl() {
         this.id = -1;
@@ -172,5 +175,32 @@
     public void setNodeContainer(NodeContainer nodeContainer) {
         this.nodeContainer = nodeContainer;
     }
-
+    
+    public void setContext(String contextId, Context context) {
+        this.contexts.put(contextId, context);
+    }
+    
+    public Context getContext(String contextId) {
+        return this.contexts.get(contextId);
+    }
+    
+    public Context resolveContext(String contextId, Object param) {
+        Context context = getContext(contextId);
+        if (context != null) {
+            context = context.resolveContext(param);
+            if (context != null) {
+                return context;
+            }
+        }
+        return nodeContainer.resolveContext(contextId, param);
+    }
+    
+    public void setMetaData(String name, Object value) {
+        this.metaData.put(name, value);
+    }
+    
+    public Object getMetaData(String name) {
+        return this.metaData.get(name);
+    }
+    
 }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeContextNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeContextNode.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeContextNode.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,48 @@
+package org.drools.workflow.core.node;
+
+import java.util.List;
+
+import org.drools.process.core.Context;
+import org.drools.process.core.ContextContainer;
+import org.drools.process.core.impl.ContextContainerImpl;
+
+/**
+ * 
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class CompositeContextNode extends CompositeNode implements ContextContainer {
+
+    private static final long serialVersionUID = 400L;
+    
+    private ContextContainer contextContainer = new ContextContainerImpl();
+
+    public List<Context> getContexts(String contextType) {
+        return this.contextContainer.getContexts(contextType);
+    }
+    
+    public void addContext(Context context) {
+        this.contextContainer.addContext(context);
+    }
+    
+    public Context getContext(String contextType, long id) {
+        return this.contextContainer.getContext(contextType, id);
+    }
+
+    public void setDefaultContext(Context context) {
+        this.contextContainer.setDefaultContext(context);
+    }
+    
+    public Context getDefaultContext(String contextType) {
+        return this.contextContainer.getDefaultContext(contextType);
+    }
+
+    public Context resolveContext(String contextId, Object param) {
+        Context context = getDefaultContext(contextId);
+        context = context.resolveContext(param);
+        if (context != null) {
+            return context;
+        }
+        return super.resolveContext(contextId, param);
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EndNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EndNode.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EndNode.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -26,6 +26,8 @@
 public class EndNode extends SequenceNode {
 
     private static final long serialVersionUID = 400L;
+    
+    // TODO: boolean terminate (should all other node instances be cancelled?)
 
     public void validateAddOutgoingConnection(final String type, final Connection connection) {
         throw new UnsupportedOperationException(

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/EventNode.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,7 @@
+package org.drools.workflow.core.node;
+
+public class EventNode extends SequenceNode {
+
+    private static final long serialVersionUID = 400L;
+
+}

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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/MilestoneNode.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -22,7 +22,7 @@
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class MilestoneNode extends SequenceNode {
+public class MilestoneNode extends EventNode {
 
 	private static final long serialVersionUID = 8552568488755348247L;
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/RuleSetNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/RuleSetNode.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/RuleSetNode.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -22,7 +22,7 @@
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class RuleSetNode extends SequenceNode {
+public class RuleSetNode extends EventNode {
 
     private static final long serialVersionUID = 400L;
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Split.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Split.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/Split.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -18,10 +18,8 @@
 
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 
 import org.drools.workflow.core.Connection;
 import org.drools.workflow.core.Constraint;
@@ -63,7 +61,7 @@
     private static final long serialVersionUID = 400L;
 
     private int type;
-    private Map<Connection, Constraint> constraints = new HashMap<Connection, Constraint>();
+    private Map<ConnectionRef, Constraint> constraints = new HashMap<ConnectionRef, Constraint>();
 
     public Split() {
         this.type = TYPE_UNDEFINED;
@@ -86,18 +84,9 @@
             throw new IllegalArgumentException( "connection is null" );
         }
 
-        // dirty hack because keys were entered wrong
-        // probably caused by xstreams
-        // TODO xstream 1.3.0 should fix this by default; in 1.2.2 it's fixable: http://jira.codehaus.org/browse/XSTR-363
-        final HashMap<Connection, Constraint> newMap = new HashMap<Connection, Constraint>();
-        for (final Iterator<Map.Entry<Connection, Constraint>> it = this.constraints.entrySet().iterator(); it.hasNext(); ) {
-            final Entry<Connection, Constraint> entry = it.next();
-            newMap.put(entry.getKey(), entry.getValue());
-        }
-        this.constraints = newMap;
-
         if ( this.type == TYPE_OR || this.type == TYPE_XOR ) {
-            return this.constraints.get(connection);
+            ConnectionRef ref = new ConnectionRef(connection.getTo().getId(), connection.getToType());
+            return this.constraints.get(ref);
         }
         throw new UnsupportedOperationException( "Constraints are " + "only supported with XOR or OR split types, not with: " + getType() );
     }
@@ -112,20 +101,22 @@
                     && !getOutgoingConnections(Node.CONNECTION_DEFAULT_TYPE).contains(connection)) {
                 throw new IllegalArgumentException("connection is unknown:" + connection);
             }
-            this.constraints.put( connection,
-                                  constraint );
+            internalSetConstraint(
+                new ConnectionRef(connection.getTo().getId(), connection.getToType()),
+                constraint);
         } else {
             throw new UnsupportedOperationException( "Constraints are " + "only supported with XOR or OR split types, not with type:" + getType() );
         }
     }
 
-    public Map<Connection, Constraint> getConstraints() {
-        if ( this.type == TYPE_OR || this.type == TYPE_XOR ) {
-            return Collections.unmodifiableMap( this.constraints );
-        }
-        throw new UnsupportedOperationException( "Constraints are " + "only supported with XOR or OR split types, not with: " + getType() );
+    public void internalSetConstraint(ConnectionRef connectionRef, Constraint constraint) {
+        this.constraints.put(connectionRef, constraint);
     }
 
+    public Map<ConnectionRef, Constraint> getConstraints() {
+        return Collections.unmodifiableMap( this.constraints );
+    }
+
     public Connection getFrom() {
         final List<Connection> list =
             getIncomingConnections(Node.CONNECTION_DEFAULT_TYPE);
@@ -162,7 +153,39 @@
 
     public void removeOutgoingConnection(final String type, final Connection connection) {
         super.removeOutgoingConnection(type, connection);
-        this.constraints.remove(connection);
+        ConnectionRef ref = new ConnectionRef(connection.getTo().getId(), connection.getToType());
+        this.constraints.remove(ref);
     }
+    
+    public static class ConnectionRef {
+        
+        private String toType;
+        private long nodeId;
+        
+        public ConnectionRef(long nodeId, String toType) {
+            this.nodeId = nodeId;
+            this.toType = toType;
+        }
+        
+        public String getToType() {
+            return toType;
+        }
+        
+        public long getNodeId() {
+            return nodeId;
+        }
+        
+        public boolean equals(Object o) {
+            if (o instanceof ConnectionRef) {
+                ConnectionRef c = (ConnectionRef) o;
+                return toType.equals(c.toType) && nodeId == c.nodeId;
+            }
+            return false;
+        }
+        
+        public int hashCode() {
+            return 7*toType.hashCode() + (int) nodeId;
+        }
+    }
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/SubProcessNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/SubProcessNode.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/SubProcessNode.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -22,12 +22,14 @@
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class SubProcessNode extends SequenceNode {
+public class SubProcessNode extends EventNode {
 
 	private static final long serialVersionUID = 400L;
 	
 	private String            processId;
 	private boolean           waitForCompletion = true;
+	// TODO boolean independent (cancel process if node gets cancelled?)
+	// TODO parameter passing
 
     public void setProcessId(final String processId) {
         this.processId = processId;

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/TimerNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/TimerNode.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/TimerNode.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,19 @@
+package org.drools.workflow.core.node;
+
+import org.drools.process.core.timer.Timer;
+
+public class TimerNode extends SequenceNode {
+
+    private static final long serialVersionUID = 400L;
+    
+    private Timer timer;
+    
+    public void setTimer(Timer timer) {
+        this.timer = timer;
+    }
+    
+    public Timer getTimer() {
+        return this.timer;
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/WorkItemNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/WorkItemNode.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/WorkItemNode.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -27,26 +27,32 @@
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class WorkItemNode extends SequenceNode {
+public class WorkItemNode extends EventNode {
 
 	private static final long serialVersionUID = 400L;
 	
 	private Work work;
     private Map<String, String> inMapping = new HashMap<String, String>();
     private Map<String, String> outMapping = new HashMap<String, String>();
+    private boolean waitForCompletion = true;
+    // TODO boolean independent (cancel work item if node gets cancelled?)
 
 	public Work getWork() {
 		return work;
 	}
 
-	public void setWork(Work task) {
-		this.work = task;
+	public void setWork(Work work) {
+		this.work = work;
 	}
 	
     public void addInMapping(String parameterName, String variableName) {
         inMapping.put(parameterName, variableName);
     }
     
+    public void setInMappings(Map<String, String> inMapping) {
+        this.inMapping = inMapping;
+    }
+    
     public String getInMapping(String parameterName) {
         return inMapping.get(parameterName);
     }
@@ -59,6 +65,10 @@
         outMapping.put(parameterName, variableName);
     }
     
+    public void setOutMappings(Map<String, String> outMapping) {
+        this.outMapping = outMapping;
+    }
+    
     public String getOutMapping(String parameterName) {
         return outMapping.get(parameterName);
     }
@@ -67,4 +77,12 @@
         return Collections.unmodifiableMap(outMapping);
     }
 
+    public boolean isWaitForCompletion() {
+        return waitForCompletion;
+    }
+
+    public void setWaitForCompletion(boolean waitForCompletion) {
+        this.waitForCompletion = waitForCompletion;
+    }
+
 }

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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/WorkflowProcessInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -16,10 +16,9 @@
  * limitations under the License.
  */
 
-import org.drools.Agenda;
-import org.drools.WorkingMemory;
 import org.drools.process.instance.ProcessInstance;
 import org.drools.process.instance.WorkItemListener;
+import org.drools.process.instance.timer.TimerListener;
 import org.drools.workflow.core.WorkflowProcess;
 
 /**
@@ -33,12 +32,12 @@
 
     WorkflowProcess getWorkflowProcess();
 
-    WorkingMemory getWorkingMemory();
-
-    Agenda getAgenda();
-    
     void addWorkItemListener(WorkItemListener listener);
 
     void removeWorkItemListener(WorkItemListener listener);
 
+    void addTimerListener(TimerListener listener);
+
+    void removeTimerListener(TimerListener listener);
+
 }
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/context/WorkflowContextInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/context/WorkflowContextInstance.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/context/WorkflowContextInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,12 @@
+package org.drools.workflow.instance.context;
+
+import org.drools.process.instance.ContextInstance;
+import org.drools.workflow.instance.NodeInstanceContainer;
+
+public interface WorkflowContextInstance extends ContextInstance {
+
+    NodeInstanceContainer getNodeInstanceContainer();
+    
+    void setNodeInstanceContainer(NodeInstanceContainer nodeInstanceContainer);
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/context/WorkflowReuseContextInstanceFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/context/WorkflowReuseContextInstanceFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/context/WorkflowReuseContextInstanceFactory.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,50 @@
+package org.drools.workflow.instance.context;
+
+import org.drools.process.core.Context;
+import org.drools.process.instance.ContextInstance;
+import org.drools.process.instance.ContextInstanceContainer;
+import org.drools.process.instance.context.AbstractContextInstance;
+import org.drools.process.instance.impl.ContextInstanceFactory;
+import org.drools.workflow.instance.NodeInstanceContainer;
+
+public class WorkflowReuseContextInstanceFactory implements ContextInstanceFactory {
+    
+    public final Class<? extends ContextInstance> cls;
+    
+    public WorkflowReuseContextInstanceFactory(Class<? extends ContextInstance> cls){
+        this.cls = cls;
+    }
+
+	public ContextInstance getContextInstance(Context context, ContextInstanceContainer contextInstanceContainer) {    	
+        ContextInstance result = contextInstanceContainer.getContextInstance( context.getType(), context.getId() );
+        if (result != null) {
+            return result;
+        }
+        try {
+            AbstractContextInstance contextInstance = (AbstractContextInstance) cls.newInstance();
+            contextInstance.setContextId(context.getId());
+            contextInstance.setContextInstanceContainer(contextInstanceContainer);
+            NodeInstanceContainer nodeInstanceContainer = null;
+            if (contextInstanceContainer instanceof NodeInstanceContainer) {
+                nodeInstanceContainer = (NodeInstanceContainer) contextInstanceContainer;
+            } else if (contextInstanceContainer instanceof ContextInstance) {
+                ContextInstanceContainer parent = ((ContextInstance) contextInstanceContainer).getContextInstanceContainer();
+                while (parent != null) {
+                    if (parent instanceof NodeInstanceContainer) {
+                        nodeInstanceContainer = (NodeInstanceContainer) parent;
+                    } else if (contextInstanceContainer instanceof ContextInstance) {
+                        parent = ((ContextInstance) contextInstanceContainer).getContextInstanceContainer();
+                    } else {
+                        parent = null;
+                    }
+                }
+            }
+            ((WorkflowContextInstance) contextInstance).setNodeInstanceContainer(nodeInstanceContainer);
+            return contextInstance;
+        } catch (Exception e) {
+            throw new RuntimeException("Unable to instantiate context '"
+                + this.cls.getName() + "': " + e.getMessage());
+        }
+	}
+
+}

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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceFactoryRegistry.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -12,6 +12,7 @@
 import org.drools.workflow.core.node.Split;
 import org.drools.workflow.core.node.StartNode;
 import org.drools.workflow.core.node.SubProcessNode;
+import org.drools.workflow.core.node.TimerNode;
 import org.drools.workflow.core.node.WorkItemNode;
 import org.drools.workflow.instance.impl.factory.CreateNewNodeFactory;
 import org.drools.workflow.instance.impl.factory.ReuseNodeFactory;
@@ -23,6 +24,7 @@
 import org.drools.workflow.instance.node.SplitInstance;
 import org.drools.workflow.instance.node.StartNodeInstance;
 import org.drools.workflow.instance.node.SubProcessNodeInstance;
+import org.drools.workflow.instance.node.TimerNodeInstance;
 import org.drools.workflow.instance.node.WorkItemNodeInstance;
 
 public class NodeInstanceFactoryRegistry {
@@ -52,6 +54,8 @@
                   new CreateNewNodeFactory( ActionNodeInstance.class ) );
         register( WorkItemNode.class,
                   new CreateNewNodeFactory( WorkItemNodeInstance.class ) );
+        register( TimerNode.class,
+                  new CreateNewNodeFactory( TimerNodeInstance.class ) );
     }
 
     public void register(Class< ? extends Node> cls,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceImpl.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -20,7 +20,11 @@
 
 import org.drools.common.EventSupport;
 import org.drools.common.InternalWorkingMemory;
+import org.drools.process.core.Context;
+import org.drools.process.instance.ContextInstance;
+import org.drools.process.instance.ContextInstanceContainer;
 import org.drools.workflow.core.Node;
+import org.drools.workflow.core.impl.NodeImpl;
 import org.drools.workflow.instance.NodeInstance;
 import org.drools.workflow.instance.NodeInstanceContainer;
 import org.drools.workflow.instance.WorkflowProcessInstance;
@@ -87,4 +91,20 @@
     }
     
     public abstract void internalTrigger(NodeInstance from, String type);
+    
+    public Context resolveContext(String contextId, Object param) {
+        return ((NodeImpl) getNode()).resolveContext(contextId, param);
+    }
+    
+    public ContextInstance resolveContextInstance(String contextId, Object param) {
+        Context context = resolveContext(contextId, param);
+        if (context == null) {
+            return null;
+        }
+        // TODO: find right context instance container and get context instance
+        // TODO: currently, only the process instance acts as a context instance container
+        ContextInstanceContainer contextInstanceContainer = getProcessInstance();
+        return contextInstanceContainer.getContextInstance(context);
+    }
+    
 }

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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/WorkflowProcessInstanceImpl.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -24,19 +24,21 @@
 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.process.core.timer.Timer;
 import org.drools.process.instance.WorkItem;
 import org.drools.process.instance.WorkItemListener;
 import org.drools.process.instance.impl.ProcessInstanceImpl;
+import org.drools.process.instance.timer.TimerListener;
 import org.drools.workflow.core.Node;
 import org.drools.workflow.core.NodeContainer;
 import org.drools.workflow.core.WorkflowProcess;
 import org.drools.workflow.instance.NodeInstance;
 import org.drools.workflow.instance.NodeInstanceContainer;
 import org.drools.workflow.instance.WorkflowProcessInstance;
+import org.drools.workflow.instance.node.EventNodeInstance;
 
 /**
  * Default implementation of a RuleFlow process instance.
@@ -48,15 +50,11 @@
 
     private static final long serialVersionUID = 400L;
 
-    private InternalWorkingMemory workingMemory;
     private final List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>();;
     private long nodeInstanceCounter = 0;
     private List<WorkItemListener> workItemListeners = new CopyOnWriteArrayList<WorkItemListener>();
+    private List<TimerListener> timerListeners = new CopyOnWriteArrayList<TimerListener>();
 
-    public WorkflowProcess getWorkflowProcess() {
-        return (WorkflowProcess) getProcess();
-    }
-
     public NodeContainer getNodeContainer() {
         return getWorkflowProcess();
     }
@@ -100,16 +98,13 @@
 
     public NodeInstance getNodeInstance(final Node node) {
         NodeInstanceFactoryRegistry nodeRegistry =
-            ((InternalRuleBase) this.workingMemory.getRuleBase())
+            ((InternalRuleBase) getWorkingMemory().getRuleBase())
                 .getConfiguration().getProcessNodeInstanceFactoryRegistry();
         NodeInstanceFactory conf = nodeRegistry.getProcessNodeInstanceFactory(node);
         if (conf == null) {
             throw new IllegalArgumentException("Illegal node type: " + node.getClass());
         }
         NodeInstanceImpl nodeInstance = (NodeInstanceImpl) conf.getNodeInstance(node, this, this);
-        nodeInstance.setNodeId(node.getId());
-        nodeInstance.setNodeInstanceContainer(this);
-        nodeInstance.setProcessInstance(this);
         if (nodeInstance == null) {
             throw new IllegalArgumentException("Illegal node type: " + node.getClass());
         }
@@ -117,39 +112,52 @@
     }
 
     public Agenda getAgenda() {
-        if ( this.workingMemory == null ) {
+        if ( getWorkingMemory() == null ) {
             return null;
         }
-        return this.workingMemory.getAgenda();
+        return getWorkingMemory().getAgenda();
     }
 
-    public void setWorkingMemory(final InternalWorkingMemory workingMemory) {
-        if ( this.workingMemory != null ) {
-            throw new IllegalArgumentException( "A working memory can only be set once." );
-        }
-        this.workingMemory = workingMemory;
+    public WorkflowProcess getWorkflowProcess() {
+        return (WorkflowProcess) getProcess();
     }
 
-    public WorkingMemory getWorkingMemory() {
-        return this.workingMemory;
-    }
-    
     public void setState(final int state) {
         super.setState( state );
+        // TODO move most of this to ProcessInstanceImpl
         if ( state == ProcessInstanceImpl.STATE_COMPLETED ) {
-            ((EventSupport) this.workingMemory).getRuleFlowEventSupport().fireBeforeRuleFlowProcessCompleted( this,
-                                                                                                              this.workingMemory );
+            InternalWorkingMemory workingMemory = (InternalWorkingMemory) getWorkingMemory();
+            ((EventSupport) getWorkingMemory()).getRuleFlowEventSupport()
+                .fireBeforeRuleFlowProcessCompleted( this, workingMemory );
             // deactivate all node instances of this process instance
             while ( !nodeInstances.isEmpty() ) {
                 NodeInstance nodeInstance = (NodeInstance) nodeInstances.get( 0 );
                 nodeInstance.cancel();
             }
             workingMemory.removeProcessInstance( this );
-            ((EventSupport) this.workingMemory).getRuleFlowEventSupport().fireAfterRuleFlowProcessCompleted( this,
-                                                                                                             this.workingMemory );
+            ((EventSupport) workingMemory).getRuleFlowEventSupport()
+                .fireAfterRuleFlowProcessCompleted( this, workingMemory );
         }
     }
 
+    public void disconnect() {
+        for (NodeInstance nodeInstance: nodeInstances) {
+            if (nodeInstance instanceof EventNodeInstance) {
+                ((EventNodeInstance) nodeInstance).removeEventListeners();
+            }
+        }
+        super.disconnect();
+    }
+    
+    public void reconnect() {
+        super.reconnect();
+        for (NodeInstance nodeInstance: nodeInstances) {
+            if (nodeInstance instanceof EventNodeInstance) {
+                ((EventNodeInstance) nodeInstance).addEventListeners();
+            }
+        }
+    }
+    
     public String toString() {
         final StringBuffer sb = new StringBuffer( "WorkflowProcessInstance" );
         sb.append( getId() );
@@ -181,4 +189,18 @@
         workItemListeners.remove(listener);
     }
     
+    public void timerTriggered(Timer timer) {
+        for (TimerListener listener: timerListeners) {
+            listener.timerTriggered(timer);
+        }
+    }
+
+    public void addTimerListener(TimerListener listener) {
+        timerListeners.add(listener);
+    }
+    
+    public void removeTimerListener(TimerListener listener) {
+        timerListeners.remove(listener);
+    }
+    
 }

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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/factory/CreateNewNodeFactory.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -5,6 +5,7 @@
 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.NodeInstanceImpl;
 
 public class CreateNewNodeFactory implements NodeInstanceFactory {
     
@@ -14,9 +15,13 @@
         this.cls = cls;
     }
     
-    public NodeInstance getNodeInstance(Node node, WorkflowProcessInstance processInstance, NodeInstanceContainer nodeInstanceContainer ) {     
+    public NodeInstance getNodeInstance(Node node, WorkflowProcessInstance processInstance, NodeInstanceContainer nodeInstanceContainer) {     
         try {
-            return this.cls.newInstance();
+            NodeInstanceImpl nodeInstance = (NodeInstanceImpl) this.cls.newInstance();
+            nodeInstance.setNodeId(node.getId());
+            nodeInstance.setNodeInstanceContainer(nodeInstanceContainer);
+            nodeInstance.setProcessInstance(processInstance);
+            return nodeInstance;
         } catch (Exception e) {
             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/impl/factory/ReuseNodeFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/factory/ReuseNodeFactory.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/factory/ReuseNodeFactory.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -5,6 +5,7 @@
 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.NodeInstanceImpl;
 
 public class ReuseNodeFactory implements NodeInstanceFactory {
     
@@ -14,13 +15,17 @@
         this.cls = cls;
     }
 
-	public NodeInstance getNodeInstance(Node node, WorkflowProcessInstance processInstance, NodeInstanceContainer nodeInstanceContainer ) {    	
+	public NodeInstance getNodeInstance(Node node, WorkflowProcessInstance processInstance, NodeInstanceContainer nodeInstanceContainer) {    	
         NodeInstance result = nodeInstanceContainer.getFirstNodeInstance( node.getId() );
         if (result != null) {
             return result;
         }
         try {
-            return cls.newInstance();
+            NodeInstanceImpl nodeInstance = (NodeInstanceImpl) cls.newInstance();
+            nodeInstance.setNodeId(node.getId());
+            nodeInstance.setNodeInstanceContainer(nodeInstanceContainer);
+            nodeInstance.setProcessInstance(processInstance);
+            return nodeInstance;
         } catch (Exception e) {
             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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -52,7 +52,7 @@
     public NodeContainer getNodeContainer() {
         return getCompositeNode();
     }
-
+    
     public void internalTrigger(final NodeInstance from, String type) {
         CompositeNode.NodeAndType nodeAndType = getCompositeNode().getLinkedIncomingNode(type);
         List<Connection> connections = nodeAndType.getNode().getIncomingConnections(nodeAndType.getType());
@@ -74,6 +74,14 @@
         getNodeInstanceContainer().getNodeInstance( connection.getTo() ).trigger( this, connection.getToType() );
     }
 
+    public void cancel() {
+        while (!nodeInstances.isEmpty()) {
+            NodeInstance nodeInstance = (NodeInstance) nodeInstances.get(0);
+            nodeInstance.cancel();
+        }
+        super.cancel();
+    }
+    
     public void addNodeInstance(final NodeInstance nodeInstance) {
         ((NodeInstanceImpl) nodeInstance).setId(nodeInstanceCounter++);
         this.nodeInstances.add(nodeInstance);

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventNodeInstance.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/EventNodeInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,29 @@
+package org.drools.workflow.instance.node;
+
+import org.drools.workflow.core.node.EventNode;
+import org.drools.workflow.instance.impl.NodeInstanceImpl;
+
+public abstract class EventNodeInstance extends NodeInstanceImpl {
+
+    public EventNode getEventNode() {
+        return (EventNode) getNode();
+    }
+    
+    public void triggerCompleted() {
+        getNodeInstanceContainer().removeNodeInstance(this);
+        getNodeInstanceContainer().getNodeInstance(getEventNode().getTo().getTo())
+            .trigger(this, getEventNode().getTo().getToType());
+    }
+    
+    public void cancel() {
+        super.cancel();
+        removeEventListeners();
+    }
+    
+    public void addEventListeners() {
+    }
+    
+    public void removeEventListeners() {
+    }
+    
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/MilestoneNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/MilestoneNodeInstance.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/MilestoneNodeInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -32,14 +32,13 @@
 import org.drools.workflow.core.Node;
 import org.drools.workflow.core.node.MilestoneNode;
 import org.drools.workflow.instance.NodeInstance;
-import org.drools.workflow.instance.impl.NodeInstanceImpl;
 
 /**
  * Runtime counterpart of a milestone node.
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class MilestoneNodeInstance extends NodeInstanceImpl implements AgendaEventListener {
+public class MilestoneNodeInstance extends EventNodeInstance implements AgendaEventListener {
 
     private static final long serialVersionUID = 400L;
 
@@ -55,20 +54,24 @@
     	RuleFlowGroup systemRuleFlowGroup = getProcessInstance().getAgenda().getRuleFlowGroup("DROOLS_SYSTEM");
     	String rule = "RuleFlow-Milestone-" + getProcessInstance().getProcess().getId()
     		+ "-" + getNode().getId();
-    	for (Iterator activations = systemRuleFlowGroup.iterator(); activations.hasNext(); ) {
-    		Activation activation = ((RuleFlowGroupNode) activations.next()).getActivation();
+    	for (Iterator<RuleFlowGroupNode> activations = systemRuleFlowGroup.iterator(); activations.hasNext(); ) {
+    		Activation activation = activations.next().getActivation();
     		if (rule.equals(activation.getRule().getName())) {
     			triggerCompleted();
         		return;
     		}
     	}
-    	getProcessInstance().getWorkingMemory().addEventListener(this);
+    	addEventListeners();
     }
+    
+    public void addEventListeners() {
+        super.addEventListeners();
+        getProcessInstance().getWorkingMemory().addEventListener(this);
+    }
 
-    public void triggerCompleted() {
-        getNodeInstanceContainer().removeNodeInstance(this);
-        getNodeInstanceContainer().getNodeInstance(getMilestoneNode().getTo().getTo())
-            .trigger(this, getMilestoneNode().getTo().getToType());
+    public void removeEventListeners() {
+        super.removeEventListeners();
+        getProcessInstance().getWorkingMemory().removeEventListener(this);
     }
 
     public void activationCancelled(ActivationCancelledEvent event,
@@ -86,7 +89,7 @@
             String ruleName = event.getActivation().getRule().getName();
             String milestoneName = "RuleFlow-Milestone-" + getProcessInstance().getProcess().getId() + "-" + getNodeId();
             if (milestoneName.equals(ruleName)) {
-                getProcessInstance().getWorkingMemory().removeEventListener(this);
+                removeEventListeners();
                 triggerCompleted();
             }
         }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/RuleSetNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/RuleSetNodeInstance.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/RuleSetNodeInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -21,51 +21,58 @@
 import org.drools.workflow.core.Node;
 import org.drools.workflow.core.node.RuleSetNode;
 import org.drools.workflow.instance.NodeInstance;
-import org.drools.workflow.instance.impl.NodeInstanceImpl;
 
 /**
  * Runtime counterpart of a ruleset node.
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class RuleSetNodeInstance extends NodeInstanceImpl implements RuleFlowGroupListener {
+public class RuleSetNodeInstance extends EventNodeInstance implements RuleFlowGroupListener {
 
     private static final long serialVersionUID = 400L;
     
-    private InternalRuleFlowGroup ruleFlowGroup;
-
-    public RuleSetNodeInstance() {
-    }
+    private transient InternalRuleFlowGroup ruleFlowGroup;
     
     protected RuleSetNode getRuleSetNode() {
         return (RuleSetNode) getNode();
     }
 
     public void internalTrigger(final NodeInstance from, String type) {
-        ruleFlowGroup = (InternalRuleFlowGroup)
-        getProcessInstance().getWorkingMemory().getAgenda()
-            .getRuleFlowGroup(getRuleSetNode().getRuleFlowGroup());
-        ruleFlowGroup.addRuleFlowGroupListener(this);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
                 "A RuleSetNode only accepts default incoming connections!");
         }
+        addEventListeners();
         getProcessInstance().getAgenda().activateRuleFlowGroup( getRuleSetNode().getRuleFlowGroup() );
     }
 
-    public void triggerCompleted() {
-        getNodeInstanceContainer().removeNodeInstance(this);
-        getNodeInstanceContainer().getNodeInstance( getRuleSetNode().getTo().getTo() ).trigger( this, getRuleSetNode().getTo().getToType() );
+    public void addEventListeners() {
+        super.addEventListeners();
+        getRuleFlowGroup().addRuleFlowGroupListener(this);
     }
-    
+
+    public void removeEventListeners() {
+        super.removeEventListeners();
+        getRuleFlowGroup().removeRuleFlowGroupListener(this);
+    }
+
     public void cancel() {
+        super.cancel();
     	getProcessInstance().getAgenda().deactivateRuleFlowGroup( getRuleSetNode().getRuleFlowGroup() );
-    	super.cancel();
     }
 
     public void ruleFlowGroupDeactivated() {
-        ruleFlowGroup.removeRuleFlowGroupListener(this);
+        removeEventListeners();
         triggerCompleted();
     }
+    
+    private InternalRuleFlowGroup getRuleFlowGroup() {
+        if (this.ruleFlowGroup == null) {
+            this.ruleFlowGroup = (InternalRuleFlowGroup) getProcessInstance()
+                .getWorkingMemory().getAgenda()
+                    .getRuleFlowGroup(getRuleSetNode().getRuleFlowGroup());
+        }
+        return this.ruleFlowGroup;
+    }
 
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SplitInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SplitInstance.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SplitInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -69,7 +69,6 @@
                                                   constraint ) ) {
                             selected = connection;
                             priority = constraint.getPriority();
-                            break;
                         }
                     }
                 }

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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/SubProcessNodeInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -27,14 +27,13 @@
 import org.drools.workflow.core.Node;
 import org.drools.workflow.core.node.SubProcessNode;
 import org.drools.workflow.instance.NodeInstance;
-import org.drools.workflow.instance.impl.NodeInstanceImpl;
 
 /**
  * Runtime counterpart of a SubFlow node.
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class SubProcessNodeInstance extends NodeInstanceImpl implements RuleFlowEventListener {
+public class SubProcessNodeInstance extends EventNodeInstance implements RuleFlowEventListener {
 
     private static final long serialVersionUID = 400L;
     
@@ -55,7 +54,7 @@
     	        || processInstance.getState() == ProcessInstance.STATE_COMPLETED) {
     		triggerCompleted();
     	} else {
-    	    getProcessInstance().getWorkingMemory().addEventListener(this);
+    	    addEventListeners();
     		this.processInstanceId = processInstance.getId();
     	}
     }
@@ -64,16 +63,20 @@
     	return processInstanceId;
     }
 
-    public void triggerCompleted() {
-        getNodeInstanceContainer().removeNodeInstance(this);
-        getNodeInstanceContainer().getNodeInstance(getSubFlowNode().getTo().getTo())
-            .trigger(this, getSubFlowNode().getTo().getToType());
+    public void addEventListeners() {
+        super.addEventListeners();
+        getProcessInstance().getWorkingMemory().addEventListener(this);
     }
 
+    public void removeEventListeners() {
+        super.removeEventListeners();
+        getProcessInstance().getWorkingMemory().removeEventListener(this);
+    }
+
     public void afterRuleFlowCompleted(RuleFlowCompletedEvent event,
             WorkingMemory workingMemory) {
         if ( event.getRuleFlowProcessInstance().getId() == processInstanceId ) {
-            getProcessInstance().getWorkingMemory().removeEventListener(this);
+            removeEventListeners();
             triggerCompleted();
         }
     }

Added: 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	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/TimerNodeInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,61 @@
+package org.drools.workflow.instance.node;
+
+import org.drools.process.core.timer.Timer;
+import org.drools.process.instance.timer.TimerListener;
+import org.drools.workflow.core.Node;
+import org.drools.workflow.core.node.TimerNode;
+import org.drools.workflow.instance.NodeInstance;
+
+public class TimerNodeInstance extends EventNodeInstance implements TimerListener {
+
+    private static final long serialVersionUID = 400L;
+    
+    private long timerId;
+    
+    public TimerNode getTimerNode() {
+        return (TimerNode) getNode();
+    }
+
+    public void internalTrigger(NodeInstance from, String type) {
+        if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
+            throw new IllegalArgumentException(
+                "A TimerNode only accepts default incoming connections!");
+        }
+        Timer timer = getTimerNode().getTimer();
+        addEventListeners();
+        getProcessInstance().getWorkingMemory().getTimerManager()
+            .registerTimer(timer, getProcessInstance());
+        timerId = timer.getId();
+    }
+
+    public void timerTriggered(Timer timer) {
+        if (timer.getId() == timerId) {
+            triggerCompleted();
+        }
+    }
+    
+    public void triggerCompleted() {
+        if (getTimerNode().getTimer().getPeriod() == 0) {
+            getNodeInstanceContainer().removeNodeInstance(this);
+        }
+        getNodeInstanceContainer().getNodeInstance(getTimerNode().getTo().getTo())
+            .trigger(this, getTimerNode().getTo().getToType());
+    }
+    
+    public void cancel() {
+        getProcessInstance().getWorkingMemory().getTimerManager()
+            .cancelTimer(getTimerNode().getTimer());
+        super.cancel();
+    }
+    
+    public void addEventListeners() {
+        super.addEventListeners();
+        getProcessInstance().addTimerListener(this);
+    }
+    
+    public void removeEventListeners() {
+        super.removeEventListeners();
+        getProcessInstance().removeTimerListener(this);
+    }
+
+}

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-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -20,19 +20,20 @@
 import java.util.Map;
 
 import org.drools.process.core.Work;
+import org.drools.process.core.context.variable.VariableScope;
 import org.drools.process.instance.WorkItem;
 import org.drools.process.instance.WorkItemListener;
+import org.drools.process.instance.context.variable.VariableScopeInstance;
 import org.drools.process.instance.impl.WorkItemImpl;
 import org.drools.workflow.core.node.WorkItemNode;
 import org.drools.workflow.instance.NodeInstance;
-import org.drools.workflow.instance.impl.NodeInstanceImpl;
 
 /**
  * Runtime counterpart of a task node.
  * 
  * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
  */
-public class WorkItemNodeInstance extends NodeInstanceImpl implements WorkItemListener {
+public class WorkItemNodeInstance extends EventNodeInstance implements WorkItemListener {
 
     private static final long serialVersionUID = 400L;
     
@@ -60,31 +61,66 @@
 		workItem.setParameters(work.getParameters());
 		for (Iterator<Map.Entry<String, String>> iterator = workItemNode.getInMappings().entrySet().iterator(); iterator.hasNext(); ) {
             Map.Entry<String, String> mapping = iterator.next();
-            workItem.setParameter(mapping.getKey(), getProcessInstance().getVariable(mapping.getValue()));
+            VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+                resolveContextInstance(VariableScope.VARIABLE_SCOPE, mapping.getValue());
+            if (variableScopeInstance != null) {
+                workItem.setParameter(mapping.getKey(), variableScopeInstance.getVariable(mapping.getValue()));
+            } else {
+                System.err.println("Could not find variable scope for variable " + mapping.getValue());
+                System.err.println("when trying to execute Work Item " + work.getName());
+                System.err.println("Continuing without setting parameter.");
+            }
         }
-		getProcessInstance().addWorkItemListener(this);
-		getProcessInstance().getWorkingMemory().getWorkItemManager().executeWorkItem(workItem);
+		if (workItemNode.isWaitForCompletion()) {
+		    addEventListeners();
+        }
+        getProcessInstance().getWorkingMemory().getWorkItemManager().internalExecuteWorkItem(workItem);
+        if (!workItemNode.isWaitForCompletion()) {
+            triggerCompleted();
+        }
     }
 
     public void triggerCompleted(WorkItem workItem) {
-        getNodeInstanceContainer().removeNodeInstance(this);
         for (Iterator<Map.Entry<String, String>> iterator = getWorkItemNode().getOutMappings().entrySet().iterator(); iterator.hasNext(); ) {
             Map.Entry<String, String> mapping = iterator.next();
-            getProcessInstance().setVariable(mapping.getValue(), workItem.getResult(mapping.getKey()));
+            VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+                resolveContextInstance(VariableScope.VARIABLE_SCOPE, mapping.getValue());
+            if (variableScopeInstance != null) {
+                variableScopeInstance.setVariable(mapping.getValue(), workItem.getResult(mapping.getKey()));
+            } else {
+                System.err.println("Could not find variable scope for variable " + mapping.getValue());
+                System.err.println("when trying to complete Work Item " + workItem.getName());
+                System.err.println("Continuing without setting variable.");
+            }
         }
-        getNodeInstanceContainer().getNodeInstance( getWorkItemNode().getTo().getTo() ).trigger( this, getWorkItemNode().getTo().getToType() );
+        triggerCompleted();
     }
+    
+    public void cancel() {
+        super.cancel();
+        getProcessInstance().getWorkingMemory().getWorkItemManager().internalAbortWorkItem(workItem.getId());
+    }
+    
+    public void addEventListeners() {
+        super.addEventListeners();
+        getProcessInstance().addWorkItemListener(this);
+    }
+    
+    public void removeEventListeners() {
+        super.removeEventListeners();
+        getProcessInstance().removeWorkItemListener(this);
+    }
 
     public void workItemAborted(WorkItem workItem) {
         if ( this.workItem.getId() == workItem.getId() ) {
-            getProcessInstance().removeWorkItemListener(this);
+            removeEventListeners();
             triggerCompleted(workItem);
         }
     }
 
     public void workItemCompleted(WorkItem workItem) {
         if ( this.workItem.getId() == workItem.getId() ) {
-            getProcessInstance().removeWorkItemListener(this);
+            removeEventListeners();
             triggerCompleted(workItem);
         }
     }

Added: labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/WorkDefinitions.conf
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/WorkDefinitions.conf	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/WorkDefinitions.conf	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,47 @@
+// We use MVEL to return a List of work definitions
+// The properties of the work definitions are specified as a Map<String, Object>
+// The allowed properties are name, parameters, displayName, icon and customEditor
+// The returned result should thus be of type List<Map<String, Object>>
+import org.drools.process.core.datatype.impl.type.StringDataType;
+import org.drools.process.core.datatype.impl.type.DateDataType;
+
+[
+
+  [
+    "name" : "Email",
+    "parameters" : [
+    	"From" : new StringDataType(),
+    	"To" : new StringDataType(),
+    	"Subject" : new StringDataType(),
+    	"Text" : new StringDataType()
+    ],
+    "displayName" : "Email",
+    "icon" : "icons/import_statement.gif",
+    "customEditor" : "org.drools.eclipse.flow.common.editor.editpart.work.SampleCustomEditor"
+  ],
+  
+  [
+    "name" : "Log",
+    "parameters" : [
+      "Message" : new StringDataType()
+    ],
+    "displayName" : "Log",
+    "icon" : "icons/open.gif"
+  ]
+  
+  [
+    "name" : "Human Task",
+    "parameters" : [
+      "ActorId" : new StringDataType(),
+      "TaskName" : new StringDataType(),
+      "Priority" : new StringDataType(),
+      "Comment" : new StringDataType()
+    ],
+    "results" : [
+      "ActorId" : new StringDataType()
+    ],
+    "displayName" : "Human Task",
+    "icon" : "icons/human_task.gif"
+  ]
+  
+]
\ No newline at end of file

Deleted: labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf	2008-04-06 23:46:49 UTC (rev 19430)
@@ -1,19 +0,0 @@
-drools.maintainTms = true
-drools.shadowproxy = true
-drools.shadowproxy.exclude =
-drools.sequential = false
-drools.sequential.agenda = sequential
-drools.removeIdentities = false
-drools.shareAlphaNodes = true
-drools.shareBetaNodes = true
-drools.alphaMemory = false
-drools.alphaNodeHashingThreshold = 3
-drools.compositeKeyDepth = 3
-drools.indexLeftBetaMemory = true
-drools.indexRightBetaMemory = true
-drools.assertBehaviour = IDENTITY
-drools.logicalOverride = DISCARD
-drools.executorService = org.drools.concurrent.DefaultExecutorService
-drools.conflictResolver = org.drools.conflict.DepthConflictResolver
-drools.consequenceExceptionHandler = org.drools.base.DefaultConsequenceExceptionHandler
-drools.ruleBaseUpdateHandler = org.drools.base.FireAllRulesRuleBaseUpdateListener

Added: labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/resources/META-INF/drools.default.rulebase.conf	2008-04-06 23:46:49 UTC (rev 19430)
@@ -0,0 +1,20 @@
+drools.maintainTms = true
+drools.shadowproxy = true
+drools.shadowproxy.exclude =
+drools.sequential = false
+drools.sequential.agenda = sequential
+drools.removeIdentities = false
+drools.shareAlphaNodes = true
+drools.shareBetaNodes = true
+drools.alphaMemory = false
+drools.alphaNodeHashingThreshold = 3
+drools.compositeKeyDepth = 3
+drools.indexLeftBetaMemory = true
+drools.indexRightBetaMemory = true
+drools.assertBehaviour = IDENTITY
+drools.logicalOverride = DISCARD
+drools.executorService = org.drools.concurrent.DefaultExecutorService
+drools.conflictResolver = org.drools.conflict.DepthConflictResolver
+drools.consequenceExceptionHandler = org.drools.base.DefaultConsequenceExceptionHandler
+drools.ruleBaseUpdateHandler = org.drools.base.FireAllRulesRuleBaseUpdateListener
+drools.workDefinitions = WorkDefinitions.conf

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/RuleFlowGroupTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/RuleFlowGroupTest.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/RuleFlowGroupTest.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -140,19 +140,27 @@
 
         // nodes
         final StartNode start = new StartNode();
+        start.setId(1);
         final RuleSetNode ruleSet0 = new RuleSetNode();
         ruleSet0.setRuleFlowGroup( "rule-flow-group-0" );
+        ruleSet0.setId(2);
         final RuleSetNode ruleSet1 = new RuleSetNode();
         ruleSet1.setRuleFlowGroup( "rule-flow-group-1" );
+        ruleSet1.setId(3);
         final RuleSetNode ruleSet2 = new RuleSetNode();
         ruleSet2.setRuleFlowGroup( "rule-flow-group-2" );
+        ruleSet2.setId(4);
         final RuleSetNode ruleSet3 = new RuleSetNode();
         ruleSet3.setRuleFlowGroup( "rule-flow-group-3" );
+        ruleSet3.setId(5);
         final Split split = new Split();
         split.setType( Split.TYPE_AND );
+        split.setId(6);
         final Join join = new Join();
         join.setType( Join.TYPE_AND );
+        join.setId(7);
         final EndNode end = new EndNode();
+        end.setId(8);
         // connections
         new ConnectionImpl( start,
                             Node.CONNECTION_DEFAULT_TYPE,
@@ -411,19 +419,27 @@
 
         // nodes
         final StartNode start = new StartNode();
+        start.setId(1);
         final RuleSetNode ruleSet0 = new RuleSetNode();
         ruleSet0.setRuleFlowGroup( "rule-flow-group-0" );
+        ruleSet0.setId(2);
         final RuleSetNode ruleSet1 = new RuleSetNode();
         ruleSet1.setRuleFlowGroup( "rule-flow-group-1" );
+        ruleSet1.setId(3);
         final RuleSetNode ruleSet2 = new RuleSetNode();
         ruleSet2.setRuleFlowGroup( "rule-flow-group-2" );
+        ruleSet2.setId(4);
         final RuleSetNode ruleSet3 = new RuleSetNode();
         ruleSet3.setRuleFlowGroup( "rule-flow-group-3" );
+        ruleSet3.setId(5);
         final Split split = new Split();
         split.setType( Split.TYPE_XOR );
+        split.setId(6);
         final Join join = new Join();
         join.setType( Join.TYPE_XOR );
+        join.setId(7);
         final EndNode end = new EndNode();
+        end.setId(8);
         // connections
         new ConnectionImpl( start,
                             Node.CONNECTION_DEFAULT_TYPE,

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/workflow/instance/node/MockNodeInstanceFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/workflow/instance/node/MockNodeInstanceFactory.java	2008-04-06 21:04:22 UTC (rev 19429)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/workflow/instance/node/MockNodeInstanceFactory.java	2008-04-06 23:46:49 UTC (rev 19430)
@@ -22,6 +22,9 @@
     }
 
     public NodeInstance getNodeInstance(Node node, WorkflowProcessInstance processInstance, NodeInstanceContainer nodeInstanceContainer) {
+        instance.setProcessInstance(processInstance);
+        instance.setNodeInstanceContainer(nodeInstanceContainer);
         return instance;
-    }        
+    }
+      
 }
\ No newline at end of file




More information about the jboss-svn-commits mailing list