You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by ka...@apache.org on 2008/12/19 22:09:18 UTC

svn commit: r728144 [1/2] - in /ode/branches/APACHE_ODE_1.X: bpel-api/src/main/java/org/apache/ode/bpel/common/ bpel-api/src/main/java/org/apache/ode/bpel/evt/ bpel-api/src/test/java/org/apache/ode/bpel/common/ bpel-compiler/src/main/java/org/apache/od...

Author: karthick
Date: Fri Dec 19 13:09:17 2008
New Revision: 728144

URL: http://svn.apache.org/viewvc?rev=728144&view=rev
Log:
Add extension to make a correlation set unique

Added:
    ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKeys.java
    ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/
    ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/counter.bpel
    ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/counter.wsdl
    ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/deploy.xml
    ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/test1.properties
    ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/test2.properties
    ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/test3.properties
Removed:
    ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKeySet.java
Modified:
    ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKey.java
    ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/evt/CorrelationMatchEvent.java
    ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/evt/CorrelationNoMatchEvent.java
    ode/branches/APACHE_ODE_1.X/bpel-api/src/test/java/org/apache/ode/bpel/common/CorrelationKeySetTest.java
    ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
    ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/PickReceiveGenerator.java
    ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/CorrelationSet.java
    ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/CorrelatorDAO.java
    ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/MessageRouteDAO.java
    ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/ProcessDAO.java
    ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OConstants.java
    ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OPartnerLink.java
    ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OScope.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelEngineImpl.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelManagementFacadeImpl.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/PartnerLinkMyRoleImpl.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/WorkEvent.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/CorrelatorDaoImpl.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/MessageRouteDaoImpl.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/ProcessDaoImpl.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelJacobRunnable.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EH_EVENT.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/InvalidProcessException.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/PICK.java
    ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/Selector.java
    ode/branches/APACHE_ODE_1.X/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java
    ode/branches/APACHE_ODE_1.X/bpel-test/src/test/java/org/apache/ode/test/MessageRouting20Test.java
    ode/branches/APACHE_ODE_1.X/dao-hibernate/src/main/java/org/apache/ode/daohib/bpel/CorrelatorDaoImpl.java
    ode/branches/APACHE_ODE_1.X/dao-hibernate/src/main/java/org/apache/ode/daohib/bpel/MessageRouteDaoImpl.java
    ode/branches/APACHE_ODE_1.X/dao-hibernate/src/main/java/org/apache/ode/daohib/bpel/ProcessDaoImpl.java
    ode/branches/APACHE_ODE_1.X/dao-jpa/src/main/java/org/apache/ode/dao/jpa/CorrelatorDAOImpl.java
    ode/branches/APACHE_ODE_1.X/dao-jpa/src/main/java/org/apache/ode/dao/jpa/MessageExchangeDAOImpl.java
    ode/branches/APACHE_ODE_1.X/dao-jpa/src/main/java/org/apache/ode/dao/jpa/MessageRouteDAOImpl.java
    ode/branches/APACHE_ODE_1.X/dao-jpa/src/main/java/org/apache/ode/dao/jpa/ProcessDAOImpl.java

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=728144&r1=728143&r2=728144&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 Fri Dec 19 13:09:17 2008
@@ -53,6 +53,9 @@
 
     /** Key values. */
     private final String _keyValues[];
