You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mr...@apache.org on 2008/11/20 17:26:28 UTC

svn commit: r719270 [2/4] - in /ode/branches/APACHE_ODE_1.X: axis2-war/src/test/java/org/apache/ode/axis2/correlation/ axis2-war/src/test/java/org/apache/ode/axis2/instancecleanup/ axis2-war/src/test/resources/TestCorrelationJoin/ axis2-war/src/test/re...

Added: ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/CorrelationMultiTest.wsdl
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/CorrelationMultiTest.wsdl?rev=719270&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/CorrelationMultiTest.wsdl (added)
+++ ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/CorrelationMultiTest.wsdl Thu Nov 20 08:26:25 2008
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<wsdl:definitions
+        targetNamespace="http://ode/bpel/unit-test.wsdl"
+        xmlns="http://schemas.xmlsoap.org/wsdl/"
+        xmlns:tns="http://ode/bpel/unit-test.wsdl"
+        xmlns:typens="http://ode/bpel/unit-test/testCorrelation.wsdl.types"
+        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+        xmlns:dummy="http://axis2.ode.apache.org"
+        xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype"
+        xmlns:prop="http://docs.oasis-open.org/wsbpel/2.0/varprop">
+
+    <wsdl:import namespace="http://axis2.ode.apache.org" location="dummy-service.wsdl"/>
+
+    <wsdl:types>
+        <xsd:schema
+                targetNamespace="http://ode/bpel/unit-test/testCorrelation.wsdl.types"
+                xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+            <xsd:complexType name="testMessage">
+                <xsd:sequence>
+                    <xsd:element name="correlationID1" type="xsd:string"/>
+                    <xsd:element name="correlationID2" type="xsd:string"/>
+                    <xsd:element name="correlationID3" type="xsd:string"/>
+                    <xsd:element name="correlationID4" type="xsd:string"/>
+                    <xsd:element name="requestText" type="xsd:string"/>
+                </xsd:sequence>
+            </xsd:complexType>
+        </xsd:schema>
+    </wsdl:types>
+
+    <wsdl:message name="HeaderTestMessage">
+        <wsdl:part name="TestPart" type="typens:testMessage"/>
+    </wsdl:message>
+
+    <wsdl:portType name="HeaderTestPortType">
+        <wsdl:operation name="hello">
+            <wsdl:input message="tns:HeaderTestMessage" name="TestIn"/>
+            <wsdl:output message="tns:HeaderTestMessage" name="TestOut"/>
+        </wsdl:operation>
+        <wsdl:operation name="continue">
+            <wsdl:input message="tns:HeaderTestMessage" name="TestIn"/>
+        </wsdl:operation>
+    </wsdl:portType>
+
+    <wsdl:binding name="HeaderTestSoapBinding" type="tns:HeaderTestPortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
+        <wsdl:operation name="hello">
+            <soap:operation soapAction="" style="rpc"/>
+            <wsdl:input>
+                <soap:body namespace="http://ode/bpel/unit-test.wsdl" use="literal"/>
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body namespace="http://ode/bpel/unit-test.wsdl" use="literal"/>
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="continue">
+            <soap:operation soapAction="" style="rpc"/>
+            <wsdl:input>
+                <soap:body namespace="http://ode/bpel/unit-test.wsdl" use="literal"/>
+            </wsdl:input>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:service name="HeaderTestService">
+        <wsdl:port name="HeaderTestPort" binding="tns:HeaderTestSoapBinding">
+            <soap:address location="http://localhost:8888/ode/processes/correlationMultiTest"/>
+        </wsdl:port>
+    </wsdl:service>
+
+    <plnk:partnerLinkType name="HeaderTestPartnerLinkType">
+        <plnk:role name="me" portType="tns:HeaderTestPortType"/>
+        <plnk:role name="you" portType="tns:HeaderTestPortType"/>
+    </plnk:partnerLinkType>
+    <plnk:partnerLinkType name="DummyPartnerLinkType">
+        <plnk:role name="you" portType="dummy:DummyServicePortType"/>
+    </plnk:partnerLinkType>
+
+    <prop:property name="testCorrelationID1" type="xsd:string"/>
+    <prop:propertyAlias propertyName="tns:testCorrelationID1" messageType="tns:HeaderTestMessage" part="TestPart">
+        <prop:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0">
+            correlationID1
+        </prop:query>
+    </prop:propertyAlias>
+
+    <prop:property name="testCorrelationID2" type="xsd:string"/>
+    <prop:propertyAlias propertyName="tns:testCorrelationID2" messageType="tns:HeaderTestMessage" part="TestPart">
+        <prop:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0">
+            correlationID2
+        </prop:query>
+    </prop:propertyAlias>
+
+    <prop:property name="testCorrelationID3" type="xsd:string"/>
+    <prop:propertyAlias propertyName="tns:testCorrelationID3" messageType="tns:HeaderTestMessage" part="TestPart">
+        <prop:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0">
+            correlationID3
+        </prop:query>
+    </prop:propertyAlias>
+
+    <prop:property name="testCorrelationID4" type="xsd:string"/>
+    <prop:propertyAlias propertyName="tns:testCorrelationID4" messageType="tns:HeaderTestMessage" part="TestPart">
+        <prop:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0">
+            correlationID4
+        </prop:query>
+    </prop:propertyAlias>
+</wsdl:definitions>
\ No newline at end of file

Added: ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/deploy.xml
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/deploy.xml?rev=719270&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/deploy.xml (added)
+++ ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/deploy.xml Thu Nov 20 08:26:25 2008
@@ -0,0 +1,33 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<deploy xmlns="http://www.apache.org/ode/schemas/dd/2007/03"
+	xmlns:pns="http://ode/bpel/unit-test" 
+	xmlns:wns="http://ode/bpel/unit-test.wsdl" xmlns:dns="http://axis2.ode.apache.org">
+
+
+	<process name="pns:HeaderTest">
+		<active>true</active>
+		<provide partnerLink="helloPartnerLink">
+			<service name="wns:HeaderTestService" port="HeaderTestPort"/>
+		</provide>
+        <invoke partnerLink="dummyPartnerLink">
+            <service name="dns:DummyService" port="DummyServiceSOAP11port_http"/>
+        </invoke>
+    </process>
+</deploy>

Added: ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/dummy-service.wsdl
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/dummy-service.wsdl?rev=719270&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/dummy-service.wsdl (added)
+++ ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/dummy-service.wsdl Thu Nov 20 08:26:25 2008
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+                  xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
+                  xmlns:ns0="http://axis2.ode.apache.org/xsd"
+                  xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
+                  xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
+                  xmlns:ns1="http://axis2.ode.apache.org"
+                  xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
+                  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+                  targetNamespace="http://axis2.ode.apache.org">
+   <wsdl:types>
+      <xs:schema xmlns:ns="http://axis2.ode.apache.org" attributeFormDefault="qualified"
+                 elementFormDefault="unqualified" targetNamespace="http://axis2.ode.apache.org">
+
+         <xs:element name="DummyException">
+            <xs:complexType>
+               <xs:sequence>
+                   <xs:element minOccurs="0" name="reason" nillable="true" type="xs:string"/>
+               </xs:sequence>
+            </xs:complexType>
+         </xs:element>
+         <xs:element name="faultTest">
+            <xs:complexType>
+               <xs:sequence>
+                  <xs:element minOccurs="0" name="in" nillable="true" type="xs:string"/>
+               </xs:sequence>
+            </xs:complexType>
+         </xs:element>
+         <xs:element name="faultTestResponse">
+            <xs:complexType>
+               <xs:sequence>
+                  <xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/>
+               </xs:sequence>
+            </xs:complexType>
+         </xs:element>
+         <xs:element name="hello">
+            <xs:complexType>
+               <xs:sequence>
+                  <xs:element minOccurs="0" name="in" nillable="true" type="xs:string"/>
+               </xs:sequence>
+            </xs:complexType>
+         </xs:element>
+         <xs:element name="helloResponse">
+            <xs:complexType>
+               <xs:sequence>
+                  <xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/>
+               </xs:sequence>
+            </xs:complexType>
+         </xs:element>
+         <xs:element name="longOperation">
+            <xs:complexType>
+               <xs:sequence>
+                  <xs:element minOccurs="0" name="in" nillable="true" type="xs:string"/>
+               </xs:sequence>
+            </xs:complexType>
+         </xs:element>
+         <xs:element name="longOperationResponse">
+            <xs:complexType>
+               <xs:sequence>
+                  <xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/>
+               </xs:sequence>
+            </xs:complexType>
+         </xs:element>
+      </xs:schema>
+   </wsdl:types>
+   <wsdl:message name="faultTestRequest">
+      <wsdl:part name="parameters" element="ns1:faultTest"/>
+   </wsdl:message>
+   <wsdl:message name="faultTestResponse">
+      <wsdl:part name="parameters" element="ns1:faultTestResponse"/>
+   </wsdl:message>
+   <wsdl:message name="DummyExceptionType">
+      <wsdl:part name="parameters" element="ns1:DummyException"/>
+   </wsdl:message>
+   <wsdl:message name="helloRequest">
+      <wsdl:part name="parameters" element="ns1:hello"/>
+   </wsdl:message>
+   <wsdl:message name="helloResponse">
+      <wsdl:part name="parameters" element="ns1:helloResponse"/>
+   </wsdl:message>
+   <wsdl:message name="longOperationRequest">
+      <wsdl:part name="parameters" element="ns1:longOperation"/>
+   </wsdl:message>
+   <wsdl:message name="longOperationResponse">
+      <wsdl:part name="parameters" element="ns1:longOperationResponse"/>
+   </wsdl:message>
+   <wsdl:portType name="DummyServicePortType">
+      <wsdl:operation name="faultTest">
+         <wsdl:input message="ns1:faultTestRequest" wsaw:Action="urn:faultTest"/>
+         <wsdl:output message="ns1:faultTestResponse" wsaw:Action="urn:faultTestResponse"/>
+         <wsdl:fault message="ns1:DummyExceptionType" name="DummyException"
+                     wsaw:Action="urn:faultTestDummyException"/>
+      </wsdl:operation>
+      <wsdl:operation name="hello">
+         <wsdl:input message="ns1:helloRequest" wsaw:Action="urn:hello"/>
+         <wsdl:output message="ns1:helloResponse" wsaw:Action="urn:helloResponse"/>
+      </wsdl:operation>
+      <wsdl:operation name="longOperation">
+         <wsdl:input message="ns1:longOperationRequest" wsaw:Action="urn:longOperation"/>
+         <wsdl:output message="ns1:longOperationResponse" wsaw:Action="urn:longOperationResponse"/>
+      </wsdl:operation>
+   </wsdl:portType>
+   <wsdl:binding name="DummyServiceSOAP11Binding" type="ns1:DummyServicePortType">
+      <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
+      <wsdl:operation name="faultTest">
+         <soap:operation soapAction="urn:faultTest" style="document"/>
+         <wsdl:input>
+            <soap:body use="literal"/>
+         </wsdl:input>
+         <wsdl:output>
+            <soap:body use="literal"/>
+         </wsdl:output>
+         <wsdl:fault name="DummyException">
+            <soap:fault use="literal" name="DummyException"/>
+         </wsdl:fault>
+      </wsdl:operation>
+      <wsdl:operation name="hello">
+         <soap:operation soapAction="urn:hello" style="document"/>
+         <wsdl:input>
+            <soap:body use="literal"/>
+         </wsdl:input>
+         <wsdl:output>
+            <soap:body use="literal"/>
+         </wsdl:output>
+      </wsdl:operation>
+      <wsdl:operation name="longOperation">
+         <soap:operation soapAction="urn:longOperation" style="document"/>
+         <wsdl:input>
+            <soap:body use="literal"/>
+         </wsdl:input>
+         <wsdl:output>
+            <soap:body use="literal"/>
+         </wsdl:output>
+      </wsdl:operation>
+   </wsdl:binding>
+   <wsdl:binding name="DummyServiceSOAP12Binding" type="ns1:DummyServicePortType">
+      <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
+      <wsdl:operation name="faultTest">
+         <soap12:operation soapAction="urn:faultTest" style="document"/>
+         <wsdl:input>
+            <soap12:body use="literal"/>
+         </wsdl:input>
+         <wsdl:output>
+            <soap12:body use="literal"/>
+         </wsdl:output>
+         <wsdl:fault name="DummyException">
+            <soap12:fault use="literal" name="DummyException"/>
+         </wsdl:fault>
+      </wsdl:operation>
+      <wsdl:operation name="hello">
+         <soap12:operation soapAction="urn:hello" style="document"/>
+         <wsdl:input>
+            <soap12:body use="literal"/>
+         </wsdl:input>
+         <wsdl:output>
+            <soap12:body use="literal"/>
+         </wsdl:output>
+      </wsdl:operation>
+      <wsdl:operation name="longOperation">
+         <soap12:operation soapAction="urn:hello" style="document"/>
+         <wsdl:input>
+            <soap12:body use="literal"/>
+         </wsdl:input>
+         <wsdl:output>
+            <soap12:body use="literal"/>
+         </wsdl:output>
+      </wsdl:operation>
+   </wsdl:binding>
+   <wsdl:binding name="DummyServiceHttpBinding" type="ns1:DummyServicePortType">
+      <http:binding verb="POST"/>
+      <wsdl:operation name="faultTest">
+         <http:operation location="DummyService/faultTest"/>
+         <wsdl:input>
+            <mime:content type="text/xml" part="faultTest"/>
+         </wsdl:input>
+         <wsdl:output>
+            <mime:content type="text/xml" part="faultTest"/>
+         </wsdl:output>
+      </wsdl:operation>
+      <wsdl:operation name="hello">
+         <http:operation location="DummyService/hello"/>
+         <wsdl:input>
+            <mime:content type="text/xml" part="hello"/>
+         </wsdl:input>
+         <wsdl:output>
+            <mime:content type="text/xml" part="hello"/>
+         </wsdl:output>
+      </wsdl:operation>
+      <wsdl:operation name="longOperation">
+         <http:operation location="DummyService/hello"/>
+         <wsdl:input>
+            <mime:content type="text/xml" part="hello"/>
+         </wsdl:input>
+         <wsdl:output>
+            <mime:content type="text/xml" part="hello"/>
+         </wsdl:output>
+      </wsdl:operation>
+   </wsdl:binding>
+   <wsdl:service name="DummyService">
+      <wsdl:port name="DummyServiceSOAP11port_http" binding="ns1:DummyServiceSOAP11Binding">
+         <soap:address location="http://localhost:8888/processes/DummyService"/>
+      </wsdl:port>
+      <wsdl:port name="DummyServiceSOAP12port_http" binding="ns1:DummyServiceSOAP12Binding">
+         <soap12:address location="http://localhost:8888/processes/DummyService"/>
+      </wsdl:port>
+      <wsdl:port name="DummyServiceHttpport" binding="ns1:DummyServiceHttpBinding">
+         <http:address location="http://localhost:8888/processes/DummyService"/>
+      </wsdl:port>
+   </wsdl:service>
+</wsdl:definitions>
\ No newline at end of file

Added: ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/testRequest.soap
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/testRequest.soap?rev=719270&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/testRequest.soap (added)
+++ ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/testRequest.soap Thu Nov 20 08:26:25 2008
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
+    <SOAP-ENV:Header>
+        <myns:ConversationId xmlns:myns="http://my.company/super/protocol">ZZZXYZ</myns:ConversationId>
+    </SOAP-ENV:Header>
+    <!-- test soap message -->
+    <SOAP-ENV:Body>
+        <ns1:hello xmlns:ns1="http://ode/bpel/unit-test.wsdl">
+            <TestPart xmlns=""><correlationID1>CORR1</correlationID1><correlationID2>CORR2</correlationID2><correlationID3>CORR3</correlationID3><correlationID4>CORR4</correlationID4><requestText>1;</requestText></TestPart>
+        </ns1:hello>
+    </SOAP-ENV:Body>
+</SOAP-ENV:Envelope>

Added: ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/testRequest2.soap
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/testRequest2.soap?rev=719270&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/testRequest2.soap (added)
+++ ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestCorrelationMulti/testRequest2.soap Thu Nov 20 08:26:25 2008
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
+    <SOAP-ENV:Header>
+        <myns:ConversationId xmlns:myns="http://my.company/super/protocol">ZZZXYZ</myns:ConversationId>
+    </SOAP-ENV:Header>
+    <!-- test soap message -->
+    <SOAP-ENV:Body>
+        <ns1:continue xmlns:ns1="http://ode/bpel/unit-test.wsdl">
+            <TestPart xmlns=""><correlationID1>CORR1</correlationID1><correlationID2>CORR2</correlationID2><correlationID3>CORR3</correlationID3><correlationID4>CORR4</correlationID4><requestText>2;</requestText></TestPart>
+        </ns1:continue>
+    </SOAP-ENV:Body>
+</SOAP-ENV:Envelope>

Modified: ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKey.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKey.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKey.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKey.java Thu Nov 20 08:26:25 2008
@@ -157,14 +157,6 @@
         return hashCode;
     }
 
-    public List<String> toCanonicalList() {
-        ArrayList<String> ret = new ArrayList<String>(_keyValues.length + 1);
-        ret.add(((Integer) _csetId).toString());
-        for (String i : _keyValues)
-            ret.add(i);
-        return ret;
-    }
-
     /**
      * @see Object#toString
      */