+    
+    /** System-Wide Unique? */
+    private boolean unique = false;
 
     /**
      * Constructor.
@@ -124,6 +127,20 @@
     }
 
     /**
+     * Is this correlation key system-wide unique?
+     * 
+     * @return <code>true</code> if the key is declared to be unique  
+     *         otherwise <code>false</code>
+     */
+    public boolean isUnique() {
+    	return unique;
+    }
+    
+    public void setUnique(boolean unique) {
+    	this.unique = unique;
+    }
+    
+    /**
      * Equals comperator method.
      * 
      * @param o

Added: ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKeys.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKeys.java?rev=728144&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKeys.java (added)
+++ ode/branches/APACHE_ODE_1.X/bpel-api/src/main/java/org/apache/ode/bpel/common/CorrelationKeys.java Fri Dec 19 13:09:17 2008
@@ -0,0 +1,362 @@
+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 CorrelationKeys implements Iterable<CorrelationKey>, 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 CorrelationKeys() {
+	}
+	
+	/**
+	 * Restores the state by parsing the given canonical form of correlation key set.
+	 * 
+	 * @param canonicalForm canonical form of correlation key set
+	 */
+	public CorrelationKeys(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 CorrelationKeys 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(CorrelationKeys 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(CorrelationKeys 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 CorrelationKeys) ) {
+			return false;
+		}
+		CorrelationKeys another = (CorrelationKeys)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<CorrelationKeys> findSubSets() {
+    	List<CorrelationKeys> subSets = new ArrayList<CorrelationKeys>();
+    	
+    	// if the key set contains a opaque key and at least one non-opaque key, take out the opaque key
+    	CorrelationKey opaqueKey = null;
+    	boolean containsNonOpaque = false;
+    	CorrelationKeys explicitKeySet = new CorrelationKeys();
+    	for( CorrelationKey ckey : correlationKeys ) {
+    		// assumes only ONE opaque key if there is
+    		if( ckey.getCSetId() == -1 ) {
+    			opaqueKey = ckey;
+    		} else {
+    			containsNonOpaque = true;
+    		}
+    		explicitKeySet.add(ckey);
+    	}
+    	if( opaqueKey != null && containsNonOpaque ) {
+    		explicitKeySet.correlationKeys.remove(opaqueKey);
+    	}
+    	
+		// we are generating (2 powered by the number of correlation keys) number of sub-sets
+    	for( int setIndex = 0; setIndex < Math.pow(2, explicitKeySet.correlationKeys.size()); setIndex++ ) {
+    		CorrelationKeys subKeySet = new CorrelationKeys(); 
+    		int bitPattern = setIndex; // the bitPattern will be 0b0000, 0b0001, 0b0010 and so on
+    		Iterator<CorrelationKey> ckeys = explicitKeySet.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;
+    		}
+
+    		if(!subKeySet.isEmpty()) { // we don't want an empty set
+    			subSets.add(subKeySet);
+    		}
+    	}
+    	
+    	if( subSets.isEmpty() ) {
+    		subSets.add(new CorrelationKeys());
+    	}
+    	
+    	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

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=728144&r1=728143&r2=728144&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 Fri Dec 19 13:09:17 2008
@@ -19,7 +19,7 @@
 package org.apache.ode.bpel.evt;
 
 import org.apache.ode.bpel.common.CorrelationKey;
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 
 import javax.xml.namespace.QName;
 
@@ -31,18 +31,18 @@
 
 	// left out for backward-compatibility
 	private CorrelationKey _correlationKey;
-	private CorrelationKeySet _correlationKeySet;
+	private CorrelationKeys _correlationKeySet;
 
-	public CorrelationMatchEvent(QName processName, QName processId, Long processInstanceId, CorrelationKeySet correlationKeySet) {
+	public CorrelationMatchEvent(QName processName, QName processId, Long processInstanceId, CorrelationKeys correlationKeySet) {
 		super(PROCESS_INPUT, processName, processId, processInstanceId);
 		_correlationKeySet = correlationKeySet;
 	}
 
-	public CorrelationKeySet getCorrelationKeySet() {
+	public CorrelationKeys getCorrelationKeySet() {
 		// backward compatibility; add up
 		if (_correlationKey != null) {
 			if( _correlationKeySet == null ) {
-				_correlationKeySet = new CorrelationKeySet();
+				_correlationKeySet = new CorrelationKeys();
 			}
 			if(!_correlationKeySet.contains(_correlationKey)) {
 				_correlationKeySet.add(_correlationKey);
@@ -52,7 +52,7 @@
 		return _correlationKeySet;
 	}
 
-	public void setCorrelationKey(CorrelationKeySet correlationKeySet) {
+	public void setCorrelationKey(CorrelationKeys correlationKeySet) {
 		_correlationKeySet = correlationKeySet;
 	}
 

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=728144&r1=728143&r2=728144&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 Fri Dec 19 13:09:17 2008
@@ -24,7 +24,7 @@
 import javax.xml.namespace.QName;
 
 import org.apache.ode.bpel.common.CorrelationKey;
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 
 /**
  * Message arrived and matched neither (a) createInstance or (b) correlation
@@ -35,19 +35,19 @@
 	
 	// left out for backward-compatibility
 	private final Set<CorrelationKey> _keys = new HashSet<CorrelationKey>();
-	private CorrelationKeySet _keySet = null;
+	private CorrelationKeys _keySet = null;
 
 	public CorrelationNoMatchEvent(QName qName, String opName, String mexId,
-			CorrelationKeySet keySet) {
+			CorrelationKeys keySet) {
 		super(qName, opName, mexId);
 
 		_keySet = keySet;
 	}
 
-	public CorrelationKeySet getKeySet() {
+	public CorrelationKeys getKeySet() {
 		// backward-compatibility; add up keys
 		if( _keys.size() > 0 && _keySet == null ) {
-			_keySet = new CorrelationKeySet();
+			_keySet = new CorrelationKeys();
 		}
 		for (CorrelationKey aKey : _keys) {
 			if (aKey != null && !_keySet.contains(aKey)) {
@@ -58,7 +58,7 @@
 		return _keySet;
 	}
 
-	public void setKeys(CorrelationKeySet keySet) {
+	public void setKeys(CorrelationKeys keySet) {
 		_keySet = keySet;
 	}
 

Modified: 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=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-api/src/test/java/org/apache/ode/bpel/common/CorrelationKeySetTest.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-api/src/test/java/org/apache/ode/bpel/common/CorrelationKeySetTest.java Fri Dec 19 13:09:17 2008
@@ -14,7 +14,7 @@
 
 	@Test
 	public void testCanonicalString() throws Exception {
-		CorrelationKeySet setA = new CorrelationKeySet();
+		CorrelationKeys setA = new CorrelationKeys();
 		setA.add(keyX);
 		setA.add(optY);
 		assertEquals("@2[1~a~b],[2~b~c]", setA.toCanonicalString());
@@ -22,8 +22,8 @@
 	
 	@Test
 	public void testContainsAll() throws Exception {
-		CorrelationKeySet setA = new CorrelationKeySet();
-		CorrelationKeySet setB = new CorrelationKeySet();
+		CorrelationKeys setA = new CorrelationKeys();
+		CorrelationKeys setB = new CorrelationKeys();
 		assertTrue(setA.containsAll(setB));
 		
 		setA.add(keyX);
@@ -39,32 +39,32 @@
 	
 	@Test
 	public void testRestoreFromCanonicalForm() throws Exception {
-		assertEquals(new CorrelationKeySet(null), new CorrelationKeySet());
-		assertEquals(new CorrelationKeySet(""), new CorrelationKeySet());
+		assertEquals(new CorrelationKeys(null), new CorrelationKeys());
+		assertEquals(new CorrelationKeys(""), new CorrelationKeys());
 		
-		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"}))
+		assertEquals(new CorrelationKeys("-1~session_key"), 
+				new CorrelationKeys().add(new CorrelationKey(-1, new String[] {"session_key"})));
+		assertEquals(new CorrelationKeys("1~key1~key2"), 
+				new CorrelationKeys().add(new CorrelationKey(1, new String[] {"key1", "key2"})));
+
+		assertEquals(new CorrelationKeys("@2"), new CorrelationKeys());
+		assertEquals(new CorrelationKeys("@2[-1~session_key]"), 
+				new CorrelationKeys().add(new CorrelationKey(-1, new String[] {"session_key"})));
+		assertEquals(new CorrelationKeys("@2[1~key1~key2]"), 
+				new CorrelationKeys().add(new CorrelationKey(1, new String[] {"key1", "key2"})));
+		assertEquals(new CorrelationKeys("@2[1~key1],[2~key2~key3]"), 
+				new CorrelationKeys().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"}))
+		assertEquals(new CorrelationKeys("@2[1~key1],[2~key2~key3]?"), 
+				new CorrelationKeys().add(new CorrelationKey(1, new String[] {"key1"}))
 				.add(new CorrelationKey(2, new String[] {"key2", "key3"})));
-		assertEquals(3, new CorrelationKeySet("@2[1~key1],[2~key2~key3]?").findSubSets().size());
+		assertEquals(3, new CorrelationKeys("@2[1~key1],[2~key2~key3]?").findSubSets().size());
 	}
 	
 	@Test
 	public void testRoutableTo() throws Exception {
-		CorrelationKeySet setA = new CorrelationKeySet();
-		CorrelationKeySet setB = new CorrelationKeySet();
+		CorrelationKeys setA = new CorrelationKeys();
+		CorrelationKeys setB = new CorrelationKeys();
 		assertTrue(setA.isRoutableTo(setB, false));
 		assertTrue(setA.isRoutableTo(setB, true));
 		
@@ -81,8 +81,8 @@
 		assertTrue(setA.isRoutableTo(setB, false));
 		assertTrue(setA.isRoutableTo(setB, true));
 		
-		CorrelationKeySet inbound = new CorrelationKeySet();
-		CorrelationKeySet candidate = new CorrelationKeySet();
+		CorrelationKeys inbound = new CorrelationKeys();
+		CorrelationKeys candidate = new CorrelationKeys();
 		candidate.add(new CorrelationKey("-1~session_key"));
 		assertFalse(inbound.isRoutableTo(candidate, false));
 		assertTrue(inbound.isRoutableTo(candidate, true));
@@ -102,7 +102,7 @@
 	@Test
 	public void testFindSubSets() throws Exception {
 		StringBuffer buf = new StringBuffer();
-		for( CorrelationKeySet subSet : new CorrelationKeySet().findSubSets() ) {
+		for( CorrelationKeys subSet : new CorrelationKeys().findSubSets() ) {
 			if( buf.length() > 0 ) {
 				buf.append(",");
 			}
@@ -110,18 +110,18 @@
 		}
 		assertEquals("'@2'",  buf.toString());
 
-		CorrelationKeySet keySet = new CorrelationKeySet();
+		CorrelationKeys keySet = new CorrelationKeys();
 		keySet.add(keyX);
 		keySet.add(keyY);
 		keySet.add(keyZ);
 		assertTrue(keySet.findSubSets().size() == 7);
 
-		keySet = new CorrelationKeySet();		
+		keySet = new CorrelationKeys();		
 		keySet.add(optX);
 		keySet.add(optY);
 		keySet.add(optZ);
 		buf = new StringBuffer();
-		for( CorrelationKeySet subSet : keySet.findSubSets() ) {
+		for( CorrelationKeys subSet : keySet.findSubSets() ) {
 			if( buf.length() > 0 ) {
 				buf.append(",");
 			}
@@ -130,12 +130,12 @@
 		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 = new CorrelationKeys();		
 		keySet.add(keyX);
 		keySet.add(keyY);
 		keySet.add(optZ);
 		buf = new StringBuffer();
-		for( CorrelationKeySet subSet : keySet.findSubSets() ) {
+		for( CorrelationKeys subSet : keySet.findSubSets() ) {
 			if( buf.length() > 0 ) {
 				buf.append(",");
 			}
@@ -143,12 +143,12 @@
 		}
 		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 = new CorrelationKeys();		
 		keySet.add(keyX);
 		keySet.add(optY);
 		keySet.add(optZ);
 		buf = new StringBuffer();
-		for( CorrelationKeySet subSet : keySet.findSubSets() ) {
+		for( CorrelationKeys subSet : keySet.findSubSets() ) {
 			if( buf.length() > 0 ) {
 				buf.append(",");
 			}

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=728144&r1=728143&r2=728144&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 Fri Dec 19 13:09:17 2008
@@ -111,6 +111,7 @@
 import org.apache.ode.bpel.o.OXslSheet;
 import org.apache.ode.utils.GUID;
 import org.apache.ode.utils.NSContext;
+import org.apache.ode.utils.Namespaces;
 import org.apache.ode.utils.StreamUtils;
 import org.apache.ode.utils.fs.FileUtils;
 import org.apache.ode.utils.msg.MessageBundle;
@@ -767,6 +768,10 @@
         constants.qnForEachCounterError = new QName(getBpwsNamespace(), "forEachCounterError");
         constants.qnInvalidBranchCondition = new QName(getBpwsNamespace(), "invalidBranchCondition");
         constants.qnInvalidExpressionValue = new QName(getBpwsNamespace(), "invalidExpressionValue");
+        
+        constants.qnDuplicateInstance = new QName(getOdeNamespace(), "duplicateInstance");
+        constants.qnRetiredProcess = new QName(getOdeNamespace(), "retiredProcess");
+        constants.qnUnknownFault = new QName(getOdeNamespace(), "unknownFault");
         return constants;
     }
 
@@ -1058,6 +1063,7 @@
         QName[] setprops = cset.getProperties();
         for (int j = 0; j < setprops.length; ++j)
             ocset.properties.add(resolveProperty(setprops[j]));
+        ocset.unique = cset.isUnique();
         oscope.addCorrelationSet(ocset);
     }
 
@@ -1299,6 +1305,7 @@
                         break;
                     case YES:
                         oevent.initCorrelations.add(cset);
+                        oevent.partnerLink.addUniqueCorrelationSetForOperation(oevent.operation, cset);
                         break;
                     case JOIN:
                     	cset.hasJoinUseCases = true;
@@ -1647,6 +1654,10 @@
     protected abstract String getDefaultExpressionLanguage();
 
     protected abstract String getBpwsNamespace();
+    
+    protected String getOdeNamespace() {
+    	return Namespaces.ODE_EXTENSION_NS;
+    }
 
     protected void registerExpressionLanguage(String expLangUri, ExpressionCompiler expressionCompiler) {
         _expLanguageCompilers.put(expLangUri, expressionCompiler);

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=728144&r1=728143&r2=728144&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 Fri Dec 19 13:09:17 2008
@@ -103,6 +103,7 @@
                 break;
             case YES:
                 onMessage.initCorrelations.add(cset);
+                onMessage.partnerLink.addUniqueCorrelationSetForOperation(onMessage.operation, cset);
                 break;
             case JOIN:
             	cset.hasJoinUseCases = true;

Modified: ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/CorrelationSet.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/CorrelationSet.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/CorrelationSet.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/CorrelationSet.java Fri Dec 19 13:09:17 2008
@@ -73,4 +73,12 @@
         return _props;
     }
 
+    /**
+     * Is the correlation set system-wide unique?
+     * 
+     * @return <code>true</code> iff the set is unique
+     */
+    public boolean isUnique() {
+        return getAttribute("unique", "no").equals("yes");
+    }
 }

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=728144&r1=728143&r2=728144&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 Fri Dec 19 13:09:17 2008
@@ -20,7 +20,7 @@
 
 import java.util.List;
 
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 
 /**
  * <p>
@@ -60,7 +60,7 @@
    * @param mex message exchange
    * @param correlationKeys pre-computed set of correlation keys for this message
    */
-  void enqueueMessage(MessageExchangeDAO mex, CorrelationKeySet correlationKeySet);
+  void enqueueMessage(MessageExchangeDAO mex, CorrelationKeys correlationKeySet);
 
 
   /**
@@ -70,14 +70,14 @@
    * @return opaque message-related data previously enqueued with the
    *         given correlation correlationKey
    */
-  MessageExchangeDAO dequeueMessage(CorrelationKeySet correlationKeySet);
+  MessageExchangeDAO dequeueMessage(CorrelationKeys correlationKeySet);
 
   /**
    * Find a route matching the given correlation key.
    * @param correlationKey correlation key
    * @return route matching the given correlation key
    */
-  List<MessageRouteDAO> findRoute(CorrelationKeySet correlationKeySet);
+  List<MessageRouteDAO> findRoute(CorrelationKeys 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, CorrelationKeySet correlationKeySet, String routePolicy);
+  void addRoute(String routeGroupId, ProcessInstanceDAO target, int index, CorrelationKeys 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=728144&r1=728143&r2=728144&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 Fri Dec 19 13:09:17 2008
@@ -18,7 +18,7 @@
  */
 package org.apache.ode.bpel.dao;
 
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 
 /**
  * Data access object representing a message consumer. A message consumer
@@ -44,5 +44,5 @@
    * Returns a correlation key set for the message route
    * @return
    */
-  public CorrelationKeySet getCorrelationKeySet();
+  public CorrelationKeys getCorrelationKeys();
 }

Modified: ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/ProcessDAO.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/ProcessDAO.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/ProcessDAO.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-dao/src/main/java/org/apache/ode/bpel/dao/ProcessDAO.java Fri Dec 19 13:09:17 2008
@@ -79,11 +79,11 @@
     /**
      * Locates a process instance based on a correlation key.
      * 
-     * @param cckey
-     *            correlation key
+     * @param cckey correlation key
+     *        wait <code>false</code> if you don't want the query to block 
      * @return collection of {@link ProcessInstanceDAO} that match correlation key, ordered by date
      */
-    Collection<ProcessInstanceDAO> findInstance(CorrelationKey cckey);
+    Collection<ProcessInstanceDAO> findInstance(CorrelationKey cckey, boolean wait);
 
     /**
      * Remove the routes with the given Id for all the correlators in the process.

Modified: ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OConstants.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OConstants.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OConstants.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-obj/src/main/java/org/apache/ode/bpel/o/OConstants.java Fri Dec 19 13:09:17 2008
@@ -27,6 +27,8 @@
 public class OConstants extends OBase {
 
     private static final long serialVersionUID = 1L;
+    
+    // standard fault names
     public QName qnMissingRequest;
     public QName qnMissingReply;
     public QName qnUninitializedVariable;
@@ -42,7 +44,11 @@
     public QName qnForEachCounterError;
     public QName qnInvalidBranchCondition;
     public QName qnInvalidExpressionValue;
-
+    
+    // non-standard fault names
+    public QName qnRetiredProcess;
+    public QName qnDuplicateInstance;
+    public QName qnUnknownFault;
 
     public OConstants(OProcess owner) {
         super(owner);

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=728144&r1=728143&r2=728144&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 Fri Dec 19 13:09:17 2008
@@ -57,6 +57,9 @@
     /** 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 initiating CorrelationSets that may be used as an uniqueness criteria, organized by {@link Operation} */
+    private final HashMap<String,Set<OScope.CorrelationSet>> _uniqueInitiatingCorrelationSets = 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>();
 
@@ -93,7 +96,7 @@
      * @param operation WSDL {@link Operation}
      * @param cset non-initiating correlation used in this operation
      */
-    public void addCorrelationSetForOperation(Operation operation, OScope.CorrelationSet cset, boolean isJoin) {
+    public void addCorrelationSetForOperation(Operation operation, OScope.CorrelationSet cset, boolean isJoin) {    	
     	if( !isJoin ) {
 	        Set<OScope.CorrelationSet> ret = _nonIntitiatingCorrelationSets.get(operation.getName());
 	        if (ret == null) {
@@ -110,7 +113,28 @@
 	        ret.add(cset);
     	}
     }
-
+    
+    /**
+     * Add a {@link org.apache.ode.bpel.o.OScope.CorrelationSet} to an {@link Operation}'s list
+     * of "unique-initiating" correlation sets. The unique-initiating correlation sets are those
+     * sets that are used (along with the operation) to "initiate" incoming messages, provided
+     * that there doesn't already exist a process instance with that correlation key.
+     * We need to know which correlation sets are used with which operation in order to
+     * pre-compute correlation keys at the time of message receipt.
+     * @param operation WSDL {@link Operation}
+     * @param cset unique-initiating correlation used in this operation
+     */
+    public void addUniqueCorrelationSetForOperation(Operation operation, OScope.CorrelationSet cset) {    	
+    	if (cset.unique) {
+	        Set<OScope.CorrelationSet> ret = _uniqueInitiatingCorrelationSets.get(operation.getName());
+	        if (ret == null) {
+	            ret = new HashSet<OScope.CorrelationSet>();
+	            _uniqueInitiatingCorrelationSets.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.
@@ -141,6 +165,21 @@
         return Collections.unmodifiableSet(ret);
     }
 
+    /**
+     * Get all unique initiating correlation sets that are ever used to qualify a receive for a the given
+     * operation.
+     * @param operation the operation
+     * @return all unique-initiating correlation sets used in the given operation
+     */
+    @SuppressWarnings("unchecked")
+    public Set<OScope.CorrelationSet> getUniqueCorrelationSetsForOperation(Operation operation) {
+        Set<OScope.CorrelationSet> ret = _uniqueInitiatingCorrelationSets.get(operation.getName());
+        if (ret == null) {
+            return Collections.EMPTY_SET;
+        }
+        return Collections.unmodifiableSet(ret);
+    }
+
     @SuppressWarnings("unchecked")
     public Operation getMyRoleOperation(String name) {
         for (Operation op : (List<Operation>)myRolePortType.getOperations()) 

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=728144&r1=728143&r2=728144&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 Fri Dec 19 13:09:17 2008
@@ -153,6 +153,7 @@
         public String name;
         public OScope declaringScope;
         public final List<OProcess.OProperty>properties = new ArrayList<OProcess.OProperty>();
+        public boolean unique;
         
         /**
          * Indicates that this correlation set has a join use case in the scope.

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelEngineImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelEngineImpl.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelEngineImpl.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelEngineImpl.java Fri Dec 19 13:09:17 2008
@@ -420,6 +420,9 @@
         } catch (ContextException ce) {
             __log.error(__msgs.msgScheduledJobFailed(we.getDetail()), ce);
             throw new Scheduler.JobProcessorException(ce, checkRetry(jobInfo, ce));
+        } catch (NonRetriableException nre) {
+            __log.error(__msgs.msgScheduledJobFailed(we.getDetail()), nre);
+            throw new Scheduler.JobProcessorException(nre, false);
         } catch (RuntimeException rte) {
             __log.error(__msgs.msgScheduledJobFailed(we.getDetail()), rte);
             throw new Scheduler.JobProcessorException(rte, checkRetry(jobInfo, rte));

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelManagementFacadeImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelManagementFacadeImpl.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelManagementFacadeImpl.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelManagementFacadeImpl.java Fri Dec 19 13:09:17 2008
@@ -65,7 +65,7 @@
 
         return dbexec(_db.getProcessDb(QName.valueOf(pid)).new Callable<Long>()  {
             public Long run(BpelDAOConnection session) throws Exception {
-                Iterator<ProcessInstanceDAO> i = getProcessDAO().findInstance(ckey).iterator();
+                Iterator<ProcessInstanceDAO> i = getProcessDAO().findInstance(ckey, true).iterator();
                 return (i.hasNext()) ? i.next().getInstanceId() : null;
             }
         });

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelProcess.java Fri Dec 19 13:09:17 2008
@@ -44,12 +44,15 @@
 import org.apache.ode.bpel.iapi.BpelEngineException;
 import org.apache.ode.bpel.iapi.Endpoint;
 import org.apache.ode.bpel.iapi.EndpointReference;
+import org.apache.ode.bpel.iapi.Message;
 import org.apache.ode.bpel.iapi.MessageExchange;
 import org.apache.ode.bpel.iapi.PartnerRoleChannel;
+import org.apache.ode.bpel.iapi.PartnerRoleMessageExchange;
 import org.apache.ode.bpel.iapi.ProcessConf;
 import org.apache.ode.bpel.iapi.ProcessConf.CLEANUP_CATEGORY;
 import org.apache.ode.bpel.intercept.InterceptorInvoker;
 import org.apache.ode.bpel.intercept.MessageExchangeInterceptor;
+import org.apache.ode.bpel.o.OConstants;
 import org.apache.ode.bpel.o.OElementVarType;
 import org.apache.ode.bpel.o.OExpressionLanguage;
 import org.apache.ode.bpel.o.OMessageVarType;
@@ -57,12 +60,16 @@
 import org.apache.ode.bpel.o.OProcess;
 import org.apache.ode.bpel.o.Serializer;
 import org.apache.ode.bpel.runtime.ExpressionLanguageRuntimeRegistry;
+import org.apache.ode.bpel.runtime.InvalidProcessException;
 import org.apache.ode.bpel.runtime.PROCESS;
 import org.apache.ode.bpel.runtime.PropertyAliasEvaluationContext;
 import org.apache.ode.bpel.runtime.channels.FaultData;
 import org.apache.ode.jacob.soup.ReplacementMap;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.Namespaces;
 import org.apache.ode.utils.ObjectPrinter;
 import org.apache.ode.utils.msg.MessageBundle;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -175,6 +182,7 @@
      * @param mex
      */
     void invokeProcess(MyRoleMessageExchangeImpl mex) {
+    	OProcess oProcess = null;
         boolean routed = false;
 
         try {
@@ -201,6 +209,7 @@
             List<PartnerLinkMyRoleImpl.RoutingInfo> routings = null;
             for (PartnerLinkMyRoleImpl target : targets) {
                 routings = target.findRoute(mex);
+                oProcess = target._process.getOProcess();
                 boolean createInstance = target.isCreateInstance(mex);
 
                 if (mex.getStatus() != MessageExchange.Status.FAILURE) {
@@ -237,15 +246,43 @@
             }
 
             markused();
+        } catch (InvalidProcessException ipe) {
+        	QName faultQName = null;
+        	if (oProcess != null) {
+        		Message faultMessage = mex.createMessage(faultQName);
+        		Document document = DOMUtils.newDocument();
+        		Element faultElement = document.createElementNS(Namespaces.SOAP_ENV_NS, "Fault");
+        		Element faultDetail = document.createElementNS(Namespaces.ODE_EXTENSION_NS, "fault");
+        		faultElement.appendChild(faultDetail);
+	        	switch (ipe.getCauseCode()) {
+		        	case InvalidProcessException.DUPLICATE_CAUSE_CODE:
+		        		faultQName = oProcess.constants.qnDuplicateInstance;
+		        		faultDetail.setTextContent("Found a duplicate instance with the same message key");
+		        		break;
+		        	case InvalidProcessException.RETIRED_CAUSE_CODE:
+		        		faultQName = oProcess.constants.qnRetiredProcess;
+		        		faultDetail.setTextContent("The process you're trying to instantiate has been retired");
+		        		break;
+		        	case InvalidProcessException.DEFAULT_CAUSE_CODE:
+		        	default:
+		        		faultQName = oProcess.constants.qnUnknownFault;
+		        		break;
+	        	}
+	        	faultMessage.setMessage(faultElement);
+	        	mex.setStatus(MessageExchange.Status.FAULT);
+	        	mex.setFault(faultQName, faultMessage);
+	        	mex.responseReceived();
+        	}
         } finally {
             _hydrationLatch.release(1);
         }
-
+        
         // For a one way, once the engine is done, the mex can be safely released.
         // Sean: not really, if route is not found, we cannot delete the mex yet
         if (mex.getPattern().equals(MessageExchange.MessageExchangePattern.REQUEST_ONLY) && routed) {
-            mex.release();
+        	mex.release();
         }
+        
     }
 
     /** Several myroles can use the same service in a given process */

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/BpelRuntimeContextImpl.java Fri Dec 19 13:09:17 2008
@@ -29,7 +29,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ode.bpel.common.CorrelationKey;
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 import org.apache.ode.bpel.common.FaultException;
 import org.apache.ode.bpel.common.ProcessState;
 import org.apache.ode.bpel.dao.CorrelationSetDAO;
@@ -607,6 +607,7 @@
         }
 
         CorrelationKey ckeyVal = new CorrelationKey(cset.declaration.getId(), propValues);
+        ckeyVal.setUnique(cset.declaration.unique);
         writeCorrelation(cset, ckeyVal);
     }
 
@@ -639,7 +640,7 @@
         _bpelProcess._engine._contexts.scheduler.schedulePersistedJob(we.getDetail(), timeToFire);
     }
 
-    private void scheduleCorrelatorMatcher(String correlatorId, CorrelationKeySet keySet) {
+    private void scheduleCorrelatorMatcher(String correlatorId, CorrelationKeys keySet) {
         WorkEvent we = new WorkEvent();
         we.setIID(_dao.getInstanceId());
         we.setType(WorkEvent.Type.MATCHER);
@@ -1321,7 +1322,7 @@
      * Attempt to match message exchanges on a correlator.
      *
      */
-    public void matcherEvent(String correlatorId, CorrelationKeySet ckeySet) {
+    public void matcherEvent(String correlatorId, CorrelationKeys ckeySet) {
         if (BpelProcess.__log.isDebugEnabled()) {
             __log.debug("MatcherEvent handling: correlatorId=" + correlatorId + ", ckeySet=" + ckeySet);
         }

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/PartnerLinkMyRoleImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/PartnerLinkMyRoleImpl.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/PartnerLinkMyRoleImpl.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/PartnerLinkMyRoleImpl.java Fri Dec 19 13:09:17 2008
@@ -19,6 +19,7 @@
 package org.apache.ode.bpel.engine;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
@@ -30,7 +31,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ode.bpel.common.CorrelationKey;
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 import org.apache.ode.bpel.common.FaultException;
 import org.apache.ode.bpel.common.InvalidMessageException;
 import org.apache.ode.bpel.common.OptionalCorrelationKey;
@@ -111,7 +112,7 @@
 
         CorrelatorDAO correlator = _process.getProcessDAO().getCorrelator(correlatorId);
 
-        CorrelationKeySet keySet;
+        CorrelationKeys processKeys, uniqueKeys;
 
         // We need to compute the correlation keys (based on the operation
         // we can  infer which correlation keys to compute - this is merely a set
@@ -119,7 +120,8 @@
         // that is ever referenced in an <receive>/<onMessage> on this
         // partnerlink/operation.
         try {
-            keySet = computeCorrelationKeys(mex);
+            processKeys = computeCorrelationKeys(mex);
+            uniqueKeys = computeUniqueCorrelationKeys(mex);
         } catch (InvalidMessageException ime) {
             // We'd like to do a graceful exit here, no sense in rolling back due to a
             // a message format problem.
@@ -132,23 +134,23 @@
         String partnerSessionId = mex.getProperty(MessageExchange.PROPERTY_SEP_PARTNERROLE_SESSIONID);
         if (__log.isDebugEnabled()) {
             __log.debug("INPUTMSG: " + correlatorId + ": MSG RCVD keys="
-                    + keySet + " mySessionId=" + mySessionId
+                    + processKeys + " mySessionId=" + mySessionId
                     + " partnerSessionId=" + partnerSessionId);
         }
 
         // Try to find a route for one of our keys.
-        List<MessageRouteDAO> messageRoutes = correlator.findRoute(keySet);
+        List<MessageRouteDAO> messageRoutes = correlator.findRoute(processKeys);
         if (messageRoutes != null && messageRoutes.size() > 0) {
             for (MessageRouteDAO messageRoute : messageRoutes) {
                 if (__log.isDebugEnabled()) {
-                    __log.debug("INPUTMSG: " + correlatorId + ": ckeySet " + messageRoute.getCorrelationKeySet() + " route is to " + messageRoute);
+                    __log.debug("INPUTMSG: " + correlatorId + ": ckeySet " + messageRoute.getCorrelationKeys() + " route is to " + messageRoute);
                 }
-                routingInfos.add(new RoutingInfo(messageRoute, messageRoute.getCorrelationKeySet(), correlator, keySet));
+                routingInfos.add(new RoutingInfo(messageRoute, messageRoute.getCorrelationKeys(), correlator, processKeys, uniqueKeys));
             }
         }
         
         if (routingInfos.size() == 0) {
-        	routingInfos.add(new RoutingInfo(null, null, correlator, keySet));
+        	routingInfos.add(new RoutingInfo(null, null, correlator, processKeys, uniqueKeys));
         }
 
         return routingInfos;
@@ -156,17 +158,18 @@
 
     class RoutingInfo {
         MessageRouteDAO messageRoute;
-        CorrelationKeySet matchedKeySet;
         CorrelatorDAO correlator;
-//        CorrelationKey[] keys;
-        CorrelationKeySet wholeKeySet;
+        CorrelationKeys matchedKeys;
+        CorrelationKeys wholeKeys;
+        CorrelationKeys uniqueKeys;
 
-        public RoutingInfo(MessageRouteDAO messageRoute, CorrelationKeySet matchedKeySet,
-                           CorrelatorDAO correlator, CorrelationKeySet wholeKeySet) {
+        public RoutingInfo(MessageRouteDAO messageRoute, CorrelationKeys matchedKeys,
+                           CorrelatorDAO correlator, CorrelationKeys wholeKeys, CorrelationKeys uniqueKeys) {
             this.messageRoute = messageRoute;
-            this.matchedKeySet = matchedKeySet;
+            this.matchedKeys = matchedKeys;
             this.correlator = correlator;
-            this.wholeKeySet = wholeKeySet;
+            this.wholeKeys = wholeKeys;
+            this.uniqueKeys = uniqueKeys;
         }
     }
 
@@ -186,7 +189,18 @@
             __log.debug("Not creating a new instance for mex " + mex + "; interceptor prevented!");
             return;
         }
-
+        
+        for (CorrelationKey uniqueKey : routing.uniqueKeys) {
+        	// double-check that the correlation set is indeed unique
+        	if (uniqueKey.isUnique()) {
+        		Collection<ProcessInstanceDAO> instances = processDAO.findInstance(uniqueKey, false);
+        		if (instances.size() != 0) {
+                    __log.debug("Not creating a new instance for mex " + mex + "; unique correlation constraint would be violated!");
+                    throw new InvalidProcessException("Unique process constraint violated", InvalidProcessException.DUPLICATE_CAUSE_CODE);
+        		}
+        	}        	
+        }
+        
         ProcessInstanceDAO newInstance = processDAO.createInstance(routing.correlator);
 
         BpelRuntimeContextImpl instance = _process
@@ -226,7 +240,7 @@
         // send process instance event
         CorrelationMatchEvent evt = new CorrelationMatchEvent(new QName(_process.getOProcess().targetNamespace,
                 _process.getOProcess().getName()), _process.getProcessDAO().getProcessId(),
-                instanceDao.getInstanceId(), routing.matchedKeySet);
+                instanceDao.getInstanceId(), routing.matchedKeys);
         evt.setPortType(mex.getPortType().getQName());
         evt.setOperation(operation.getName());
         evt.setMexId(mex.getMessageExchangeId());
@@ -255,7 +269,7 @@
 
 	            // send event
 	            CorrelationNoMatchEvent evt = new CorrelationNoMatchEvent(mex.getPortType().getQName(), mex
-	                    .getOperation().getName(), mex.getMessageExchangeId(), routing.wholeKeySet);
+	                    .getOperation().getName(), mex.getMessageExchangeId(), routing.wholeKeys);
 	
 	            evt.setProcessId(_process.getProcessDAO().getProcessId());
 	            evt.setProcessName(new QName(_process.getOProcess().targetNamespace, _process.getOProcess().getName()));
@@ -264,7 +278,7 @@
 	            mex.setCorrelationStatus(MyRoleMessageExchange.CorrelationStatus.QUEUED);
 	
 	            // No match, means we add message exchange to the queue.
-	            routing.correlator.enqueueMessage(mex.getDAO(), routing.wholeKeySet);
+	            routing.correlator.enqueueMessage(mex.getDAO(), routing.wholeKeys);
         	}
         }
     }
@@ -281,8 +295,8 @@
         return _plinkDef.getMyRoleOperation(operationName);
     }
 
-    private CorrelationKeySet computeCorrelationKeys(MyRoleMessageExchangeImpl mex) {
-        CorrelationKeySet keySet = new CorrelationKeySet();
+    private CorrelationKeys computeCorrelationKeys(MyRoleMessageExchangeImpl mex) {
+        CorrelationKeys keySet = new CorrelationKeys();
 
         Operation operation = mex.getOperation();
         Element msg = mex.getRequest().getMessage();
@@ -310,6 +324,23 @@
         return keySet;
     }
 
+    private CorrelationKeys computeUniqueCorrelationKeys(MyRoleMessageExchangeImpl mex) {
+        CorrelationKeys keySet = new CorrelationKeys();
+
+        Operation operation = mex.getOperation();
+        Element msg = mex.getRequest().getMessage();
+        javax.wsdl.Message msgDescription = operation.getInput().getMessage();
+
+        Set<OScope.CorrelationSet> csets = _plinkDef.getUniqueCorrelationSetsForOperation(operation);
+        for (OScope.CorrelationSet cset : csets) {
+            CorrelationKey key = computeCorrelationKey(cset,
+                    _process.getOProcess().messageTypes.get(msgDescription.getQName()), msg);
+            keySet.add(key);
+        }
+
+        return keySet;
+    }
+    
     @SuppressWarnings("unchecked")
     private CorrelationKey computeCorrelationKey(OScope.CorrelationSet cset, OMessageVarType messagetype,
             Element msg) {
@@ -346,6 +377,8 @@
         	key = new CorrelationKey(cset.getId(), values);
         }
         
+        key.setUnique(cset.unique);
+        
         return key;
     }
     

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/WorkEvent.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/WorkEvent.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/WorkEvent.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/engine/WorkEvent.java Fri Dec 19 13:09:17 2008
@@ -19,7 +19,7 @@
 
 package org.apache.ode.bpel.engine;
 
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 
 import javax.xml.namespace.QName;
 import java.util.HashMap;
@@ -93,11 +93,11 @@
         _jobDetail.put("correlatorId", correlatorId);
     }
     
-    public CorrelationKeySet getCorrelationKeySet() {
-        return new CorrelationKeySet((String) _jobDetail.get("ckeySet"));
+    public CorrelationKeys getCorrelationKeySet() {
+        return new CorrelationKeys((String) _jobDetail.get("ckeySet"));
     }
     
-    public void setCorrelationKeySet(CorrelationKeySet ckeySet) {
+    public void setCorrelationKeySet(CorrelationKeys ckeySet) {
         _jobDetail.put("ckeySet", ckeySet == null ? null : ckeySet.toCanonicalString());
     }
 

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/CorrelatorDaoImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/CorrelatorDaoImpl.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/CorrelatorDaoImpl.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/CorrelatorDaoImpl.java Fri Dec 19 13:09:17 2008
@@ -21,7 +21,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ode.bpel.common.CorrelationKey;
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 import org.apache.ode.bpel.dao.CorrelatorDAO;
 import org.apache.ode.bpel.dao.MessageExchangeDAO;
 import org.apache.ode.bpel.dao.MessageRouteDAO;
@@ -49,13 +49,13 @@
         _conn = conn;
     }
 
-    public MessageExchangeDAO dequeueMessage(CorrelationKeySet instanceKeySet) {
+    public MessageExchangeDAO dequeueMessage(CorrelationKeys instanceKeySet) {
         if (__log.isDebugEnabled()) {
             __log.debug("dequeueEarliest: MATCHING correlationKey=" + instanceKeySet);
         }
         for (Iterator<MsgQueueEntry> i = _messages.iterator(); i.hasNext();) {
             MsgQueueEntry mqe = i.next();
-            CorrelationKeySet aKeySet = mqe.keySet;
+            CorrelationKeys aKeySet = mqe.keySet;
             if (aKeySet.isRoutableTo(instanceKeySet, false)) {
                 i.remove();
                 return mqe.message;
@@ -67,7 +67,7 @@
         return null;
     }
 
-    public List<MessageRouteDAO> findRoute(CorrelationKeySet keySet) {
+    public List<MessageRouteDAO> findRoute(CorrelationKeys keySet) {
     	List<MessageRouteDAO> routes = new ArrayList<MessageRouteDAO>();
 
     	assert keySet != null;
@@ -96,7 +96,7 @@
         ((ProcessInstanceDaoImpl)target).removeRoutes(routeGroupId);
     }
 
-    public void enqueueMessage(MessageExchangeDAO mex, CorrelationKeySet keySet) {
+    public void enqueueMessage(MessageExchangeDAO mex, CorrelationKeys keySet) {
         if (__log.isDebugEnabled()) {
             __log.debug("enqueueProcessInvocation: data=" + mex + " keys=" + keySet);
         }
@@ -105,7 +105,7 @@
         _messages.add(mqe);
     }
 
-    public void addRoute(String routeId,ProcessInstanceDAO target, int idx, CorrelationKeySet keySet, String routePolicy) {
+    public void addRoute(String routeId,ProcessInstanceDAO target, int idx, CorrelationKeys keySet, String routePolicy) {
         if (__log.isDebugEnabled()) {
             __log.debug("addRoute: target=" + target + " correlationKeySet=" + keySet);
         }
@@ -149,10 +149,10 @@
 
     private class MsgQueueEntry {
         public final MessageExchangeDAO message;
-        public final CorrelationKeySet keySet;
+        public final CorrelationKeys keySet;
 
         private MsgQueueEntry(MessageExchangeDAO mex,
-                              CorrelationKeySet keySet) {
+                              CorrelationKeys keySet) {
             this.message = mex;
             this.keySet = keySet;
         }

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/MessageRouteDaoImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/MessageRouteDaoImpl.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/MessageRouteDaoImpl.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/MessageRouteDaoImpl.java Fri Dec 19 13:09:17 2008
@@ -18,7 +18,7 @@
  */
 package org.apache.ode.bpel.memdao;
 
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 import org.apache.ode.bpel.dao.MessageRouteDAO;
 import org.apache.ode.bpel.dao.ProcessInstanceDAO;
 
@@ -29,11 +29,11 @@
 class MessageRouteDaoImpl extends DaoBaseImpl implements MessageRouteDAO {
   ProcessInstanceDaoImpl _instance;
   String _groupId;
-  CorrelationKeySet _ckeySet;
+  CorrelationKeys _ckeySet;
   int _idx;
   String _route;
 
-  MessageRouteDaoImpl(ProcessInstanceDaoImpl owner, String groupId, CorrelationKeySet ckeySet, int idx, String routePolicy) {
+  MessageRouteDaoImpl(ProcessInstanceDaoImpl owner, String groupId, CorrelationKeys ckeySet, int idx, String routePolicy) {
     _instance = owner;
     _groupId = groupId;
     _ckeySet = ckeySet;
@@ -57,7 +57,7 @@
 	  return _route;
   }
   
-  public CorrelationKeySet getCorrelationKeySet() {
+  public CorrelationKeys getCorrelationKeys() {
 	  return _ckeySet;
   }
 }

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/ProcessDaoImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/ProcessDaoImpl.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/ProcessDaoImpl.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/memdao/ProcessDaoImpl.java Fri Dec 19 13:09:17 2008
@@ -131,7 +131,7 @@
         return _instances.get(instanceId);
     }
 
-    public Collection<ProcessInstanceDAO> findInstance(CorrelationKey key) {
+    public Collection<ProcessInstanceDAO> findInstance(CorrelationKey key, boolean wait) {
         ArrayList<ProcessInstanceDAO> result = new ArrayList<ProcessInstanceDAO>();
         for (ProcessInstanceDAO instance : _instances.values()) {
             for (CorrelationSetDAO corrSet : instance.getCorrelationSets()) {

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelJacobRunnable.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelJacobRunnable.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelJacobRunnable.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/BpelJacobRunnable.java Fri Dec 19 13:09:17 2008
@@ -98,6 +98,7 @@
         }
 
         CorrelationKey ckeyVal = new CorrelationKey(cset.declaration.getId(), propValues);
+        ckeyVal.setUnique(cset.declaration.unique);
         getBpelRuntimeContext().writeCorrelation(cset,ckeyVal);
     }
     

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EH_EVENT.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EH_EVENT.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EH_EVENT.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/EH_EVENT.java Fri Dec 19 13:09:17 2008
@@ -24,7 +24,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ode.bpel.common.CorrelationKey;
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 import org.apache.ode.bpel.common.FaultException;
 import org.apache.ode.bpel.o.OEventHandler;
 import org.apache.ode.bpel.o.OScope;
@@ -114,7 +114,7 @@
             Selector selector;
             try {
                 PickResponseChannel pickResponseChannel = newChannel(PickResponseChannel.class);
-                CorrelationKeySet keySet = new CorrelationKeySet();
+                CorrelationKeys keySet = new CorrelationKeys();
                 PartnerLinkInstance pLinkInstance = _scopeFrame.resolve(_oevent.partnerLink);
                 for( OScope.CorrelationSet cset : _oevent.joinCorrelations ) {
                 	if(getBpelRuntimeContext().isCorrelationInitialized(_scopeFrame.resolve(cset))) {

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/InvalidProcessException.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/InvalidProcessException.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/InvalidProcessException.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/InvalidProcessException.java Fri Dec 19 13:09:17 2008
@@ -31,6 +31,8 @@
 
     public final static int RETIRED_CAUSE_CODE = 1;
 
+    public final static int DUPLICATE_CAUSE_CODE = 2;
+    
     private final int causeCode;
 
     public InvalidProcessException(String msg, Throwable cause) {

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/PICK.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/PICK.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/PICK.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/PICK.java Fri Dec 19 13:09:17 2008
@@ -29,7 +29,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ode.bpel.common.CorrelationKey;
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 import org.apache.ode.bpel.common.FaultException;
 import org.apache.ode.bpel.evt.VariableModificationEvent;
 import org.apache.ode.bpel.explang.EvaluationException;
@@ -90,7 +90,7 @@
             	}
 
                 PartnerLinkInstance pLinkInstance = _scopeFrame.resolve(onMessage.partnerLink);
-                CorrelationKeySet keySet = resolveCorrelationKey(pLinkInstance, matchCorrelations);
+                CorrelationKeys keySet = resolveCorrelationKey(pLinkInstance, matchCorrelations);
 
                 selectors[idx] = new Selector(idx, pLinkInstance, onMessage.operation.getName(), onMessage.operation
                         .getOutput() == null, onMessage.messageExchangeId, keySet, onMessage.route);
@@ -139,8 +139,8 @@
      * @return returns the resolved CorrelationKey
      * @throws FaultException thrown when the correlation is not initialized and createInstance flag is not set
      */
-    private CorrelationKeySet resolveCorrelationKey(PartnerLinkInstance pLinkInstance, Set<OScope.CorrelationSet> matchCorrelations) throws FaultException {
-        CorrelationKeySet keySet = new CorrelationKeySet(); // is empty for the case of the createInstance activity
+    private CorrelationKeys resolveCorrelationKey(PartnerLinkInstance pLinkInstance, Set<OScope.CorrelationSet> matchCorrelations) throws FaultException {
+        CorrelationKeys keySet = new CorrelationKeys(); // is empty for the case of the createInstance activity
 
         if (matchCorrelations.isEmpty() && !_opick.createInstanceFlag) {
             // Adding a route for opaque correlation. In this case,

Modified: ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/Selector.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/Selector.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/Selector.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/runtime/Selector.java Fri Dec 19 13:09:17 2008
@@ -19,7 +19,7 @@
 package org.apache.ode.bpel.runtime;
 
 import org.apache.ode.bpel.common.CorrelationKey;
-import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.common.CorrelationKeys;
 import org.apache.ode.utils.ObjectPrinter;
 
 import java.io.Serializable;
@@ -31,14 +31,14 @@
 	// here for the backward compatibility
 	@SuppressWarnings("unused")
 	private final CorrelationKey correlationKey = null;
-  public final CorrelationKeySet correlationKeySet;
+  public final CorrelationKeys correlationKeySet;
   public final String opName;
   public final String messageExchangeId;
   public final int idx;
   public final boolean oneWay;
   public final String route;
 
-  Selector(int idx, PartnerLinkInstance plinkInstance, String opName, boolean oneWay, String mexId, CorrelationKeySet keySet, String route) {
+  Selector(int idx, PartnerLinkInstance plinkInstance, String opName, boolean oneWay, String mexId, CorrelationKeys keySet, String route) {
     this.idx = idx;
     this.plinkInstance = plinkInstance;
     this.correlationKeySet = keySet;

Modified: ode/branches/APACHE_ODE_1.X/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java Fri Dec 19 13:09:17 2008
@@ -253,8 +253,21 @@
         inv.request = DOMUtils.stringToDOM(request);
         inv.expectedStatus = null;
         if (responsePattern != null) {
-            inv.expectedFinalStatus = MessageExchange.Status.RESPONSE;
-            inv.expectedResponsePattern = Pattern.compile(responsePattern, Pattern.DOTALL);
+            if ("ASYNC".equals(responsePattern)) {
+            	inv.expectedFinalStatus = MessageExchange.Status.ASYNC;
+            	inv.expectedResponsePattern = null;
+            } else if ("FAULT".equals(responsePattern)) {
+            	inv.expectedFinalStatus = MessageExchange.Status.COMPLETED_FAULT;
+            	inv.expectedResponsePattern = null;
+            } else if ("FAILURE".equals(responsePattern)) {
+            	inv.expectedFinalStatus = MessageExchange.Status.COMPLETED_FAILURE;
+            	inv.expectedResponsePattern = null;
+            } else {
+                inv.expectedResponsePattern = Pattern.compile(responsePattern, Pattern.DOTALL);
+                inv.expectedFinalStatus = MessageExchange.Status.RESPONSE;
+            }        
+        } else {
+        	inv.expectedFinalStatus = MessageExchange.Status.RESPONSE;
         }
 
         _invocations.add(inv);
@@ -353,6 +366,7 @@
             store.undeploy(d.deployDir);
         }
     }
+
     protected void doInvokes() throws Exception {
         ArrayList<Thread> testThreads = new ArrayList<Thread>();
         for (Invocation i : _invocations) {
@@ -370,6 +384,14 @@
 
     }
     
+    protected int getMaximumWaitInMillis() {
+    	return 60 * 1000;
+    }
+
+    protected int getMinimumWaitInMillis() {
+    	return -1;
+    }
+   
     protected long getWaitBeforeInvokeTimeout() {
     	return WAIT_BEFORE_INVOKE_TIMEOUT;
     }
@@ -521,8 +543,8 @@
         /** Maximum number of ms to wait for a response. */
         public long maximumWaitMs = 60 * 1000;
 
-        /** If non-null, minimum number of ms before a response should be available. */
-        public Long minimumWaitMs = null;
+        /** If positive, minimum number of ms before a response should be available. */
+        public long minimumWaitMs = -1;
 
         long invokeTime;
 
@@ -545,6 +567,8 @@
 
         InvokerThread(Invocation invocation) {
             _invocation = invocation;
+            _invocation.maximumWaitMs = getMaximumWaitInMillis();
+            _invocation.minimumWaitMs = getMinimumWaitInMillis();
         }
 
         public void run() {
@@ -598,7 +622,7 @@
 
             long ctime = System.currentTimeMillis();
             long itime = ctime - _invocation.invokeTime;
-            if (_invocation.minimumWaitMs != null && _invocation.minimumWaitMs >= itime)
+            if (_invocation.minimumWaitMs != -1 && _invocation.minimumWaitMs >= itime)
                 failure(_invocation, "Response received too soon.", _invocation.minimumWaitMs, itime);
 
             if (_invocation.maximumWaitMs <= itime)

Modified: ode/branches/APACHE_ODE_1.X/bpel-test/src/test/java/org/apache/ode/test/MessageRouting20Test.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-test/src/test/java/org/apache/ode/test/MessageRouting20Test.java?rev=728144&r1=728143&r2=728144&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-test/src/test/java/org/apache/ode/test/MessageRouting20Test.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-test/src/test/java/org/apache/ode/test/MessageRouting20Test.java Fri Dec 19 13:09:17 2008
@@ -128,4 +128,7 @@
         go("/bpel/2.0/TestConcurrentSyncMex");
     }
 
+    @Test public void testCorrelationUnique() throws Throwable {
+        go("/bpel/2.0/TestCorrelationUnique");
+    }
 }

Added: ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/counter.bpel
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/counter.bpel?rev=728144&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/counter.bpel (added)
+++ ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/counter.bpel Fri Dec 19 13:09:17 2008
@@ -0,0 +1,98 @@
+<?xml version="1.0"?>
+<b:process xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+	   xsi:schemaLocation="http://docs.oasis-open.org/wsbpel/2.0/process/executable http://docs.oasis-open.org/wsbpel/2.0/CS01/process/executable/ws-bpel_executable.xsd"
+	   xmlns:b="http://docs.oasis-open.org/wsbpel/2.0/process/executable"
+	   name="counter"
+	   xmlns:t="http://example.com/bpel/counter"
+	   targetNamespace="http://example.com/bpel/counter">
+  
+  <b:import importType="http://schemas.xmlsoap.org/wsdl/"
+	    location="counter.wsdl"
+	    namespace="http://example.com/bpel/counter" />
+  
+  <b:partnerLinks>
+    <b:partnerLink name="operations" partnerLinkType="t:plink" myRole="me" />
+  </b:partnerLinks>
+  
+  <b:variables>
+    <b:variable name="counter" messageType="t:responseMessage" />
+    <b:variable name="initiation" messageType="t:requestMessage" />
+    <b:variable name="empty" messageType="t:emptyResponse" />
+  </b:variables>
+  
+  <b:correlationSets>
+    <b:correlationSet name="name" properties="t:counterProp" unique="yes"/>
+  </b:correlationSets>
+  
+  <b:sequence>
+    <b:receive partnerLink="operations" createInstance="yes" operation="init" portType="t:port"
+        variable="initiation">
+      <b:correlations>
+        <b:correlation set="name" initiate="yes"/>
+      </b:correlations>
+    </b:receive>
+    <b:assign>
+      <b:copy>
+        <b:from>0</b:from>
+        <b:to variable="counter" part="value"></b:to>
+      </b:copy>
+    </b:assign>
+    <b:reply partnerLink="operations" operation="init" variable="empty" />
+    <b:flow>
+      <b:while>
+        <b:condition>true()</b:condition>
+          <b:scope>
+            <b:variables>
+              <b:variable name="tmp" messageType="t:requestMessage" />
+            </b:variables>
+            <b:sequence>
+              <b:receive partnerLink="operations" operation="getAndIncrement" portType="t:port"
+                  variable="tmp">
+                <b:correlations>
+                  <b:correlation set="name" initiate="no" />
+                </b:correlations>
+              </b:receive>          
+              <b:reply partnerLink="operations" operation="getAndIncrement" variable="counter" />
+              <b:assign>
+                <b:copy>
+                  <b:from>$counter.value+1</b:from>
+                  <b:to>$counter.value</b:to>
+                </b:copy>
+              </b:assign>          
+            </b:sequence>
+          </b:scope>
+      </b:while>
+      <b:while>
+        <b:condition>true()</b:condition>
+        <b:scope>
+          <b:variables>
+            <b:variable name="tmp" messageType="t:requestMessage" />
+          </b:variables>
+          <b:sequence>
+            <b:receive partnerLink="operations" operation="get" variable="tmp">
+              <b:correlations>
+                <b:correlation set="name" initiate="no" />
+              </b:correlations>            
+            </b:receive>
+            <b:reply partnerLink="operations" operation="get" variable="counter" />
+          </b:sequence>
+        </b:scope>
+      </b:while>
+        <b:scope>
+          <b:variables>
+            <b:variable name="tmp" messageType="t:requestMessage" />
+          </b:variables>          
+          <b:sequence>
+            <b:receive partnerLink="operations" operation="close" variable="tmp">
+              <b:correlations>
+                <b:correlation set="name" initiate="no" />
+              </b:correlations>
+            </b:receive>
+            <b:reply partnerLink="operations" operation="close" variable="empty"/>
+            <b:exit />
+          </b:sequence>
+        </b:scope>
+    </b:flow>
+  </b:sequence>
+</b:process>

Added: ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/counter.wsdl
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/counter.wsdl?rev=728144&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/counter.wsdl (added)
+++ ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestCorrelationUnique/counter.wsdl Fri Dec 19 13:09:17 2008
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+  targetNamespace="http://example.com/bpel/counter" 
+  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xmlns:p="http://docs.oasis-open.org/wsbpel/2.0/plnktype"
+  xmlns:v="http://docs.oasis-open.org/wsbpel/2.0/varprop"
+  xmlns:t="http://example.com/bpel/counter">
+  
+  <wsdl:message name="requestMessage">
+    <wsdl:part name="name" type="xsd:string" />
+  </wsdl:message>
+  
+  <wsdl:message name="responseMessage">
+    <wsdl:part name="value" type="xsd:int" />
+  </wsdl:message>
+  
+  <wsdl:message name="emptyResponse" />
+  
+  <wsdl:portType name="port">
+    <wsdl:operation name="init">
+      <wsdl:input message="t:requestMessage" />
+      <wsdl:output message="t:emptyResponse" />
+    </wsdl:operation>
+    <wsdl:operation name="get">
+      <wsdl:input message="t:requestMessage" />
+      <wsdl:output message="t:responseMessage" />
+    </wsdl:operation>
+    <wsdl:operation name="getAndIncrement">
+      <wsdl:input message="t:requestMessage" />
+      <wsdl:output message="t:responseMessage" />
+    </wsdl:operation>
+    <wsdl:operation name="close">
+      <wsdl:input message="t:requestMessage" />
+      <wsdl:output message="t:emptyResponse" />
+    </wsdl:operation>
+  </wsdl:portType>
+  
+  <wsdl:binding name="binding" type="t:port">
+    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
+    <wsdl:operation name="init">
+      <soap:operation soapAction="" style="rpc"/>
+      <wsdl:input>
+        <soap:body namespace="http://example.com/bpel/counter" use="literal"/>
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body namespace="http://example.com/bpel/counter" use="literal"/>
+      </wsdl:output>
+    </wsdl:operation>
+    <wsdl:operation name="get">
+      <soap:operation soapAction="" style="rpc"/>
+      <wsdl:input>
+        <soap:body namespace="http://example.com/bpel/counter" use="literal"/>
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body namespace="http://example.com/bpel/counter" use="literal"/>
+      </wsdl:output>
+    </wsdl:operation>
+    <wsdl:operation name="getAndIncrement">
+      <soap:operation soapAction="" style="rpc"/>
+      <wsdl:input>
+        <soap:body namespace="http://example.com/bpel/counter" use="literal"/>
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body namespace="http://example.com/bpel/counter" use="literal"/>
+      </wsdl:output>
+    </wsdl:operation>
+  </wsdl:binding>
+  <wsdl:service name="counter">
+    <wsdl:port name="port" binding="t:binding">
+      <soap:address location="http://localhost:8080/ode/processes/counter"/>
+    </wsdl:port>
+  </wsdl:service>
+  
+  <p:partnerLinkType name="plink">
+    <p:role name="me" portType="t:port" />
+    <p:role name="you" portType="t:port" />
+  </p:partnerLinkType>
+  
+  <v:property name="counterProp" type="xsd:string" />
+  
+  <v:propertyAlias propertyName="t:counterProp" part="name" messageType="t:requestMessage" />
+</wsdl:definitions>
\ No newline at end of file