Added: ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKeySet.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKeySet.java?rev=719270&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKeySet.java (added)
+++ ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKeySet.java Thu Nov 20 08:26:25 2008
@@ -0,0 +1,358 @@
+package org.apache.ode.bpel.common;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * This class implements a set of correlation keys.
+ * 
+ * The example of canonical forms of correlation key sets are:
+ * 
+ *  <ul>
+ *  <li>@2</li>
+ *  <li>@2[12~a~b]</li>
+ *  <li>@2[12~a~b],[25~b~c]</li>
+ *  </ul>
+ *  
+ *  The first example shows an empty correlation key set. The second shows a set with one correlation key inside.
+ *  The third shows a set with two keys inside. The correlation keys are sorted by the correlation set ids.
+ *  
+ * @author sean
+ *
+ */
+public class CorrelationKeySet implements Serializable {
+	private static final long serialVersionUID = 1L;
+	
+	public final static String VERSION_1 = "1";
+	public final static String VERSION_2 = "2";
+
+	@SuppressWarnings("unused")
+	private String version = VERSION_2;
+	
+	private final Set<CorrelationKey> correlationKeys = new TreeSet<CorrelationKey>(new CorrelationKeyComparator());
+	
+	/**
+	 * Default Constructor
+	 */
+	public CorrelationKeySet() {
+	}
+	
+	/**
+	 * Restores the state by parsing the given canonical form of correlation key set.
+	 * 
+	 * @param canonicalForm canonical form of correlation key set
+	 */
+	public CorrelationKeySet(String canonicalForm) {
+		restore(canonicalForm);
+	}
+	
+	/**
+	 * Adds a correlation key to this correlation key set. If a correlation key with the same correlation set id
+	 * already exists, the old one is replaced with the given new one.
+	 * 
+	 * @param ck a correlation key to add
+	 * @return returns this correlation key set
+	 */
+	public CorrelationKeySet add(CorrelationKey ck) {
+		for( CorrelationKey key : correlationKeys ) {
+			if( key.getCSetId() == ck.getCSetId() ) {
+				correlationKeys.remove(ck);
+				break;
+			}
+		}
+		correlationKeys.add(ck);
+		
+		return this;
+	}
+	
+	/**
+	 * Checks if this correlation key set contains the opaque correlation key as the only key 
+	 * in this correlation key set.
+	 * 
+	 * @return returns true if the correlation key set is opaque
+	 */
+	public boolean isOpaque() {
+		return correlationKeys.size() == 1 && correlationKeys.iterator().next().getCSetId() == -1;
+	}
+
+	/**
+	 * Checks if an incoming message with this correlation key set can be accepted by the given 
+	 * correlation key set.
+	 * 
+	 * @param candidateKeySet a correlation key set stored in a route
+	 * @param isAllRoute use true if the route="all" is set
+	 * @return return true if routable
+	 */
+	public boolean isRoutableTo(CorrelationKeySet candidateKeySet, boolean isAllRoute) {
+		boolean isRoutable = containsAll(candidateKeySet);
+		
+		if( isAllRoute ) {
+			isRoutable = isRoutable || candidateKeySet.isOpaque() && isEmpty();
+		}
+		
+		return isRoutable;
+	}
+	
+	/**
+	 * Checks if this correlation key set contains all correlation keys from the given correlation key set.
+	 * 
+	 * @param c a correlation key set
+	 * @return return true if this correlation key set is a superset
+	 */
+    public boolean containsAll(CorrelationKeySet c) {
+		Iterator<CorrelationKey> e = c.iterator();
+		while (e.hasNext())
+			if (!contains(e.next()))
+				return false;
+		return true;
+	}
+	
+    /**
+     * Returns true if this correlation key set contains no correlation keys.
+     * 
+     * @return returns true if empty
+     */
+    public boolean isEmpty() {
+    	return correlationKeys.isEmpty();
+    }
+    
+    /**
+     * Returns true if this correlation key set contains the give correlation key.
+     * 
+     * @param correlationKey a correlation key
+     * @return 
+     */
+    public boolean contains(CorrelationKey correlationKey) {
+		Iterator<CorrelationKey> e = correlationKeys.iterator();
+		if (correlationKey == null) {
+			while (e.hasNext())
+				if (e.next() == null)
+					return true;
+		} else {
+			while (e.hasNext()) {
+				if (correlationKey.equals(e.next()))
+					return true;
+			}
+		}
+		return false;
+	}
+	
+    /**
+     * Returns an iterator on the correlation keys that this correlation key set contains.
+     * 
+     * @return an iterator
+     */
+    public Iterator<CorrelationKey> iterator() {
+    	return correlationKeys.iterator();
+    }
+    
+    /**
+     * Removes all correlation keys in this correlation keys.
+     */
+    public void clear() {
+    	correlationKeys.clear();
+    }
+
+    @Override
+	public boolean equals(Object o) {
+		if( o == null || !(o instanceof CorrelationKeySet) ) {
+			return false;
+		}
+		CorrelationKeySet another = (CorrelationKeySet)o;
+		
+		if( correlationKeys.size() != another.correlationKeys.size() ) {
+			return false;
+		}
+
+		return containsAll(another);
+	}
+
+    /**
+     * Finds all subsets of this correlation key set.
+     * 
+     * @return a list of all subset correlation key sets
+     */
+    public List<CorrelationKeySet> findSubSets() {
+    	List<CorrelationKeySet> subSets = new ArrayList<CorrelationKeySet>();
+    	
+    	// split into two sets: with mandatory keys and with optional keys
+    	CorrelationKeySet mandatoryKeySet = new CorrelationKeySet();
+    	CorrelationKeySet optionalKeySet = new CorrelationKeySet();
+    	for( CorrelationKey ckey : correlationKeys ) {
+    		if( ckey instanceof OptionalCorrelationKey ) {
+    			optionalKeySet.add(ckey);
+    		} else {
+    			mandatoryKeySet.add(ckey);
+    		}
+    	}
+    	
+    	if( optionalKeySet.isEmpty() ) {
+    		// no optional keys found
+    		subSets.add(this);
+    	} else {
+    		// we are generating (2 powered by the number of correlation keys) number of sub-sets
+	    	for( int setIndex = 0; setIndex < Math.pow(2, optionalKeySet.correlationKeys.size()); setIndex++ ) {
+	    		CorrelationKeySet subKeySet = new CorrelationKeySet(); 
+	    		int bitPattern = setIndex; // the bitPattern will be 0b0000, 0b0001, 0b0010 and so on
+	    		Iterator<CorrelationKey> ckeys = optionalKeySet.iterator();
+	    		while( ckeys.hasNext() && bitPattern > 0 ) { // bitPattern > 0 condition saves half of the iterations
+	    			CorrelationKey ckey = ckeys.next();
+	    			if( (bitPattern & 0x01) > 0 ) {
+	    				subKeySet.add(ckey);
+	    			}
+	        		bitPattern = bitPattern >> 1;
+	    		}
+	    		// add the mandatory keys
+	    		subKeySet.correlationKeys.addAll(mandatoryKeySet.correlationKeys);
+	    		if(!subKeySet.isEmpty()) { // we don't want an empty set
+	    			subSets.add(subKeySet);
+	    		}
+	    	}
+    	}
+    	
+    	return subSets;
+    }
+
+    /**
+     * Returns a canonical form of this correlation key set.
+     * 
+     * @return
+     */
+    public String toCanonicalString() {
+        StringBuffer buf = new StringBuffer();
+        
+        for( CorrelationKey ckey : correlationKeys ) {
+        	if( buf.length() > 0 ) {
+        		buf.append(",");
+        	}
+	        buf.append("[").append(escapeRightBracket(ckey.toCanonicalString())).append("]");
+        }
+        
+        return "@" + VERSION_2 + buf.toString();
+    }
+    
+    private static String escapeRightBracket(String str) {
+        if (str == null)
+            return null;
+
+        StringBuffer buf = new StringBuffer();
+    	
+        char[] chars = str.toCharArray();
+        for (char achar : chars) {
+            if (achar == ']') {
+                buf.append("]]");
+            } else {
+                buf.append(achar);
+            }
+        }
+        
+        return buf.toString();
+    }
+
+    @Override
+    public String toString() {
+    	return correlationKeys.toString();
+    }
+
+    /**
+     * Restores the state of this correlation key set from a canonical form.
+     * 
+     * @param canonicalForm a canonical form of correlation key set
+     */
+	public void restore(String canonicalForm) {
+		if( canonicalForm == null || canonicalForm.trim().length() == 0 ) return;
+
+		if( canonicalForm.startsWith("@") ) {
+			parseCanonicalForm(canonicalForm);
+		} else {
+			version = VERSION_1;
+			add( new CorrelationKey(canonicalForm) );
+		}
+	}
+
+	private static enum ParserState {
+		INITIAL, MET_ALPHA, MET_LEFT_BRACKET, MET_RIGHT_BRACKET, MET_QUESTION, MET_COMMA
+	}
+
+	// parses a canonical form of correlation key set through an automata subsystem(FSM)
+	private void parseCanonicalForm(String canonicalForm) {
+		ParserState state = ParserState.INITIAL;
+
+		StringBuffer buf = new StringBuffer();
+		for( int i = 0; i < canonicalForm.length(); i++ ) {
+			char ch = canonicalForm.charAt(i);
+			if( state == ParserState.INITIAL ) {
+				if( ch == '@' ) {
+					state = ParserState.MET_ALPHA;
+				} else {
+					buf.append(ch);
+					state = ParserState.MET_LEFT_BRACKET;
+				}
+			} else if( state == ParserState.MET_ALPHA ) {
+				if( ch == '[' ) {
+					version = buf.toString();
+					buf.setLength(0);
+					state = ParserState.MET_LEFT_BRACKET;
+				} else {
+					buf.append(ch);
+				}
+			} else if( state == ParserState.MET_LEFT_BRACKET ) {
+				if( ch == ']' ) {
+					state = ParserState.MET_RIGHT_BRACKET;
+				} else {
+					buf.append(ch);
+				}
+			} else if( state == ParserState.MET_RIGHT_BRACKET ) {
+				if( ch == ']' ) {
+					buf.append(ch);
+					state = ParserState.MET_LEFT_BRACKET;
+				} else if( ch == ',' ) {
+					if( buf.toString().trim().length() != 0 ) {
+						add( new CorrelationKey(buf.toString()) );
+					}
+					buf.setLength(0);
+					state = ParserState.MET_COMMA;
+				} else if( ch == '?' ) { // this is only a convenient feature for testing
+					if( buf.toString().trim().length() != 0 ) {
+						add( new OptionalCorrelationKey(buf.toString()) );
+					}
+					buf.setLength(0);
+					state = ParserState.MET_COMMA;
+				}
+			} else if( state == ParserState.MET_QUESTION ) {
+				if( ch == ',' ) {
+					state = ParserState.MET_COMMA;
+				}
+			} else if( state == ParserState.MET_COMMA ) {
+				if( ch == '[' ) {
+					state = ParserState.MET_LEFT_BRACKET;
+				}
+			}
+		}
+		if( buf.toString().trim().length() != 0 ) {
+			if( state == ParserState.MET_ALPHA ) {
+				version = buf.toString();
+			} else {
+				add( new CorrelationKey(buf.toString()) );
+			}
+		}
+	}
+
+    private class CorrelationKeyComparator implements Serializable, Comparator<CorrelationKey> {
+		private static final long serialVersionUID = 1L;
+
+		public int compare(CorrelationKey o1, CorrelationKey o2) {
+			if( o1 == null || o2 == null ) {
+				return 0;
+			}
+			
+			// used only in sorting the correlation keys in the CorrelationKeySet; does not matter with the values
+			return o1.getCSetId() - o2.getCSetId();
+		}
+    }    
+}
\ No newline at end of file

Added: ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/OptionalCorrelationKey.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/OptionalCorrelationKey.java?rev=719270&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/OptionalCorrelationKey.java (added)
+++ ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/OptionalCorrelationKey.java Thu Nov 20 08:26:25 2008
@@ -0,0 +1,41 @@
+package org.apache.ode.bpel.common;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import org.apache.ode.utils.CollectionUtils;
+
+/**
+ * An instance of this class represents a correlation key that has a 'join' use case in the process definition.
+ * For instance, if a correlation set, 'orderId' is used as initiate="no" in 3 occurrences and initiate="join"
+ * in 1 occurrence, any correlation keys that are derived from the correlation set, 'orderId' is an 
+ * optional correlation key.
+ * 
+ * @author sean
+ *
+ */
+public class OptionalCorrelationKey extends CorrelationKey implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    public OptionalCorrelationKey(int csetId, String[] keyValues) {
+    	super(csetId, keyValues);
+    }
+
+    public OptionalCorrelationKey(String canonicalForm) {
+    	super(canonicalForm);
+    }
+
+    /**
+     * @see Object#toString
+     */
+    public String toString() {
+        StringBuffer buf = new StringBuffer("{OptionalCorrelationKey ");
+        buf.append("setId=");
+        buf.append(getCSetId());
+        buf.append(", values=");
+        buf.append(CollectionUtils.makeCollection(ArrayList.class, getValues()));
+        buf.append('}');
+
+        return buf.toString();
+    }
+}
\ No newline at end of file

Modified: ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/evt/CorrelationMatchEvent.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/evt/CorrelationMatchEvent.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/evt/CorrelationMatchEvent.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/evt/CorrelationMatchEvent.java Thu Nov 20 08:26:25 2008
@@ -19,6 +19,7 @@
 package org.apache.ode.bpel.evt;
 
 import org.apache.ode.bpel.common.CorrelationKey;
+import org.apache.ode.bpel.common.CorrelationKeySet;
 
 import javax.xml.namespace.QName;
 
@@ -26,25 +27,36 @@
  * Correlation matched a process instance on inbound message.
  */
 public class CorrelationMatchEvent extends ProcessMessageExchangeEvent {
-  private static final long serialVersionUID = 1L;
-  private CorrelationKey _correlationKey;
+	private static final long serialVersionUID = 1L;
 
-  public CorrelationMatchEvent(
-    QName processName, QName processId, Long processInstanceId, CorrelationKey correlationKey) {
-    super(PROCESS_INPUT, processName,processId,processInstanceId);
-    _correlationKey = correlationKey;
-  }
-
-	public CorrelationKey getCorrelationKey() {
-    return _correlationKey;
-  }
-
-  public void setCorrelationKey(CorrelationKey correlationKey) {
-    _correlationKey = correlationKey;
-  }
-
-  public TYPE getType() {
-    return TYPE.correlation;
-  }
-
-}
+	// left out for backward-compatibility
+	private CorrelationKey _correlationKey;
+	private CorrelationKeySet _correlationKeySet;
+
+	public CorrelationMatchEvent(QName processName, QName processId, Long processInstanceId, CorrelationKeySet correlationKeySet) {
+		super(PROCESS_INPUT, processName, processId, processInstanceId);
+		_correlationKeySet = correlationKeySet;
+	}
+
+	public CorrelationKeySet getCorrelationKeySet() {
+		// backward compatibility; add up
+		if (_correlationKey != null) {
+			if( _correlationKeySet == null ) {
+				_correlationKeySet = new CorrelationKeySet();
+			}
+			if(!_correlationKeySet.contains(_correlationKey)) {
+				_correlationKeySet.add(_correlationKey);
+			}
+		}
+		
+		return _correlationKeySet;
+	}
+
+	public void setCorrelationKey(CorrelationKeySet correlationKeySet) {
+		_correlationKeySet = correlationKeySet;
+	}
+
+	public TYPE getType() {
+		return TYPE.correlation;
+	}
+}
\ No newline at end of file

Modified: ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/evt/CorrelationNoMatchEvent.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/evt/CorrelationNoMatchEvent.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/evt/CorrelationNoMatchEvent.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/evt/CorrelationNoMatchEvent.java Thu Nov 20 08:26:25 2008
@@ -24,27 +24,42 @@
 import javax.xml.namespace.QName;
 
 import org.apache.ode.bpel.common.CorrelationKey;
+import org.apache.ode.bpel.common.CorrelationKeySet;
 
 /**
- * Message arrived and matched neither (a) createInstance or (b) correlation match
+ * Message arrived and matched neither (a) createInstance or (b) correlation
+ * match
  */
 public class CorrelationNoMatchEvent extends CorrelationEvent {
-  private static final long serialVersionUID = 1L;
-  private final HashSet<CorrelationKey> _keys = new HashSet<CorrelationKey>();
-  
-  public CorrelationNoMatchEvent(QName qName, String opName, String mexId, CorrelationKey[] keys) {
-    super(qName, opName, mexId);
-    for (CorrelationKey key:keys)
-      _keys.add(key);
-  }
-
-  public Set<CorrelationKey> getKeys() {
-    return _keys;
-  }
-  
-  public void setKeys(Set<CorrelationKey> keys) {
-    _keys.clear();
-    _keys.addAll(keys);
-  }
+	private static final long serialVersionUID = 1L;
+	
+	// left out for backward-compatibility
+	private final Set<CorrelationKey> _keys = new HashSet<CorrelationKey>();
+	private CorrelationKeySet _keySet = null;
+
+	public CorrelationNoMatchEvent(QName qName, String opName, String mexId,
+			CorrelationKeySet keySet) {
+		super(qName, opName, mexId);
+
+		_keySet = keySet;
+	}
+
+	public CorrelationKeySet getKeySet() {
+		// backward-compatibility; add up keys
+		if( _keys.size() > 0 && _keySet == null ) {
+			_keySet = new CorrelationKeySet();
+		}
+		for (CorrelationKey aKey : _keys) {
+			if (aKey != null && !_keySet.contains(aKey)) {
+				_keySet.add(aKey);
+			}
+		}
+		
+		return _keySet;
+	}
+
+	public void setKeys(CorrelationKeySet keySet) {
+		_keySet = keySet;
+	}
 
 }

Added: ode/branches/APACHE_ODE_1.X/bpel-api/src/test/java/org/apache/ode/bpel/common/CorrelationKeySetTest.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-api/src/test/java/org/apache/ode/bpel/common/CorrelationKeySetTest.java?rev=719270&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-api/src/test/java/org/apache/ode/bpel/common/CorrelationKeySetTest.java (added)
+++ ode/branches/APACHE_ODE_1.X/bpel-api/src/test/java/org/apache/ode/bpel/common/CorrelationKeySetTest.java Thu Nov 20 08:26:25 2008
@@ -0,0 +1,151 @@
+package org.apache.ode.bpel.common;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+public class CorrelationKeySetTest {
+	private CorrelationKey keyX = new CorrelationKey("1~a~b");
+	private CorrelationKey keyY = new CorrelationKey("2~b~c");
+	private CorrelationKey keyZ = new CorrelationKey("3~c~d");
+	private CorrelationKey optX = new OptionalCorrelationKey("1~a~b");
+	private CorrelationKey optY = new OptionalCorrelationKey("2~b~c");
+	private CorrelationKey optZ = new OptionalCorrelationKey("3~c~d");
+
+	@Test
+	public void testCanonicalString() throws Exception {
+		CorrelationKeySet setA = new CorrelationKeySet();
+		setA.add(keyX);
+		setA.add(optY);
+		assertEquals("@2[1~a~b],[2~b~c]", setA.toCanonicalString());
+	}
+	
+	@Test
+	public void testContainsAll() throws Exception {
+		CorrelationKeySet setA = new CorrelationKeySet();
+		CorrelationKeySet setB = new CorrelationKeySet();
+		assertTrue(setA.containsAll(setB));
+		
+		setA.add(keyX);
+		assertTrue(setA.containsAll(setB));
+
+		setB.add(keyY);
+		assertFalse(setA.containsAll(setB));
+
+		setA.clear();
+		setA.add(keyY);
+		assertTrue(setA.containsAll(setB));
+	}
+	
+	@Test
+	public void testRestoreFromCanonicalForm() throws Exception {
+		assertEquals(new CorrelationKeySet(null), new CorrelationKeySet());
+		assertEquals(new CorrelationKeySet(""), new CorrelationKeySet());
+		
+		assertEquals(new CorrelationKeySet("-1~session_key"), 
+				new CorrelationKeySet().add(new CorrelationKey(-1, new String[] {"session_key"})));
+		assertEquals(new CorrelationKeySet("1~key1~key2"), 
+				new CorrelationKeySet().add(new CorrelationKey(1, new String[] {"key1", "key2"})));
+
+		assertEquals(new CorrelationKeySet("@2"), new CorrelationKeySet());
+		assertEquals(new CorrelationKeySet("@2[-1~session_key]"), 
+				new CorrelationKeySet().add(new CorrelationKey(-1, new String[] {"session_key"})));
+		assertEquals(new CorrelationKeySet("@2[1~key1~key2]"), 
+				new CorrelationKeySet().add(new CorrelationKey(1, new String[] {"key1", "key2"})));
+		assertEquals(new CorrelationKeySet("@2[1~key1],[2~key2~key3]"), 
+				new CorrelationKeySet().add(new CorrelationKey(1, new String[] {"key1"}))
+				.add(new CorrelationKey(2, new String[] {"key2", "key3"})));
+		assertEquals(new CorrelationKeySet("@2[1~key1],[2~key2~key3]?"), 
+				new CorrelationKeySet().add(new CorrelationKey(1, new String[] {"key1"}))
+				.add(new CorrelationKey(2, new String[] {"key2", "key3"})));
+		assertEquals(2, new CorrelationKeySet("@2[1~key1],[2~key2~key3]?").findSubSets().size());
+	}
+	
+	@Test
+	public void testRoutableTo() throws Exception {
+		CorrelationKeySet setA = new CorrelationKeySet();
+		CorrelationKeySet setB = new CorrelationKeySet();
+		assertTrue(setA.isRoutableTo(setB, false));
+		assertTrue(setA.isRoutableTo(setB, true));
+		
+		setA.add(keyX);
+		assertTrue(setA.isRoutableTo(setB, false));
+		assertTrue(setA.isRoutableTo(setB, true));
+
+		setB.add(keyY);
+		assertFalse(setA.isRoutableTo(setB, false));
+		assertFalse(setA.isRoutableTo(setB, true));
+
+		setA.clear();
+		setA.add(keyY);
+		assertTrue(setA.isRoutableTo(setB, false));
+		assertTrue(setA.isRoutableTo(setB, true));
+		
+		CorrelationKeySet inbound = new CorrelationKeySet();
+		CorrelationKeySet candidate = new CorrelationKeySet();
+		candidate.add(new CorrelationKey("-1~session_key"));
+		assertFalse(inbound.isRoutableTo(candidate, false));
+		assertTrue(inbound.isRoutableTo(candidate, true));
+
+		inbound.add(new CorrelationKey("-1~session_key_different"));
+		assertFalse(inbound.isRoutableTo(candidate, false));
+		assertFalse(inbound.isRoutableTo(candidate, true));
+	}
+	
+	@Test
+	public void testFindSubSets() throws Exception {
+		StringBuffer buf = new StringBuffer();
+		for( CorrelationKeySet subSet : new CorrelationKeySet().findSubSets() ) {
+			if( buf.length() > 0 ) {
+				buf.append(",");
+			}
+			buf.append("'").append(subSet.toCanonicalString()).append("'");
+		}
+		assertEquals("'@2'",  buf.toString());
+
+		CorrelationKeySet keySet = new CorrelationKeySet();
+		keySet.add(keyX);
+		keySet.add(keyY);
+		keySet.add(keyZ);
+		assertTrue(keySet.findSubSets().size() == 1 && keySet.findSubSets().get(0).equals(keySet));
+
+		keySet = new CorrelationKeySet();		
+		keySet.add(optX);
+		keySet.add(optY);
+		keySet.add(optZ);
+		buf = new StringBuffer();
+		for( CorrelationKeySet subSet : keySet.findSubSets() ) {
+			if( buf.length() > 0 ) {
+				buf.append(",");
+			}
+			buf.append("'").append(subSet.toCanonicalString()).append("'");
+		}
+		assertEquals("'@2[1~a~b]','@2[2~b~c]','@2[1~a~b],[2~b~c]','@2[3~c~d]','@2[1~a~b],[3~c~d]','@2[2~b~c],[3~c~d]','@2[1~a~b],[2~b~c],[3~c~d]'", 
+			buf.toString());
+
+		keySet = new CorrelationKeySet();		
+		keySet.add(keyX);
+		keySet.add(keyY);
+		keySet.add(optZ);
+		buf = new StringBuffer();
+		for( CorrelationKeySet subSet : keySet.findSubSets() ) {
+			if( buf.length() > 0 ) {
+				buf.append(",");
+			}
+			buf.append("'").append(subSet.toCanonicalString()).append("'");
+		}
+		assertEquals("'@2[1~a~b],[2~b~c]','@2[1~a~b],[2~b~c],[3~c~d]'", buf.toString());
+
+		keySet = new CorrelationKeySet();		
+		keySet.add(keyX);
+		keySet.add(optY);
+		keySet.add(optZ);
+		buf = new StringBuffer();
+		for( CorrelationKeySet subSet : keySet.findSubSets() ) {
+			if( buf.length() > 0 ) {
+				buf.append(",");
+			}
+			buf.append("'").append(subSet.toCanonicalString()).append("'");
+		}
+		assertEquals("'@2[1~a~b]','@2[1~a~b],[2~b~c]','@2[1~a~b],[3~c~d]','@2[1~a~b],[2~b~c],[3~c~d]'", buf.toString());
+	}
+}
\ No newline at end of file

Modified: ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java Thu Nov 20 08:26:25 2008
@@ -27,9 +27,11 @@
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.Stack;
 
 import javax.wsdl.Definition;
@@ -175,7 +177,7 @@
     private Map<QName, Node> _customProcessProperties;
 
     private URI _processURI;
-
+    
     BpelCompiler(WSDLFactory4BPEL wsdlFactory) {
         _wsdlFactory = wsdlFactory;
         _wsdlRegistry = new WSDLRegistry(this);
@@ -1280,23 +1282,28 @@
                     throw new CompilationException(__cmsgs.errPortTypeMismatch(onEvent.getPortType(),
                             oevent.partnerLink.myRolePortType.getQName()));
 
+                Set<String> csetNames = new HashSet<String>(); // prevents duplicate cset in on one set of correlations
                 for (Correlation correlation : onEvent.getCorrelations()) {
-                    OScope.CorrelationSet cset = resolveCorrelationSet(correlation.getCorrelationSet());
+                	if( csetNames.contains(correlation.getCorrelationSet() ) ) {
+                        throw new CompilationException(__cmsgs.errDuplicateUseCorrelationSet(correlation
+                                .getCorrelationSet()));
+                	}
+
+                	OScope.CorrelationSet cset = resolveCorrelationSet(correlation.getCorrelationSet());
 
                     switch (correlation.getInitiate()) {
                     case UNSET:
                     case NO:
-                        if (oevent.matchCorrelation != null)
-                            throw new CompilationException(__cmsgs.errTODO("Matching multiple correlations sets."));
-                        oevent.matchCorrelation = cset;
-                        oevent.partnerLink.addCorrelationSetForOperation(oevent.operation, cset);
+                        oevent.matchCorrelations.add(cset);
+                        oevent.partnerLink.addCorrelationSetForOperation(oevent.operation, cset, false);
                         break;
                     case YES:
                         oevent.initCorrelations.add(cset);
                         break;
                     case JOIN:
-                        oevent.joinCorrelation = cset;
-                        oevent.partnerLink.addCorrelationSetForOperation(oevent.operation, cset);
+                    	cset.hasJoinUseCases = true;
+                        oevent.joinCorrelations.add(cset);
+                        oevent.partnerLink.addCorrelationSetForOperation(oevent.operation, cset, true);
                     }
 
                     for (OProcess.OProperty property : cset.properties) {
@@ -1305,8 +1312,9 @@
                         resolvePropertyAlias(oevent.variable, property.name);
                     }
 
+                    csetNames.add(correlation.getCorrelationSet());
                 }
-
+                
                 if (onEvent.getActivity() == null) throw new CompilationException(__cmsgs.errInvalidAlarm().setSource(onEvent));
                 oevent.activity = compile(onEvent.getActivity());
             }
@@ -1329,7 +1337,7 @@
 
         oscope.eventHandler.onMessages.add(oevent);
     }
-
+    
     private DebugInfo createDebugInfo(BpelObject bpelObject, String description) {
         int lineNo = bpelObject == null ? -1 : bpelObject.getLineNo();
         String str = description == null && bpelObject != null ? bpelObject.toString() : null;

Modified: ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/CommonCompilationMessages.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/CommonCompilationMessages.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/CommonCompilationMessages.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/CommonCompilationMessages.java Thu Nov 20 08:26:25 2008
@@ -108,6 +108,12 @@
             "Attempt to reference undeclared correlation set \"{0}\".", csetName);
     }
 
+    /** Attempt to reference undeclared correlation set "{0}". */
+    public CompilationMessage errDuplicateUseCorrelationSet(String csetName) {
+        return this.formatCompilationMessage(
+            "Attempt to use a correlation set \"{0}\" more than once for a set of correlations.", csetName);
+    }
+
     /**
      * Cannot use non-message variable "{0}" in this context (message variable is
      * required).

Modified: ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/InvokeGenerator.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/InvokeGenerator.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/InvokeGenerator.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/InvokeGenerator.java Thu Nov 20 08:26:25 2008
@@ -34,12 +34,15 @@
 import javax.wsdl.OperationType;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Generates code for <code>&lt;invoke&gt;</code> activities.
  */
 class InvokeGenerator extends DefaultActivityGenerator {
+    private static final CommonCompilationMessages __cmsgsGeneral = MessageBundle.getMessages(CommonCompilationMessages.class);
 
     private static final InvokeGeneratorMessages __imsgs = MessageBundle.getMessages(InvokeGeneratorMessages.class);
 
@@ -122,8 +125,14 @@
             Collection<OScope.CorrelationSet> assertCorrelations, 
             Collection<OScope.CorrelationSet> initCorrelations,
             Collection<OScope.CorrelationSet> joinCorrelations) {
+        Set<String> csetNames = new HashSet<String>(); // prevents duplicate cset in on one set of correlations
         for (Correlation correlation : correlations) {
-            OScope.CorrelationSet cset = _context.resolveCorrelationSet(correlation.getCorrelationSet());
+        	if( csetNames.contains(correlation.getCorrelationSet() ) ) {
+                throw new CompilationException(__cmsgsGeneral.errDuplicateUseCorrelationSet(correlation
+                        .getCorrelationSet()));
+        	}
+
+        	OScope.CorrelationSet cset = _context.resolveCorrelationSet(correlation.getCorrelationSet());
             switch (correlation.getInitiate()) {
             case NO:
                 assertCorrelations.add(cset);
@@ -132,6 +141,7 @@
                 initCorrelations.add(cset);
                 break;
             case JOIN:
+            	cset.hasJoinUseCases = true;
                 joinCorrelations.add(cset);
             }
             for (OProcess.OProperty property : cset.properties) {
@@ -147,6 +157,7 @@
                 }
                 // onMessage.
             }
+            csetNames.add(correlation.getCorrelationSet());
         }
     }
 }

Modified: ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/PickReceiveGenerator.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/PickReceiveGenerator.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/PickReceiveGenerator.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/PickReceiveGenerator.java Thu Nov 20 08:26:25 2008
@@ -29,6 +29,8 @@
 
 import javax.xml.namespace.QName;
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * Base class for the {@link PickGenerator} and {@link ReceiveGenerator}
@@ -81,7 +83,13 @@
         if (createInstance)
             onMessage.partnerLink.addCreateInstanceOperation(onMessage.operation);
 
+        Set<String> csetNames = new HashSet<String>(); // prevents duplicate cset in on one set of correlations
         for (Correlation correlation : correlations) {
+        	if( csetNames.contains(correlation.getCorrelationSet() ) ) {
+                throw new CompilationException(__cmsgsGeneral.errDuplicateUseCorrelationSet(correlation
+                        .getCorrelationSet()));
+        	}
+        	
             OScope.CorrelationSet cset = _context.resolveCorrelationSet(correlation.getCorrelationSet());
 
             switch (correlation.getInitiate()) {
@@ -90,22 +98,16 @@
                 if (createInstance)
                     throw new CompilationException(__cmsgsGeneral.errUseOfUninitializedCorrelationSet(correlation
                             .getCorrelationSet()));
-                if (onMessage.matchCorrelation != null || onMessage.joinCorrelation != null)
-                    throw new CompilationException(__cmsgs.errSecondNonInitiateOrJoinCorrelationSet(correlation
-                            .getCorrelationSet()));
-                onMessage.matchCorrelation = cset;
-                onMessage.partnerLink.addCorrelationSetForOperation(onMessage.operation, cset);
+                onMessage.matchCorrelations.add(cset);
+                onMessage.partnerLink.addCorrelationSetForOperation(onMessage.operation, cset, false);
                 break;
             case YES:
                 onMessage.initCorrelations.add(cset);
-                onMessage.partnerLink.addCorrelationSetForOperation(onMessage.operation, cset);
                 break;
             case JOIN:
-                if (onMessage.matchCorrelation != null || onMessage.joinCorrelation != null)
-                    throw new CompilationException(__cmsgs.errSecondNonInitiateOrJoinCorrelationSet(correlation
-                            .getCorrelationSet()));
-            	onMessage.joinCorrelation = cset;
-                onMessage.partnerLink.addCorrelationSetForOperation(onMessage.operation, cset);
+            	cset.hasJoinUseCases = true;
+            	onMessage.joinCorrelations.add(cset);
+                onMessage.partnerLink.addCorrelationSetForOperation(onMessage.operation, cset, true);
                 break;
 
             default:
@@ -117,6 +119,8 @@
                 // this variable-property pair.
                 _context.resolvePropertyAlias(onMessage.variable, property.name);
             }
+
+            csetNames.add(correlation.getCorrelationSet());
         }
 
         if (!onMessage.partnerLink.hasMyRole()) {

Modified: ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ReplyGenerator.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ReplyGenerator.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ReplyGenerator.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ReplyGenerator.java Thu Nov 20 08:26:25 2008
@@ -29,7 +29,10 @@
 import org.apache.ode.utils.msg.MessageBundle;
 
 import javax.wsdl.Fault;
+
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Set;
 
 
 /**
@@ -87,8 +90,14 @@
                 throw new CompilationException(_cmsgsGeneral.errVariableTypeMismatch(oreply.variable.name, oreply.operation.getOutput().getMessage().getQName(),((OMessageVarType)oreply.variable.type).messageType));
         }
 
+        Set<String> csetNames = new HashSet<String>(); // prevents duplicate cset in on one set of correlations
         for (Correlation correlation  : replyDef.getCorrelations()) {
-            OScope.CorrelationSet cset = _context.resolveCorrelationSet(correlation.getCorrelationSet());
+        	if( csetNames.contains(correlation.getCorrelationSet() ) ) {
+                throw new CompilationException(_cmsgsGeneral.errDuplicateUseCorrelationSet(correlation
+                        .getCorrelationSet()));
+        	}
+
+        	OScope.CorrelationSet cset = _context.resolveCorrelationSet(correlation.getCorrelationSet());
 
             switch (correlation.getInitiate()) {
                 case UNSET:
@@ -99,6 +108,7 @@
                     oreply.initCorrelations.add(cset);
                     break;
                 case JOIN:
+                	cset.hasJoinUseCases = true;
                 	oreply.joinCorrelations.add(cset);
                 	break;
                 default:
@@ -111,6 +121,8 @@
                 // Force resolution of alias, to make sure that we have one for this variable-property pair.
                 _context.resolvePropertyAlias(oreply.variable, property.name);
             }
+
+            csetNames.add(correlation.getCorrelationSet());
         }
     }
 }

Modified: ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/CorrelatorDAO.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/CorrelatorDAO.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/CorrelatorDAO.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/CorrelatorDAO.java Thu Nov 20 08:26:25 2008
@@ -20,7 +20,7 @@
 
 import java.util.List;
 
-import org.apache.ode.bpel.common.CorrelationKey;
+import org.apache.ode.bpel.common.CorrelationKeySet;
 
 /**
  * <p>
@@ -60,7 +60,7 @@
    * @param mex message exchange
    * @param correlationKeys pre-computed set of correlation keys for this message
    */
-  void enqueueMessage(MessageExchangeDAO mex, CorrelationKey[] correlationKeys);
+  void enqueueMessage(MessageExchangeDAO mex, CorrelationKeySet correlationKeySet);
 
 
   /**
@@ -70,14 +70,14 @@
    * @return opaque message-related data previously enqueued with the
    *         given correlation correlationKey
    */
-  MessageExchangeDAO dequeueMessage(CorrelationKey correlationKey);
+  MessageExchangeDAO dequeueMessage(CorrelationKeySet correlationKeySet);
 
   /**
    * Find a route matching the given correlation key.
    * @param correlationKey correlation key
    * @return route matching the given correlation key
    */
-  List<MessageRouteDAO> findRoute(CorrelationKey correlationKey);
+  List<MessageRouteDAO> findRoute(CorrelationKeySet correlationKeySet);
 
   /**
    * Add a route from the given correlation key to the given process instance.
@@ -86,7 +86,7 @@
    * @param index relative order in which the route should be considered
    * @param correlationKey correlation key to match
    */
-  void addRoute(String routeGroupId, ProcessInstanceDAO target, int index, CorrelationKey correlationKey, String routePolicy);
+  void addRoute(String routeGroupId, ProcessInstanceDAO target, int index, CorrelationKeySet correlationKeySet, String routePolicy);
 
   /**
    * Remove all routes with the given route-group identifier.

Modified: ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/MessageRouteDAO.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/MessageRouteDAO.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/MessageRouteDAO.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/MessageRouteDAO.java Thu Nov 20 08:26:25 2008
@@ -18,6 +18,8 @@
  */
 package org.apache.ode.bpel.dao;
 
+import org.apache.ode.bpel.common.CorrelationKeySet;
+
 /**
  * Data access object representing a message consumer. A message consumer
  * represents an unsatisfied BPEL <code>pick</code> or <code>receive</code>
@@ -37,4 +39,10 @@
   int getIndex();
   
   String getRoute();
+  
+  /**
+   * Returns a correlation key set for the message route
+   * @return
+   */
+  public CorrelationKeySet getCorrelationKeySet();
 }

Modified: ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OEventHandler.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OEventHandler.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OEventHandler.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OEventHandler.java Thu Nov 20 08:26:25 2008
@@ -18,6 +18,9 @@
  */
 package org.apache.ode.bpel.o;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -56,10 +59,12 @@
         public final List <OScope.CorrelationSet> initCorrelations = new ArrayList<OScope.CorrelationSet>();
 
         /** Correlation set to match on. */
-        public OScope.CorrelationSet matchCorrelation;
+        public final List <OScope.CorrelationSet> matchCorrelations = new ArrayList<OScope.CorrelationSet>();
+        private OScope.CorrelationSet matchCorrelation;
 
         /** Correlation set to join on. */
-        public OScope.CorrelationSet joinCorrelation;
+        public final List<OScope.CorrelationSet> joinCorrelations = new ArrayList<CorrelationSet>();
+        private OScope.CorrelationSet joinCorrelation;
 
         public OPartnerLink partnerLink;
         public Operation operation;
@@ -77,5 +82,31 @@
         public OEvent(OProcess owner, OActivity parent) {
             super(owner, parent);
         }
+
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        	in.defaultReadObject();
+
+        	// backward compatibility; matchCorrelation could have a value if read from old definition
+        	if( matchCorrelation != null ) {
+        		matchCorrelations.add(matchCorrelation);
+        	}
+        	// backward compatibility; joinCorrelations could be null if read from old definition
+        	if( joinCorrelations == null ) {
+        		try {
+        			Field field = OEvent.class.getDeclaredField("joinCorrelations");
+        			field.setAccessible(true);
+        			field.set(this, new ArrayList<CorrelationSet>());
+        		} catch( NoSuchFieldException nfe ) {
+        			throw new IOException(nfe.getMessage());
+        		} catch( IllegalAccessException iae ) {
+        			throw new IOException(iae.getMessage());
+        		}
+        	}
+        	// backward compatibility; joinCorrelation could have a value if read from old definition
+        	if( joinCorrelation != null ) {
+        		joinCorrelation.hasJoinUseCases = true;
+        		joinCorrelations.add(joinCorrelation);
+        	}
+        }
     }
-}
+}
\ No newline at end of file

Modified: ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OInvoke.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OInvoke.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OInvoke.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OInvoke.java Thu Nov 20 08:26:25 2008
@@ -18,11 +18,16 @@
  */
 package org.apache.ode.bpel.o;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.List;
 
 import javax.wsdl.Operation;
 
+import org.apache.ode.bpel.o.OScope.CorrelationSet;
+
 /**
  * Compiled rerpresentation of the BPEL <code>&lt;invoke&gt;</code> activity.
  */
@@ -55,4 +60,33 @@
     public OInvoke(OProcess owner, OActivity parent) {
         super(owner, parent);
     }
+
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+    	in.defaultReadObject();
+
+    	// backward compatibility; joinCorrelationInput could be null if read from old definition
+    	if( joinCorrelationsInput == null ) {
+    		try {
+    			Field field = OInvoke.class.getDeclaredField("joinCorrelationsInput");
+    			field.setAccessible(true);
+    			field.set(this, new ArrayList<OScope.CorrelationSet>());
+    		} catch( NoSuchFieldException nfe ) {
+    			throw new IOException(nfe.getMessage());
+    		} catch( IllegalAccessException iae ) {
+    			throw new IOException(iae.getMessage());
+    		}
+    	}
+    	// backward compatibility; joinCorrelationOutput could be null if read from old definition
+    	if( joinCorrelationsOutput == null ) {
+    		try {
+    			Field field = OInvoke.class.getDeclaredField("joinCorrelationsOutput");
+    			field.setAccessible(true);
+    			field.set(this, new ArrayList<CorrelationSet>());
+    		} catch( NoSuchFieldException nfe ) {
+    			throw new IOException(nfe.getMessage());
+    		} catch( IllegalAccessException iae ) {
+    			throw new IOException(iae.getMessage());
+    		}
+    	}
+    }
 }

Modified: ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OPartnerLink.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OPartnerLink.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OPartnerLink.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OPartnerLink.java Thu Nov 20 08:26:25 2008
@@ -54,6 +54,9 @@
     /** The set of CorrelationSets that may be used as a match criteria, organized by {@link Operation} */
     private final HashMap<String,Set<OScope.CorrelationSet>> _nonIntitiatingCorrelationSets = new HashMap<String,Set<OScope.CorrelationSet>>();
 
+    /** The set of joining CorrelationSets that may be used as a match criteria, organized by {@link Operation} */
+    private final HashMap<String,Set<OScope.CorrelationSet>> _joiningCorrelationSets = new HashMap<String,Set<OScope.CorrelationSet>>();
+
     /** The set of {@link Operation}s that can be used to create a process instance. */
     private final HashSet<String> _createInstanceOperations = new HashSet<String>();
 
@@ -90,25 +93,48 @@
      * @param operation WSDL {@link Operation}
      * @param cset non-initiating correlation used in this operation
      */
-    public void addCorrelationSetForOperation(Operation operation, OScope.CorrelationSet cset) {
+    public void addCorrelationSetForOperation(Operation operation, OScope.CorrelationSet cset, boolean isJoin) {
+    	if( !isJoin ) {
+	        Set<OScope.CorrelationSet> ret = _nonIntitiatingCorrelationSets.get(operation.getName());
+	        if (ret == null) {
+	            ret = new HashSet<OScope.CorrelationSet>();
+	            _nonIntitiatingCorrelationSets.put(operation.getName(), ret);
+	        }
+	        ret.add(cset);
+    	} else {
+	        Set<OScope.CorrelationSet> ret = _joiningCorrelationSets.get(operation.getName());
+	        if (ret == null) {
+	            ret = new HashSet<OScope.CorrelationSet>();
+	            _joiningCorrelationSets.put(operation.getName(), ret);
+	        }
+	        ret.add(cset);
+    	}
+    }
+
+    /**
+     * Get all non-initiating correlation sets that are ever used to qualify a receive for a the given
+     * operation.
+     * @param operation the operation
+     * @return all non-initiating correlation sets used in the given operation
+     */
+    @SuppressWarnings("unchecked")
+    public Set<OScope.CorrelationSet> getNonInitiatingCorrelationSetsForOperation(Operation operation) {
         Set<OScope.CorrelationSet> ret = _nonIntitiatingCorrelationSets.get(operation.getName());
         if (ret == null) {
-            ret = new HashSet<OScope.CorrelationSet>();
-            _nonIntitiatingCorrelationSets.put(operation.getName(), ret);
+            return Collections.EMPTY_SET;
         }
-        ret.add(cset);
-
+        return Collections.unmodifiableSet(ret);
     }
 
     /**
-     * Get all non-initiating correlation sets that are ever used to qualify a receive for a the given
+     * Get all joining correlation sets that are ever used to qualify a receive for a the given
      * operation.
      * @param operation the operation
      * @return all non-initiating correlation sets used in the given operation
      */
     @SuppressWarnings("unchecked")
-    public Set<OScope.CorrelationSet> getCorrelationSetsForOperation(Operation operation) {
-        Set<OScope.CorrelationSet> ret = _nonIntitiatingCorrelationSets.get(operation.getName());
+    public Set<OScope.CorrelationSet> getJoinningCorrelationSetsForOperation(Operation operation) {
+        Set<OScope.CorrelationSet> ret = _joiningCorrelationSets.get(operation.getName());
         if (ret == null) {
             return Collections.EMPTY_SET;
         }

Modified: ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OPickReceive.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OPickReceive.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OPickReceive.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OPickReceive.java Thu Nov 20 08:26:25 2008
@@ -18,12 +18,14 @@
  */
 package org.apache.ode.bpel.o;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.List;
 
 import javax.wsdl.Operation;
 
-
 /**
  * Compiled rerperesentation of the BPEL <code>&lt;pick&gt;</code> and
  * <codE>&lt;receive&gt;</code> activities. Because the latter is essentially
@@ -53,17 +55,20 @@
     }
     
     public static class OnMessage extends OBase {
-      
         static final long serialVersionUID = -1L  ;
         
         /** Correlations to initialize. */
-        public final List <OScope.CorrelationSet> initCorrelations = new ArrayList<OScope.CorrelationSet>();
-
-        /** Correlation set to match on. */
-        public OScope.CorrelationSet matchCorrelation;
+        public final List<OScope.CorrelationSet> initCorrelations = new ArrayList<OScope.CorrelationSet>();
 
-        /** Correlation to join on. */
-        public OScope.CorrelationSet joinCorrelation;
+        /** Correlations to match on. */
+        public final List<OScope.CorrelationSet> matchCorrelations = new ArrayList<OScope.CorrelationSet>();
+        // left out for backward-compatibility, java serialization is lenient about scope
+        private OScope.CorrelationSet matchCorrelation;
+        
+		/** Correlations to join on. */
+        public final List<OScope.CorrelationSet> joinCorrelations = new ArrayList<OScope.CorrelationSet>();
+        // left out for backward-compatibility, java serialization is lenient about scope
+        private OScope.CorrelationSet joinCorrelation;
 
         public OPartnerLink partnerLink;
         public Operation operation;
@@ -82,5 +87,31 @@
         public String getCorrelatorId() {
             return partnerLink.getId() + "." + operation.getName();
         }
+        
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        	in.defaultReadObject();
+
+        	// backward compatibility; matchCorrelation could have a value if read from old definition
+        	if( matchCorrelation != null ) {
+        		matchCorrelations.add(matchCorrelation);
+        	}
+        	// backward compatibility; joinCorrelations could be null if read from old definition
+        	if( joinCorrelations == null ) {
+        		try {
+        			Field field = OnMessage.class.getDeclaredField("joinCorrelations");
+        			field.setAccessible(true);
+        			field.set(this, new ArrayList<OScope.CorrelationSet>());
+        		} catch( NoSuchFieldException nfe ) {
+        			throw new IOException(nfe.getMessage());
+        		} catch( IllegalAccessException iae ) {
+        			throw new IOException(iae.getMessage());
+        		}
+        	}
+        	// backward compatibility; joinCorrelation could have a value if read from old definition
+        	if( joinCorrelation != null ) {
+        		joinCorrelation.hasJoinUseCases = true;
+        		joinCorrelations.add(joinCorrelation);
+        	}
+        }
     }
-}
+}
\ No newline at end of file

Modified: ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java Thu Nov 20 08:26:25 2008
@@ -18,9 +18,6 @@
  */
 package org.apache.ode.bpel.o;
 
-import org.apache.ode.utils.stl.CollectionsX;
-import org.apache.ode.utils.stl.MemberOfFunction;
-
 import javax.wsdl.Operation;
 import javax.xml.namespace.QName;
 import java.io.IOException;
@@ -117,10 +114,12 @@
         return processName;
     }
 
+    @SuppressWarnings("unchecked")
     public Collection getExpressionLanguages() {
         throw new UnsupportedOperationException(); // TODO: implement me!
     }
 
+    @SuppressWarnings("unchecked")
     public List<String> getCorrelators() {
         // MOVED from ProcessSchemaGenerator
         List<String> correlators = new ArrayList<String>();

Modified: ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OReply.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OReply.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OReply.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OReply.java Thu Nov 20 08:26:25 2008
@@ -18,6 +18,9 @@
  */
 package org.apache.ode.bpel.o;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -56,4 +59,21 @@
     public OReply(OProcess owner, OActivity parent) {
         super(owner, parent);
     }
+
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+    	in.defaultReadObject();
+
+    	// backward compatibility; joinCorrelations could be null if read from old definition
+    	if( joinCorrelations == null ) {
+    		try {
+    			Field field = OReply.class.getDeclaredField("joinCorrelations");
+    			field.setAccessible(true);
+    			field.set(this, new ArrayList<OScope.CorrelationSet>());
+    		} catch( NoSuchFieldException nfe ) {
+    			throw new IOException(nfe.getMessage());
+    		} catch( IllegalAccessException iae ) {
+    			throw new IOException(iae.getMessage());
+    		}
+    	}
+    }
 }

Modified: ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OScope.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OScope.java?rev=719270&r1=719269&r2=719270&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OScope.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OScope.java Thu Nov 20 08:26:25 2008
@@ -148,12 +148,16 @@
     }
 
     public static final class CorrelationSet extends OBase {
-      
         static final long serialVersionUID = -1L  ;
+        
         public String name;
         public OScope declaringScope;
         public final List<OProcess.OProperty>properties = new ArrayList<OProcess.OProperty>();
-
+        
+        /**
+         * Indicates that this correlation set has a join use case in the scope.
+         */
+        public boolean hasJoinUseCases = false;
 
         public CorrelationSet(OProcess owner) {
             super(owner);

Added: ode/branches/APACHE_ODE_1.X/bpel-obj/src/test/java/org/apache/ode/bpel/o/SerializerTest.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-obj/src/test/java/org/apache/ode/bpel/o/SerializerTest.java?rev=719270&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-obj/src/test/java/org/apache/ode/bpel/o/SerializerTest.java (added)
+++ ode/branches/APACHE_ODE_1.X/bpel-obj/src/test/java/org/apache/ode/bpel/o/SerializerTest.java Thu Nov 20 08:26:25 2008
@@ -0,0 +1,147 @@
+package org.apache.ode.bpel.o;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+public class SerializerTest {
+	@Test
+	public void testOnMessageBackwardCompatibility() throws Exception {
+		OPickReceive.OnMessage onMessage = new OPickReceive.OnMessage(null);
+
+		// had a value in matchCorrelation variable
+		OScope.CorrelationSet cset1 = new OScope.CorrelationSet(null);
+		cset1.name = "cset1";
+		Field matchCorrelationField = OPickReceive.OnMessage.class.getDeclaredField("matchCorrelation");
+		matchCorrelationField.setAccessible(true);
+		matchCorrelationField.set(onMessage, cset1);
+
+		// joinCorrelations variable was not defined
+		Field joinCorrelationsField = OPickReceive.OnMessage.class.getDeclaredField("joinCorrelations");
+		joinCorrelationsField.setAccessible(true);
+		joinCorrelationsField.set(onMessage, null);
+
+		// had a value in joinCorrelation variable
+		OScope.CorrelationSet cset2 = new OScope.CorrelationSet(null);
+		cset2.name = "cset2";
+		Field joinCorrelationField = OPickReceive.OnMessage.class.getDeclaredField("joinCorrelation");
+		joinCorrelationField.setAccessible(true);
+		joinCorrelationField.set(onMessage, cset2);
+		
+		ObjectOutputStream os = null;
+		ObjectInputStream is = null;
+		try {
+			ByteArrayOutputStream baos = new ByteArrayOutputStream();
+			os = new ObjectOutputStream(baos);
+			os.writeObject(onMessage);
+	
+			is = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
+			onMessage = (OPickReceive.OnMessage)is.readObject();
+			assertEquals("The value in 'matchCorrelation' member should've been transferred to 'matchCorrelations'", 
+					"cset1", onMessage.matchCorrelations.get(0).name);
+			assertNotNull("'joinCorrelations' member cannot be null", onMessage.joinCorrelations);
+			assertEquals("The value in 'joinCorrelation' member should've been transferred to 'joinCorrelations'",
+					"cset2", onMessage.joinCorrelations.get(0).name);
+		} finally {
+			if( os != null ) os.close();
+			if( is != null ) is.close();
+		}
+	}
+
+	@Test
+	public void testOEventBackwardCompatibility() throws Exception {
+		OEventHandler.OEvent oEvent = new OEventHandler.OEvent(null, null);
+		
+		OScope.CorrelationSet cset1 = new OScope.CorrelationSet(null);
+		cset1.name = "cset1";
+		Field matchCorrelationField = OEventHandler.OEvent.class.getDeclaredField("matchCorrelation");
+		matchCorrelationField.setAccessible(true);
+		matchCorrelationField.set(oEvent, cset1);
+
+		Field joinCorrelationsField = OEventHandler.OEvent.class.getDeclaredField("joinCorrelations");
+		joinCorrelationsField.setAccessible(true);
+		joinCorrelationsField.set(oEvent, null);
+
+		OScope.CorrelationSet cset2 = new OScope.CorrelationSet(null);
+		cset2.name = "cset2";
+		Field joinCorrelationField = OEventHandler.OEvent.class.getDeclaredField("joinCorrelation");
+		joinCorrelationField.setAccessible(true);
+		joinCorrelationField.set(oEvent, cset2);
+		
+		ObjectOutputStream os = null;
+		ObjectInputStream is = null;
+		try {
+			ByteArrayOutputStream baos = new ByteArrayOutputStream();
+			os = new ObjectOutputStream(baos);
+			os.writeObject(oEvent);
+	
+			is = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
+			oEvent = (OEventHandler.OEvent)is.readObject();
+			assertEquals("The value in 'matchCorrelation' member should've been transferred to 'matchCorrelations'",
+					"cset1", oEvent.matchCorrelations.get(0).name);
+			assertNotNull("'joinCorrelations' member cannot be null", oEvent.joinCorrelations);
+			assertEquals("The value in 'joinCorrelation' member should've been transferred to 'joinCorrelations'",
+					"cset2", oEvent.joinCorrelations.get(0).name);
+		} finally {
+			if( os != null ) os.close();
+			if( is != null ) is.close();
+		}
+	}
+
+	@Test
+	public void testOReplyBackwardCompatibility() throws Exception {
+		OReply reply = new OReply(null, null);
+		
+		Field joinCorrelationsField = OReply.class.getDeclaredField("joinCorrelations");
+		joinCorrelationsField.setAccessible(true);
+		joinCorrelationsField.set(reply, null);
+		
+		ObjectOutputStream os = null;
+		ObjectInputStream is = null;
+		try {
+			ByteArrayOutputStream baos = new ByteArrayOutputStream();
+			os = new ObjectOutputStream(baos);
+			os.writeObject(reply);
+	
+			is = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
+			reply = (OReply)is.readObject();
+			assertNotNull("'joinCorrelations' member cannot be null", reply.joinCorrelations);
+		} finally {
+			if( os != null ) os.close();
+			if( is != null ) is.close();
+		}
+	}
+
+	@Test
+	public void testOInvokeBackwardCompatibility() throws Exception {
+		OInvoke invoke = new OInvoke(null, null);
+		
+		Field joinCorrelationsField = OInvoke.class.getDeclaredField("joinCorrelationsInput");
+		joinCorrelationsField.setAccessible(true);
+		joinCorrelationsField.set(invoke, null);
+		joinCorrelationsField = OInvoke.class.getDeclaredField("joinCorrelationsOutput");
+		joinCorrelationsField.setAccessible(true);
+		joinCorrelationsField.set(invoke, null);
+		
+		ObjectOutputStream os = null;
+		ObjectInputStream is = null;
+		try {
+			ByteArrayOutputStream baos = new ByteArrayOutputStream();
+			os = new ObjectOutputStream(baos);
+			os.writeObject(invoke);
+	
+			is = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
+			invoke = (OInvoke)is.readObject();
+			assertNotNull("'joinCorrelationsInput' member cannot be null", invoke.joinCorrelationsInput);
+			assertNotNull("'joinCorrelationsOutput' member cannot be null", invoke.joinCorrelationsOutput);
+		} finally {
+			if( os != null ) os.close();
+			if( is != null ) is.close();
+		}
+	}
+}
\ No newline at end of file