You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by sa...@apache.org on 2018/01/30 10:20:48 UTC

[02/14] ode git commit: Port extension activity and extension assign operation support from ODE 2.0 alpha branch

Port extension activity and extension assign operation support from ODE 2.0 alpha branch


Project: http://git-wip-us.apache.org/repos/asf/ode/repo
Commit: http://git-wip-us.apache.org/repos/asf/ode/commit/acb7e8ee
Tree: http://git-wip-us.apache.org/repos/asf/ode/tree/acb7e8ee
Diff: http://git-wip-us.apache.org/repos/asf/ode/diff/acb7e8ee

Branch: refs/heads/master
Commit: acb7e8ee5267a08898b3ad20a3fe6862f66cbb9b
Parents: a3df12d
Author: hahnml <ha...@users.noreply.github.com>
Authored: Wed Nov 29 14:16:54 2017 +0100
Committer: hahnml <ha...@users.noreply.github.com>
Committed: Wed Nov 29 14:16:54 2017 +0100

----------------------------------------------------------------------
 .gitignore                                      |   2 +
 .../webapp/WEB-INF/conf/ode-axis2.properties    |   5 +
 .../java/org/apache/ode/axis2/ODEServer.java    |  87 ++++++++
 .../ode/bpel/extension/ExtensibleElement.java   |  32 +++
 .../bpel/extension/ExtensionBundleRuntime.java  |  12 +
 .../extension/ExtensionBundleValidation.java    |  13 ++
 .../ode/bpel/extension/ExtensionOperation.java  |  54 +++++
 .../ode/bpel/extension/ExtensionValidator.java  |  38 ++++
 .../ode/bpel/compiler/AssignGenerator.java      |  43 +++-
 .../bpel/compiler/AssignGeneratorMessages.java  |  14 ++
 .../org/apache/ode/bpel/compiler/BpelC.java     |  14 ++
 .../apache/ode/bpel/compiler/BpelCompiler.java  |  70 +++++-
 .../ode/bpel/compiler/BpelCompiler20.java       |   2 +
 .../ode/bpel/compiler/BpelCompiler20Draft.java  |   2 +
 .../ExtensionActivityGeneratorMessages.java     |  43 ++++
 .../compiler/ExtensionActivtityGenerator.java   |  86 ++++++++
 .../ode/bpel/compiler/api/CompilerContext.java  |   5 +
 .../ode/bpel/compiler/bom/AssignActivity.java   |  35 +++
 .../ode/bpel/compiler/bom/Bpel20QNames.java     |   8 +
 .../bpel/compiler/bom/BpelObjectFactory.java    |   8 +
 .../org/apache/ode/bpel/compiler/bom/Copy.java  |   3 +-
 .../apache/ode/bpel/compiler/bom/Extension.java |  41 ++++
 .../bpel/compiler/bom/ExtensionActivity.java    | 104 +++++++++
 .../compiler/bom/ExtensionAssignOperation.java  |  58 +++++
 .../ode/bpel/compiler/bom/Extensions.java       |  34 +++
 .../apache/ode/bpel/compiler/bom/Process.java   |  13 ++
 .../org/apache/ode/bpel/compiler/XPathTest.java |   9 +
 .../ode/il/config/OdeConfigProperties.java      |  11 +
 .../java/org/apache/ode/bpel/obj/OAssign.java   | 118 ++++++++--
 .../apache/ode/bpel/obj/OExtensionActivity.java | 102 +++++++++
 .../java/org/apache/ode/bpel/obj/OProcess.java  |  78 ++++++-
 .../java/org/apache/ode/bpel/o/OAssign.java     |  60 ++++-
 .../apache/ode/bpel/o/OExtensionActivity.java   |  45 ++++
 .../java/org/apache/ode/bpel/o/OProcess.java    |  24 +-
 .../org/apache/ode/bpel/engine/BpelProcess.java |  29 ++-
 .../ode/bpel/engine/BpelRuntimeContextImpl.java |  16 ++
 .../apache/ode/bpel/engine/BpelServerImpl.java  |  12 +
 .../org/apache/ode/bpel/engine/Contexts.java    |   6 +
 .../org/apache/ode/bpel/engine/Messages.java    |   5 +
 .../org/apache/ode/bpel/runtime/ASSIGN.java     |  76 +++++--
 .../bpel/runtime/ActivityTemplateFactory.java   |   1 +
 .../ode/bpel/runtime/BpelRuntimeContext.java    |  10 +
 .../ode/bpel/runtime/EXTENSIONACTIVITY.java     |  98 +++++++++
 .../ode/bpel/runtime/ExtensionContextImpl.java  | 218 +++++++++++++++++++
 .../AbstractAsyncExtensionOperation.java        |  36 +++
 .../extension/AbstractExtensionBundle.java      | 109 ++++++++++
 .../AbstractSyncExtensionOperation.java         |  45 ++++
 .../common/extension/ExtensibilityQNames.java   |  58 +++++
 .../common/extension/ExtensionContext.java      | 190 ++++++++++++++++
 .../xpath20/runtime/MockCompilerContext.java    |  12 +
 .../apache/ode/bpel/runtime/CoreBpelTest.java   |  17 ++
 .../org/apache/ode/store/DeploymentUnitDir.java |   8 +
 .../org/apache/ode/store/ProcessStoreImpl.java  |  13 +-
 .../java/org/apache/ode/jbi/OdeLifeCycle.java   |  60 +++++
 .../java/org/apache/ode/utils/DOMUtils.java     |   4 +
 55 files changed, 2237 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 27225ba..c7cf71d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,5 @@ derby.log
 Gemfile.lock
 spoon
 *.log
+.m2/
+tmp/

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/axis2-war/src/main/webapp/WEB-INF/conf/ode-axis2.properties
----------------------------------------------------------------------
diff --git a/axis2-war/src/main/webapp/WEB-INF/conf/ode-axis2.properties b/axis2-war/src/main/webapp/WEB-INF/conf/ode-axis2.properties
index 03ac79c..3c61926 100644
--- a/axis2-war/src/main/webapp/WEB-INF/conf/ode-axis2.properties
+++ b/axis2-war/src/main/webapp/WEB-INF/conf/ode-axis2.properties
@@ -101,3 +101,8 @@ ode-axis2.db.emb.name=derby-jpadb
 
 ## Clustering Implementation class.
 #ode-axis2.clustering.impl.class = org.apache.ode.clustering.hazelcast.HazelcastClusterImpl
+
+## Extension Bundles
+## FQCNs, comma separated.
+#ode-axis2.extension.bundles.runtime=[packageName].[bundleClassName]
+#ode-axis2.extension.bundles.validation=[packageName].[bundleClassName]

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java
----------------------------------------------------------------------
diff --git a/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java b/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java
index e002695..347f44c 100644
--- a/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java
+++ b/axis2/src/main/java/org/apache/ode/axis2/ODEServer.java
@@ -38,12 +38,16 @@ import org.apache.ode.bpel.dao.BpelDAOConnectionFactory;
 import org.apache.ode.bpel.engine.BpelServerImpl;
 import org.apache.ode.bpel.engine.CountLRUDehydrationPolicy;
 import org.apache.ode.bpel.engine.cron.CronScheduler;
+import org.apache.ode.bpel.extension.ExtensionBundleRuntime;
+import org.apache.ode.bpel.extension.ExtensionBundleValidation;
+import org.apache.ode.bpel.extension.ExtensionValidator;
 import org.apache.ode.bpel.extvar.jdbc.JdbcExternalVariableModule;
 import org.apache.ode.bpel.iapi.*;
 import org.apache.ode.bpel.intercept.MessageExchangeInterceptor;
 import org.apache.ode.bpel.memdao.BpelDAOConnectionFactoryImpl;
 import org.apache.ode.bpel.pmapi.InstanceManagement;
 import org.apache.ode.bpel.pmapi.ProcessManagement;
+import org.apache.ode.bpel.runtime.common.extension.AbstractExtensionBundle;
 import org.apache.ode.il.config.OdeConfigProperties;
 import org.apache.ode.il.dbutil.Database;
 import org.apache.ode.scheduler.simple.JdbcDelegate;
@@ -58,6 +62,8 @@ import javax.servlet.ServletException;
 import javax.sql.DataSource;
 import javax.transaction.*;
 import javax.transaction.xa.XAResource;
+import javax.xml.namespace.QName;
+
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -195,6 +201,7 @@ public class ODEServer {
         registerEventListeners();
         registerMexInterceptors();
         registerExternalVariableModules();
+        registerExtensionActivityBundles();
 
         _store.loadAll();
         if (_clusterManager != null) {
@@ -691,6 +698,86 @@ public class ODEServer {
 
     }
 
+    // Add support for extension bundles based on ODE 2.0 alpha branch
+    private void registerExtensionActivityBundles() {
+		String extensionsRTStr = _odeConfig.getExtensionActivityBundlesRT();
+		String extensionsValStr = _odeConfig
+				.getExtensionActivityBundlesValidation();
+		if (extensionsRTStr != null) {
+			// TODO replace StringTokenizer by regex
+			for (StringTokenizer tokenizer = new StringTokenizer(
+					extensionsRTStr, ",;"); tokenizer.hasMoreTokens();) {
+				String bundleCN = tokenizer.nextToken();
+				
+				//@hahnml: Remove any whitespaces
+				bundleCN = bundleCN.replaceAll(" ", "");
+				
+				try {
+					// instantiate bundle
+					ExtensionBundleRuntime bundleRT = (ExtensionBundleRuntime) Class
+							.forName(bundleCN).newInstance();
+					
+					// register extension bundle (BPEL server)
+					_bpelServer.registerExtensionBundle(bundleRT);
+					
+					if (bundleRT instanceof AbstractExtensionBundle) {
+						AbstractExtensionBundle bundle = (AbstractExtensionBundle) bundleRT;
+						
+						//@hahnml: Get the registered validators from the process store
+						Map<QName, ExtensionValidator> validators = _store.getExtensionValidators();
+						
+						//Add the validators of this bundle to the existing validators
+						validators.putAll(bundle.getExtensionValidators());
+						
+						// register extension bundle (BPEL store)
+						_store.setExtensionValidators(validators);
+					}
+				} catch (Exception e) {
+					__log.warn("Couldn't register the extension bundle runtime "
+							+ bundleCN
+							+ ", the class couldn't be "
+							+ "loaded properly.");
+				}
+			}
+		}
+		if (extensionsValStr != null) {
+			Map<QName, ExtensionValidator> validators = new HashMap<QName, ExtensionValidator>();
+			for (StringTokenizer tokenizer = new StringTokenizer(
+					extensionsValStr, ",;"); tokenizer.hasMoreTokens();) {
+				String bundleCN = tokenizer.nextToken();
+				
+				//@hahnml: Remove any whitespaces
+				bundleCN = bundleCN.replaceAll(" ", "");
+				
+				try {
+					// instantiate bundle
+					ExtensionBundleValidation bundleVal = (ExtensionBundleValidation) Class
+							.forName(bundleCN).newInstance();
+					// add validators
+					validators.putAll(bundleVal.getExtensionValidators());
+				} catch (Exception e) {
+					__log.warn("Couldn't register the extension bundle validator "
+							+ bundleCN
+							+ ", the class couldn't be "
+							+ "loaded properly.");
+				}
+			}
+			// register extension bundle (BPEL store)
+			//@hahnml: Check if validators are registered already
+			if (_store.getExtensionValidators().isEmpty()) {
+				_store.setExtensionValidators(validators);
+			} else {
+				//@hahnml: Get the registered validators from the process store
+				Map<QName, ExtensionValidator> allValidators = _store.getExtensionValidators();
+				
+				//Add the registered validators to the existing validators
+				allValidators.putAll(validators);
+				
+				// register extension bundle (BPEL store)
+				_store.setExtensionValidators(allValidators);
+			}
+		}
+	}
     private class ProcessStoreListenerImpl implements ProcessStoreListener {
 
         public void onProcessStoreEvent(ProcessStoreEvent event) {

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensibleElement.java
----------------------------------------------------------------------
diff --git a/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensibleElement.java b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensibleElement.java
new file mode 100644
index 0000000..f7922d4
--- /dev/null
+++ b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensibleElement.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.extension;
+
+import org.w3c.dom.Element;
+
+/**
+ * Common interface for ExtensionActivity and AssignExtensionOperation.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public interface ExtensibleElement {
+
+	Element getNestedElement();
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleRuntime.java
----------------------------------------------------------------------
diff --git a/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleRuntime.java b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleRuntime.java
new file mode 100644
index 0000000..2ddf3ac
--- /dev/null
+++ b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleRuntime.java
@@ -0,0 +1,12 @@
+package org.apache.ode.bpel.extension;
+
+public interface ExtensionBundleRuntime {
+
+	String getNamespaceURI();
+
+	void registerExtensionActivities();
+
+	ExtensionOperation getExtensionOperationInstance(String localName)
+			throws InstantiationException, IllegalAccessException;
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleValidation.java
----------------------------------------------------------------------
diff --git a/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleValidation.java b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleValidation.java
new file mode 100644
index 0000000..f12cf14
--- /dev/null
+++ b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionBundleValidation.java
@@ -0,0 +1,13 @@
+package org.apache.ode.bpel.extension;
+
+import javax.xml.namespace.QName;
+import java.util.Map;
+
+/**
+ * Compile-time validation of extensions implemented by your bundle.
+ */
+public interface ExtensionBundleValidation {
+
+	Map<QName, ExtensionValidator> getExtensionValidators();
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionOperation.java
----------------------------------------------------------------------
diff --git a/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionOperation.java b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionOperation.java
new file mode 100644
index 0000000..da1c930
--- /dev/null
+++ b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionOperation.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.extension;
+
+import org.apache.ode.bpel.common.FaultException;
+import org.w3c.dom.Element;
+
+/**
+ * This is the basis interface for implementations of
+ * <code>&lt;extensionAssignOperation&gt;</code> and
+ * <code>&lt;extensionActivity&gt;</code> nodes.
+ * 
+ * Implementations of this interface must provide a default constructor as they
+ * are created using reflection.
+ * 
+ * @see AbstractExtensionBundle
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public interface ExtensionOperation {
+
+	/**
+	 * Provides the runtime implementation.
+	 * 
+	 * <strong>Note:</strong> This method MAY run concurrently. Since Xerces'
+	 * DOM implementation is not thread-safe, please make sure to synchronize
+	 * the access to <code>element</code> if necessary.
+	 * 
+	 * @param context
+	 *            injected ExtensionContext
+	 * @param element
+	 *            the extension element (child of <code>extensionActivity</code>
+	 *            or <code>extensionAssignOperation</code>
+	 * @throws FaultException
+	 */
+	void run(Object context, Element element) throws FaultException;
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionValidator.java
----------------------------------------------------------------------
diff --git a/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionValidator.java b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionValidator.java
new file mode 100644
index 0000000..5159c1b
--- /dev/null
+++ b/bpel-api/src/main/java/org/apache/ode/bpel/extension/ExtensionValidator.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.extension;
+
+import org.apache.ode.bpel.extension.ExtensibleElement;
+
+/**
+ * Interface that allows Ode extensions to validate an extension element's
+ * content during compilation.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public interface ExtensionValidator {
+
+	/**
+	 * 
+	 * @param compilerContext
+	 * @param element
+	 */
+	void validate(Object compilerContext, ExtensibleElement element);
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGenerator.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGenerator.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGenerator.java
index a2b5f25..91a6384 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGenerator.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGenerator.java
@@ -23,7 +23,9 @@ import org.slf4j.LoggerFactory;
 import org.apache.ode.bpel.compiler.api.CompilationException;
 import org.apache.ode.bpel.compiler.bom.Activity;
 import org.apache.ode.bpel.compiler.bom.AssignActivity;
+import org.apache.ode.bpel.compiler.bom.AssignActivity.AssignOperation;
 import org.apache.ode.bpel.compiler.bom.Copy;
+import org.apache.ode.bpel.compiler.bom.ExtensionAssignOperation;
 import org.apache.ode.bpel.compiler.bom.ExtensionVal;
 import org.apache.ode.bpel.compiler.bom.From;
 import org.apache.ode.bpel.compiler.bom.LiteralVal;
@@ -31,6 +33,7 @@ import org.apache.ode.bpel.compiler.bom.PartnerLinkVal;
 import org.apache.ode.bpel.compiler.bom.PropertyVal;
 import org.apache.ode.bpel.compiler.bom.To;
 import org.apache.ode.bpel.compiler.bom.VariableVal;
+import org.apache.ode.bpel.extension.ExtensionValidator;
 import org.apache.ode.bpel.obj.DebugInfo;
 import org.apache.ode.bpel.obj.OActivity;
 import org.apache.ode.bpel.obj.OAssign;
@@ -62,7 +65,9 @@ class AssignGenerator extends DefaultActivityGenerator {
     public void compile(OActivity dest, Activity source) {
         OAssign oassign = (OAssign) dest;
         AssignActivity ad = (AssignActivity) source;
-        for (Copy scopy : ad.getCopies()) {
+		for (AssignOperation operation : ad.getOperations()) {
+			if (operation instanceof Copy) {
+				Copy scopy = (Copy) operation;
             OAssign.Copy ocopy = new OAssign.Copy(_context.getOProcess());
             ocopy.setKeepSrcElementName(scopy.isKeepSrcElement());
             ocopy.setIgnoreMissingFromData(scopy.isIgnoreMissingFromData());
@@ -81,11 +86,45 @@ class AssignGenerator extends DefaultActivityGenerator {
                 ocopy.setFrom(compileFrom(scopy.getFrom(), toResultType[0]));
 
                 verifyCopy(ocopy);
-                oassign.getCopy().add(ocopy);
+                oassign.getOperations().add(ocopy);
 
             } catch (CompilationException ce) {
                 _context.recoveredFromError(scopy, ce);
             }
+			} else if (operation instanceof ExtensionAssignOperation) {
+				ExtensionAssignOperation sop = (ExtensionAssignOperation) operation;
+				OAssign.ExtensionAssignOperation oext = new OAssign.ExtensionAssignOperation(
+						_context.getOProcess());
+				oext.setDebugInfo(new DebugInfo(_context.getSourceLocation(),
+						sop.getLineNo(), source.getExtensibilityElements()));
+				try {
+					if (source.is20Draft()) {
+						throw new CompilationException(
+								__cmsgs.errExtensibleAssignNotSupported());
+					}
+					Element el = sop.getNestedElement();
+					if (el == null) {
+						throw new CompilationException(__cmsgs
+								.errMissingExtensionAssignOperationElement()
+								.setSource(sop));
+					}
+					if (!_context.isExtensionDeclared(el.getNamespaceURI())) {
+						throw new CompilationException(__cmsgs
+								.errUndeclaredExtensionAssignOperation()
+								.setSource(sop));
+					}
+					ExtensionValidator validator = _context
+							.getExtensionValidator(DOMUtils.getElementQName(el));
+					if (validator != null) {
+						validator.validate(_context, sop);
+					}
+					oext.setExtensionName(DOMUtils.getElementQName(el));
+					oext.setNestedElement(DOMUtils.domToString(el));
+					oassign.getOperations().add(oext);
+				} catch (CompilationException ce) {
+					_context.recoveredFromError(sop, ce);
+				}
+			}
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGeneratorMessages.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGeneratorMessages.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGeneratorMessages.java
index 74252dc..abef091 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGeneratorMessages.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/AssignGeneratorMessages.java
@@ -86,4 +86,18 @@ public class AssignGeneratorMessages extends CompilationMessageBundle {
         return this.formatCompilationMessage("To-spec format is unrecognized.");
     }
 
+    /**ExtensionAssignOperation's nested element missing*/
+    public CompilationMessage errMissingExtensionAssignOperationElement(){
+    	return this.formatCompilationMessage("Extensibility element in <extensionAssignOperation> is missing.");
+    }
+
+    /**ExtensionAssignOperation's nested element missing*/
+    public CompilationMessage errUndeclaredExtensionAssignOperation(){
+    	return this.formatCompilationMessage("Extension namespace of <extensionAssignOperation> has not been declared.");
+    }
+
+    /**Draft extensibleAssign is not supported.*/
+    public CompilationMessage errExtensibleAssignNotSupported(){
+    	return this.formatCompilationMessage("ExtensibleAssign is not supported, please upgrade to BPEL 2.0 final.");
+    }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelC.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelC.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelC.java
index ff1bd34..71cb107 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelC.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelC.java
@@ -38,6 +38,7 @@ import org.apache.ode.bpel.compiler.api.CompileListener;
 import org.apache.ode.bpel.compiler.api.SourceLocation;
 import org.apache.ode.bpel.compiler.bom.BpelObjectFactory;
 import org.apache.ode.bpel.compiler.bom.Process;
+import org.apache.ode.bpel.extension.ExtensionValidator;
 import org.apache.ode.bpel.obj.OProcess;
 import org.apache.ode.bpel.obj.OProcessWrapper;
 import org.apache.ode.bpel.obj.serde.DeSerializer;
@@ -72,6 +73,8 @@ public class BpelC {
     private Map<String,Object> _compileProperties;
     private boolean _dryRun = false;
 
+    private Map<QName, ExtensionValidator> _extensionValidators;
+
     public static BpelC newBpelCompiler() {
         return new BpelC();
     }
@@ -252,6 +255,9 @@ public class BpelC {
                 if (_compileProperties.get(PROCESS_CUSTOM_PROPERTIES) != null)
                     compiler.setCustomProperties((Map<QName, Node>) _compileProperties.get(PROCESS_CUSTOM_PROPERTIES));
             }
+            if (_extensionValidators != null) {
+            	compiler.setExtensionValidators(_extensionValidators);
+            }
         } catch (CompilationException ce) {
             this.invalidate();
             throw ce;
@@ -523,4 +529,12 @@ public class BpelC {
         }
     }
 
+    /**
+     * Registers extension validators to eventually validate the content of extensibility
+     * elements. 
+     * @param extensionValidators
+     */
+    public void setExtensionValidators(Map<QName, ExtensionValidator> extensionValidators) {
+        _extensionValidators = extensionValidators;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
index 00d8ccd..a1545ee 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler.java
@@ -63,6 +63,7 @@ import org.apache.ode.bpel.compiler.bom.Correlation;
 import org.apache.ode.bpel.compiler.bom.CorrelationSet;
 import org.apache.ode.bpel.compiler.bom.Expression;
 import org.apache.ode.bpel.compiler.bom.Expression11;
+import org.apache.ode.bpel.compiler.bom.Extension;
 import org.apache.ode.bpel.compiler.bom.FaultHandler;
 import org.apache.ode.bpel.compiler.bom.Import;
 import org.apache.ode.bpel.compiler.bom.LinkSource;
@@ -81,6 +82,7 @@ import org.apache.ode.bpel.compiler.bom.TerminationHandler;
 import org.apache.ode.bpel.compiler.bom.Variable;
 import org.apache.ode.bpel.compiler.wsdl.Definition4BPEL;
 import org.apache.ode.bpel.compiler.wsdl.WSDLFactory4BPEL;
+import org.apache.ode.bpel.extension.ExtensionValidator;
 import org.apache.ode.bpel.obj.DebugInfo;
 import org.apache.ode.bpel.obj.OActivity;
 import org.apache.ode.bpel.obj.OAssign;
@@ -138,7 +140,7 @@ public abstract class BpelCompiler implements CompilerContext {
 
     private Date _generatedDate;
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings("rawtypes")
     private HashMap<Class, ActivityGenerator> _actGenerators = new HashMap<Class, ActivityGenerator>();
 
     private boolean _supressJoinFailure = false;
@@ -182,6 +184,9 @@ public abstract class BpelCompiler implements CompilerContext {
 
     private URI _processURI;
 
+    private final Set<String> _declaredExtensionNS = new HashSet<String>();
+	private Map<QName, ExtensionValidator> _extensionValidators = new HashMap<QName, ExtensionValidator>();
+
     BpelCompiler(WSDLFactory4BPEL wsdlFactory) {
         _wsdlFactory = wsdlFactory;
         _wsdlRegistry = new WSDLRegistry(this);
@@ -733,6 +738,11 @@ public abstract class BpelCompiler implements CompilerContext {
             }
         }
 
+        // compile extensions
+	for (Extension e : _processDef.getExtensions()) {
+		compileExtension(e);
+	}
+
         OScope procesScope = new OScope(_oprocess, null);
         procesScope.setName("__PROCESS_SCOPE:" + (process.getName()));
         procesScope.setDebugInfo(createDebugInfo(process, null));
@@ -1628,17 +1638,44 @@ public abstract class BpelCompiler implements CompilerContext {
         for (OActivity act : _compiledActivities) {
             if (act instanceof OAssign) {
                 OAssign assign = (OAssign) act;
-                for (OAssign.Copy copy : assign.getCopy()) {
-                    if (copy.getTo() instanceof OAssign.PartnerLinkRef) {
-                        if (((OAssign.PartnerLinkRef) copy.getTo()).getPartnerLink().getName().equals(plink))
-                            return true;
-                    }
-                }
+                for (OAssign.OAssignOperation operation : assign.getOperations()) {
+					if (operation instanceof OAssign.Copy) {
+						OAssign.Copy copy = (OAssign.Copy) operation;
+						if (copy.getTo() instanceof OAssign.PartnerLinkRef) {
+							if (((OAssign.PartnerLinkRef) copy.getTo()).getPartnerLink()
+									.getName().equals(plink))
+								return true;
+						}
+					}
+				}
             }
         }
         return false;
     }
 
+    /**
+	 * Registers a declared extension. Since compilation may take place
+	 * independently of the target engine configuration, the compiler will not
+	 * check whether a extension implementation is registered.
+	 */
+	private void compileExtension(Extension ext) {
+		OProcess.OExtension oextension = new OProcess.OExtension(_oprocess);
+		oextension.setNamespace(ext.getNamespaceURI());
+		oextension.setMustUnderstand(ext.isMustUnderstand());
+
+		oextension.setDebugInfo(createDebugInfo(_processDef,
+				"Extension " + ext.getNamespaceURI()));
+
+		_declaredExtensionNS.add(ext.getNamespaceURI());
+		_oprocess.getDeclaredExtensions().add(oextension);
+		if (ext.isMustUnderstand()) {
+			_oprocess.getMustUnderstandExtensions().add(oextension);
+		}
+
+		if (__log.isDebugEnabled())
+			__log.debug("Compiled extension " + oextension);
+	}
+
     public Definition[] getWsdlDefinitions() {
         Definition[] result = new Definition[_wsdlRegistry.getDefinitions().length];
         for (int m = 0; m < _wsdlRegistry.getDefinitions().length; m++) {
@@ -1657,7 +1694,7 @@ public abstract class BpelCompiler implements CompilerContext {
         return type;
     }
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings("rawtypes")
     private ActivityGenerator findActivityGen(Activity source) {
 
         Class actClass = source.getClass();
@@ -1674,7 +1711,7 @@ public abstract class BpelCompiler implements CompilerContext {
         throw new CompilationException(__cmsgs.errUnknownActivity(actClass.getName()).setSource(source));
     }
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings("rawtypes")
     protected void registerActivityCompiler(Class defClass, ActivityGenerator generator) {
         if (__log.isDebugEnabled()) {
             __log.debug("Adding compiler for nodes class \"" + defClass.getName() + " = " + generator);
@@ -1709,12 +1746,25 @@ public abstract class BpelCompiler implements CompilerContext {
         _expLanguageCompilers.put(expLangUri, expressionCompiler);
     }
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings("rawtypes")
     protected void registerExpressionLanguage(String expLangUri, String classname) throws Exception {
         Class cls = Class.forName(classname);
         registerExpressionLanguage(expLangUri, (ExpressionCompiler) cls.newInstance());
     }
 
+    public void setExtensionValidators(
+			Map<QName, ExtensionValidator> extensionValidators) {
+		_extensionValidators = extensionValidators;
+	}
+
+	public boolean isExtensionDeclared(String namespace) {
+		return _declaredExtensionNS.contains(namespace);
+	}
+
+	public ExtensionValidator getExtensionValidator(QName extensionElementName) {
+		return _extensionValidators.get(extensionElementName);
+	}
+
     public List<OActivity> getActivityStack() {
         ArrayList<OActivity> rval = new ArrayList<OActivity>(_structureStack._stack);
         Collections.reverse(rval);

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20.java
index 7bba612..e4b1f0d 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20.java
@@ -23,6 +23,7 @@ import org.apache.ode.bpel.compiler.bom.Bpel20QNames;
 import org.apache.ode.bpel.compiler.bom.CompensateActivity;
 import org.apache.ode.bpel.compiler.bom.CompensateScopeActivity;
 import org.apache.ode.bpel.compiler.bom.EmptyActivity;
+import org.apache.ode.bpel.compiler.bom.ExtensionActivity;
 import org.apache.ode.bpel.compiler.bom.FlowActivity;
 import org.apache.ode.bpel.compiler.bom.ForEachActivity;
 import org.apache.ode.bpel.compiler.bom.IfActivity;
@@ -71,6 +72,7 @@ public class BpelCompiler20 extends BpelCompiler {
         registerActivityCompiler(TerminateActivity.class, new TerminateGenerator());
         registerActivityCompiler(RethrowActivity.class, new RethrowGenerator());
         registerActivityCompiler(ForEachActivity.class, new ForEachGenerator());
+        registerActivityCompiler(ExtensionActivity.class, new ExtensionActivtityGenerator());
 
         registerExpressionLanguage(OASIS_EXPLANG_XPATH_1_0, new XPath10ExpressionCompilerBPEL20());
 

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20Draft.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20Draft.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20Draft.java
index 8faf69a..bb9f082 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20Draft.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/BpelCompiler20Draft.java
@@ -23,6 +23,7 @@ import org.apache.ode.bpel.compiler.bom.AssignActivity;
 import org.apache.ode.bpel.compiler.bom.Bpel20QNames;
 import org.apache.ode.bpel.compiler.bom.CompensateScopeActivity;
 import org.apache.ode.bpel.compiler.bom.EmptyActivity;
+import org.apache.ode.bpel.compiler.bom.ExtensionActivity;
 import org.apache.ode.bpel.compiler.bom.FlowActivity;
 import org.apache.ode.bpel.compiler.bom.ForEachActivity;
 import org.apache.ode.bpel.compiler.bom.IfActivity;
@@ -70,6 +71,7 @@ public class BpelCompiler20Draft extends BpelCompiler {
         registerActivityCompiler(TerminateActivity.class, new TerminateGenerator());
         registerActivityCompiler(RethrowActivity.class, new RethrowGenerator());
         registerActivityCompiler(ForEachActivity.class, new ForEachGenerator());
+        registerActivityCompiler(ExtensionActivity.class, new ExtensionActivtityGenerator());
 
         registerExpressionLanguage(OASIS_EXPLANG_XPATH_1_0, new XPath10ExpressionCompilerBPEL20Draft());
         try {

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivityGeneratorMessages.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivityGeneratorMessages.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivityGeneratorMessages.java
new file mode 100644
index 0000000..5971bc8
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivityGeneratorMessages.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ode.bpel.compiler;
+
+import org.apache.ode.bpel.compiler.api.CompilationMessage;
+import org.apache.ode.bpel.compiler.api.CompilationMessageBundle;
+
+/**
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class ExtensionActivityGeneratorMessages extends
+		CompilationMessageBundle {
+
+	/** ExtensionActivity is empty. */
+	public CompilationMessage errMissingExtensionActivityElement() {
+		return this
+				.formatCompilationMessage("Extensibility element in <extensionActivity> is missing.");
+	}
+
+	/** Extension namespace is not yet declared. */
+	public CompilationMessage errUndeclaredExtensionActivity() {
+		return this
+				.formatCompilationMessage("Extension namespace of <extensionActivity> has not been declared.");
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivtityGenerator.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivtityGenerator.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivtityGenerator.java
new file mode 100644
index 0000000..22d949b
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/ExtensionActivtityGenerator.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.compiler;
+
+import org.apache.ode.bpel.compiler.api.CompilationException;
+import org.apache.ode.bpel.compiler.bom.Activity;
+import org.apache.ode.bpel.compiler.bom.CompositeActivity;
+import org.apache.ode.bpel.compiler.bom.ExtensionActivity;
+import org.apache.ode.bpel.extension.ExtensionValidator;
+import org.apache.ode.bpel.obj.OActivity;
+import org.apache.ode.bpel.obj.OExtensionActivity;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.msg.MessageBundle;
+import org.w3c.dom.Element;
+
+/**
+ * Generates code for <code>&lt;empty&gt;</code> activities.
+ * 
+ * @author Tammo van Lessen
+ */
+public class ExtensionActivtityGenerator extends DefaultActivityGenerator {
+	private static final ExtensionActivityGeneratorMessages __cmsgs = MessageBundle
+			.getMessages(ExtensionActivityGeneratorMessages.class);
+
+	public void compile(OActivity output, Activity srcx) {
+		ExtensionActivity src = (ExtensionActivity) srcx;
+		OExtensionActivity oactivity = (OExtensionActivity) output;
+		Element child = src.getFirstExtensibilityElementElement();
+		try {
+			if (child == null) {
+				throw new CompilationException(
+						__cmsgs.errMissingExtensionActivityElement());
+			}
+			if (!_context.isExtensionDeclared(child.getNamespaceURI())) {
+				throw new CompilationException(__cmsgs
+						.errUndeclaredExtensionActivity().setSource(src));
+			}
+			ExtensionValidator validator = _context
+					.getExtensionValidator(DOMUtils.getElementQName(child));
+			if (validator != null) {
+				validator.validate(_context, src);
+			}
+			oactivity.setExtensionName(DOMUtils.getElementQName(child));
+			oactivity.setNestedElement(DOMUtils.domToString(child));
+
+			compileChildren(oactivity, (ExtensionActivity) src);
+
+		} catch (CompilationException e) {
+			_context.recoveredFromError(src, e);
+		}
+	}
+
+	public OActivity newInstance(Activity src) {
+		return new OExtensionActivity(_context.getOProcess(),
+				_context.getCurrent());
+	}
+
+	protected void compileChildren(OExtensionActivity dest,
+			CompositeActivity src) {
+		for (Activity child : src.getActivities()) {
+			try {
+				OActivity compiledChild = _context.compile(child);
+				dest.getChildren().add(compiledChild);
+			} catch (CompilationException ce) {
+				_context.recoveredFromError(child, ce);
+			}
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/api/CompilerContext.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/api/CompilerContext.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/api/CompilerContext.java
index 5d9f634..83467df 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/api/CompilerContext.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/api/CompilerContext.java
@@ -29,6 +29,7 @@ import javax.xml.transform.Source;
 import org.apache.ode.bpel.compiler.bom.Activity;
 import org.apache.ode.bpel.compiler.bom.Expression;
 import org.apache.ode.bpel.compiler.bom.ScopeLikeActivity;
+import org.apache.ode.bpel.extension.ExtensionValidator;
 import org.apache.ode.bpel.obj.OActivity;
 import org.apache.ode.bpel.obj.OExpression;
 import org.apache.ode.bpel.obj.OLValueExpression;
@@ -146,6 +147,10 @@ public interface CompilerContext {
 
     Map<URI, Source> getSchemaSources();
 
+	boolean isExtensionDeclared(String namespace);
+
+	ExtensionValidator getExtensionValidator(QName extensionElementName);
+
     /**
      * Retrieves the base URI that the BPEL Process execution contextis running relative to.
      *

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/AssignActivity.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/AssignActivity.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/AssignActivity.java
index f503a83..1c890aa 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/AssignActivity.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/AssignActivity.java
@@ -18,6 +18,7 @@
  */
 package org.apache.ode.bpel.compiler.bom;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import org.w3c.dom.Element;
@@ -41,4 +42,38 @@ public class AssignActivity extends Activity {
     public List<Copy> getCopies() {
         return getChildren(Copy.class);
     }
+
+    /**
+     * Get the list of <code>&lt;extensionAssignOperation&gt;</code> entries for this activity.
+     * 
+     * @return extensionAssignOperation entries
+     */
+    public List<ExtensionAssignOperation> getExtensionAssignOperations() {
+        return getChildren(ExtensionAssignOperation.class);
+    }
+
+    /**
+     * Get the list of all assign operation entries (<code>copy</code> 
+     * and <code>extensionAssignOperation</code>) for this activity.
+     * 
+     * @return assign operation entries
+     */
+    public List<AssignOperation> getOperations() {
+    	//all children objects
+    	List<BpelObject> children = getChildren(BpelObject.class);
+    	
+    	//aggregate only copy and extensionAssignOperation entries
+    	List<AssignOperation> ops = new ArrayList<AssignOperation>();
+    	for (BpelObject bo: children) {
+    		if ((bo instanceof Copy)
+    				||(bo instanceof ExtensionAssignOperation)) {
+    			ops.add((AssignOperation)bo);				
+			}
+    	}    	
+
+    	return ops;
+    }
+
+    /** Marker interface for assign operations */
+    public static interface AssignOperation {}
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java
index 492514e..3e962a0 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Bpel20QNames.java
@@ -109,6 +109,10 @@ public abstract class Bpel20QNames {
     public static final QName FINAL_PROPQUERY = new QName(NS_WSBPEL2_0_FINAL_VARPROP, "query");
     public static final QName FINAL_PLINKTYPE = new QName(NS_WSBPEL2_0_FINAL_PLINK, "partnerLinkType");
     public static final QName FINAL_PLINKROLE = new QName(NS_WSBPEL2_0_FINAL_PLINK, "role");
+    public static final QName FINAL_EXTENSIONS = newFinalQName("extensions");
+    public static final QName FINAL_EXTENSION = newFinalQName("extension");
+    public static final QName FINAL_EXTENSION_ASSIGN_OPERATION = newFinalQName("extensionAssignOperation");
+    public static final QName FINAL_EXTENSION_ACTIVITY = newFinalQName("extensionActivity");
 
     /** Some BPEL 2.0 Draft Elements **/
     public static final QName PROCESS = newQName("process");
@@ -183,6 +187,10 @@ public abstract class Bpel20QNames {
     public static final QName PROPERTY = newQName("property");
     public static final QName PLINKTYPE = new QName(NS_WSBPEL_PARTNERLINK_2004_03, "partnerLinkType");
     public static final QName PLINKROLE = new QName(NS_WSBPEL_PARTNERLINK_2004_03, "role");
+    public static final QName EXTENSIONS = newQName("extensions");
+    public static final QName EXTENSION = newQName("extension");
+    public static final QName EXTENSIBLE_ASSIGN = newQName("extensibleAssign");
+    public static final QName EXTENSION_ACTIVITY = newQName("extensionActivity");
 
     /** Not part of BPEL, but handy to have. */
     public static final String NS_RDF = "http://www.w3.org/2000/01/rdf-schema#";

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java
index 7ab2acb..f2b64aa 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/BpelObjectFactory.java
@@ -131,6 +131,10 @@ public class BpelObjectFactory {
         _mappings.put(Bpel20QNames.FINAL_EVENTHANDLERS, BpelObject.class);
         _mappings.put(Bpel20QNames.FINAL_TARGETS,Targets.class);
         _mappings.put(Bpel20QNames.FINAL_SOURCES,Sources.class);
+        _mappings.put(Bpel20QNames.FINAL_EXTENSIONS,Extensions.class);
+        _mappings.put(Bpel20QNames.FINAL_EXTENSION,Extension.class);
+        _mappings.put(Bpel20QNames.FINAL_EXTENSION_ACTIVITY,ExtensionActivity.class);
+        _mappings.put(Bpel20QNames.FINAL_EXTENSION_ASSIGN_OPERATION,ExtensionAssignOperation.class);
 
         //
         // BPEL 2.0 draft Mappings
@@ -207,6 +211,10 @@ public class BpelObjectFactory {
         _mappings.put(Bpel20QNames.TARGETS,Targets.class);
         _mappings.put(Bpel20QNames.SOURCES,Sources.class);
         _mappings.put(Bpel20QNames.RDF_LABEL,RdfLabel.class);
+        _mappings.put(Bpel20QNames.EXTENSIONS,Extensions.class);
+        _mappings.put(Bpel20QNames.EXTENSION,Extension.class);
+        _mappings.put(Bpel20QNames.EXTENSION_ACTIVITY,ExtensionActivity.class);
+        _mappings.put(Bpel20QNames.EXTENSIBLE_ASSIGN,ExtensionAssignOperation.class);
 
         //
         // BPEL 1.1 Mappings

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Copy.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Copy.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Copy.java
index 1764828..22523e0 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Copy.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Copy.java
@@ -18,6 +18,7 @@
  */
 package org.apache.ode.bpel.compiler.bom;
 
+import org.apache.ode.bpel.compiler.bom.AssignActivity.AssignOperation;
 import org.w3c.dom.Element;
 
 /**
@@ -25,7 +26,7 @@ import org.w3c.dom.Element;
  * (L-value) and a "right hand side (R-value). The value on the right hand side
  * is copied to the location referenced in the left hand side.
  */
-public class Copy extends BpelObject {
+public class Copy extends BpelObject implements AssignOperation {
 
     public Copy(Element el) {
         super(el);

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extension.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extension.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extension.java
new file mode 100644
index 0000000..2a5a755
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extension.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.compiler.bom;
+
+import org.w3c.dom.Element;
+
+/**
+ * BOM representation of the BPEL <code>&lt;extension&gt;</code> element.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class Extension extends BpelObject {
+
+	public Extension(Element el) {
+		super(el);
+	}
+
+	public boolean isMustUnderstand() {
+		return getAttribute("mustUnderstand", "no").equals("yes");
+	}
+
+	public String getNamespaceURI() {
+		return getAttribute("namespace", null);
+	}
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionActivity.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionActivity.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionActivity.java
new file mode 100644
index 0000000..78c5d87
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionActivity.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.compiler.bom;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.w3c.dom.Element;
+import org.apache.ode.bpel.extension.ExtensibleElement;
+
+/**
+ * BOM representation of the BPEL <code>&lt;extensionActivity&gt;</code>
+ * activity. The <code>&lt;extensionActivity&gt;</code> activity contains a
+ * nested DOM element that represents the actual extension element. According to
+ * the BPEL 2.0 PR1 specification, the standards elements and standards
+ * attributes are not located in the extensionActivity element but in the nested
+ * element. Therefore the convenient access methods for standards
+ * attributes/elements are overridden to refer to the nested elements.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class ExtensionActivity extends CompositeActivity implements
+		ExtensibleElement {
+	private Activity _childActivity;
+
+	public ExtensionActivity(Element el) {
+		super(el);
+		_childActivity = null;
+		Element child = getFirstExtensibilityElementElement();
+		if (child != null) {
+			_childActivity = new Activity(getFirstExtensibilityElementElement());
+		}
+	}
+
+	@Override
+	public Expression getJoinCondition() {
+		if (_childActivity == null) {
+			return null;
+		}
+		return _childActivity.getJoinCondition();
+	}
+
+	@Override
+	public List<LinkSource> getLinkSources() {
+		if (_childActivity == null) {
+			return Collections.emptyList();
+		}
+		return _childActivity.getLinkSources();
+	}
+
+	@Override
+	public List<LinkTarget> getLinkTargets() {
+		if (_childActivity == null) {
+			return Collections.emptyList();
+		}
+		return _childActivity.getLinkTargets();
+	}
+
+	@Override
+	public String getName() {
+		if (_childActivity == null) {
+			return null;
+		}
+		return _childActivity.getName();
+	}
+
+	@Override
+	public SuppressJoinFailure getSuppressJoinFailure() {
+		if (_childActivity == null) {
+			return SuppressJoinFailure.NOTSET;
+		}
+		return _childActivity.getSuppressJoinFailure();
+	}
+
+	@Override
+	public List<Activity> getActivities() {
+		if (_childActivity == null) {
+			return Collections.emptyList();
+		}
+
+		return _childActivity.getChildren(Activity.class);
+	}
+
+	public Element getNestedElement() {
+		return getFirstExtensibilityElementElement();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionAssignOperation.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionAssignOperation.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionAssignOperation.java
new file mode 100644
index 0000000..6a18cdf
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/ExtensionAssignOperation.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.compiler.bom;
+
+import org.apache.ode.bpel.compiler.bom.AssignActivity.AssignOperation;
+import org.apache.ode.bpel.extension.ExtensibleElement;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * BOM representation of the BPEL <code>&lt;extensionAssignOperation&gt;</code>.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class ExtensionAssignOperation extends BpelObject implements
+		AssignOperation, ExtensibleElement {
+	private Element _childElement;
+
+	public ExtensionAssignOperation(Element el) {
+		super(el);
+	}
+
+	public Element getNestedElement() {
+		// XXX
+		// return getFirstExtensibilityElement();
+		if (_childElement == null) {
+			NodeList nl = getElement().getChildNodes();
+			for (int i = 0; i < nl.getLength(); ++i) {
+				Node node = nl.item(i);
+				if (node.getNodeType() == Node.ELEMENT_NODE
+						&& !Bpel20QNames.NS_WSBPEL2_0.equals(node
+								.getNamespaceURI())) {
+					_childElement = (Element) node;
+					break;
+				}
+			}
+		}
+		return _childElement;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extensions.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extensions.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extensions.java
new file mode 100644
index 0000000..5f7365b
--- /dev/null
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Extensions.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.compiler.bom;
+
+import org.w3c.dom.Element;
+
+/**
+ * BOM representation of the BPEL <code>&lt;extension&gt;</code> element.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class Extensions extends BpelObject {
+
+	public Extensions(Element el) {
+		super(el);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Process.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Process.java b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Process.java
index 694c10c..017c175 100644
--- a/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Process.java
+++ b/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/bom/Process.java
@@ -20,6 +20,7 @@ package org.apache.ode.bpel.compiler.bom;
 
 import org.w3c.dom.Element;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
@@ -111,4 +112,16 @@ public class Process extends Scope {
         return getChildren(Import.class);
     }
 
+    /**
+     * Get the <code>&lt;extensions&gt;</code>(s) of the process.
+     * 
+     * @return {@link Set} of {@link Extension}s
+     */
+    public List<Extension> getExtensions() {
+        Extensions extensions = getFirstChild(Extensions.class);
+        if (extensions == null)
+            return Collections.emptyList();
+        return extensions.getChildren(Extension.class);
+
+    }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-compiler/src/test/java/org/apache/ode/bpel/compiler/XPathTest.java
----------------------------------------------------------------------
diff --git a/bpel-compiler/src/test/java/org/apache/ode/bpel/compiler/XPathTest.java b/bpel-compiler/src/test/java/org/apache/ode/bpel/compiler/XPathTest.java
index 57f6ea4..df00dac 100644
--- a/bpel-compiler/src/test/java/org/apache/ode/bpel/compiler/XPathTest.java
+++ b/bpel-compiler/src/test/java/org/apache/ode/bpel/compiler/XPathTest.java
@@ -44,6 +44,7 @@ import org.apache.ode.bpel.elang.xpath10.compiler.XPath10ExpressionCompilerBPEL2
 import org.apache.ode.bpel.elang.xpath10.compiler.XPath10ExpressionCompilerBPEL20Draft;
 import org.apache.ode.bpel.elang.xpath20.compiler.XPath20ExpressionCompilerBPEL20;
 import org.apache.ode.bpel.elang.xpath20.compiler.XPath20ExpressionCompilerBPEL20Draft;
+import org.apache.ode.bpel.extension.ExtensionValidator;
 import org.apache.ode.bpel.obj.OActivity;
 import org.apache.ode.bpel.obj.OElementVarType;
 import org.apache.ode.bpel.obj.OExpression;
@@ -301,4 +302,12 @@ class MockCompilerContext implements CompilerContext {
     public NSContext tryCacheNamespaceContext(NSContext nsContext) {
         return nsContext;
     }
+
+    public boolean isExtensionDeclared(String namespace) {
+		return false;
+	}
+
+	public ExtensionValidator getExtensionValidator(QName extensionElementName) {
+		return null;
+	}
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-epr/src/main/java/org/apache/ode/il/config/OdeConfigProperties.java
----------------------------------------------------------------------
diff --git a/bpel-epr/src/main/java/org/apache/ode/il/config/OdeConfigProperties.java b/bpel-epr/src/main/java/org/apache/ode/il/config/OdeConfigProperties.java
index c03edf6..abfc50f 100644
--- a/bpel-epr/src/main/java/org/apache/ode/il/config/OdeConfigProperties.java
+++ b/bpel-epr/src/main/java/org/apache/ode/il/config/OdeConfigProperties.java
@@ -112,6 +112,10 @@ public class OdeConfigProperties {
 
     public static final String DEFAULT_CLUSTERING_IMPL_CLASS_NAME = "org.apache.ode.clustering.hazelcast.HazelcastClusterImpl";
 
+    public static final String PROP_EXTENSION_BUNDLES_RT = "extension.bundles.runtime";
+    
+    public static final String PROP_EXTENSION_BUNDLES_VAL = "extension.bundles.validation";
+
     private File _cfgFile;
 
     private String _prefix;
@@ -384,4 +388,11 @@ public class OdeConfigProperties {
         return Integer.valueOf(getProperty(PROP_MIGRATION_TRANSACTION_TIMEOUT, String.valueOf(0)));
     }
 
+    public String getExtensionActivityBundlesRT() {
+	return getProperty(PROP_EXTENSION_BUNDLES_RT);
+    }
+
+    public String getExtensionActivityBundlesValidation() {
+	return getProperty(PROP_EXTENSION_BUNDLES_VAL);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OAssign.java
----------------------------------------------------------------------
diff --git a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OAssign.java b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OAssign.java
index 8db6375..b0b5868 100644
--- a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OAssign.java
+++ b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OAssign.java
@@ -32,36 +32,37 @@ import org.w3c.dom.Document;
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 
-public class OAssign extends OActivity  implements Serializable{
+public class OAssign extends OActivity implements Serializable {
 	public static final long serialVersionUID = -1L;
-	private static final String COPY = "copy";
+	private static final String OPERATION = "operation";
 
 	@JsonCreator
 	public OAssign(){
 	}
+	
 	public OAssign(OProcess owner, OActivity parent) {
 		super(owner, parent);
-		setCopy(new ArrayList<Copy>());
+		setOperations(new ArrayList<OAssignOperation>());
 	}
 
 	@Override
 	public void dehydrate() {
 		super.dehydrate();
-		for (Copy copy : getCopy()) {
-			copy.dehydrate();
+		for (OAssignOperation operation : getOperations()) {
+			operation.dehydrate();
 		}
 	}
 
 	@SuppressWarnings("unchecked")
 	@JsonIgnore
-	public List<Copy> getCopy() {
-		Object o = fieldContainer.get(COPY);
-		return o == null ? null : (List<Copy>)o;
+	public List<OAssignOperation> getOperations() {
+		Object o = fieldContainer.get(OPERATION);
+		return o == null ? null : (List<OAssignOperation>)o;
 	}
 
-	public void setCopy(List<Copy> copy) {
-		if (getCopy() == null){
-			fieldContainer.put(COPY, copy);
+	public void setOperations(List<OAssignOperation> operation) {
+		if (getOperations() == null){
+			fieldContainer.put(OPERATION, operation);
 		}
 	}
 
@@ -69,12 +70,31 @@ public class OAssign extends OActivity  implements Serializable{
 		return "{OAssign : " + getName() + ", joinCondition="
 				+ getJoinCondition() + "}";
 	}
+	
+	/** 
+     * Base class for assign operations.
+     */
+    public static abstract class OAssignOperation extends OBase implements Serializable {
+		private static final long serialVersionUID = -3042873658302758854L;
+
+		public enum Type { Copy, ExtensionOperation }
+
+		@JsonCreator
+		public OAssignOperation() {
+		}
+		
+    	public OAssignOperation(OProcess owner) {
+    		super(owner);
+    	}
+    	
+    	public abstract Type getType();
+    }
 
 	/**
-	 * Assignmenet copy entry, i.e. what the assignment consits of.
+	 * Assignment copy entry, i.e. what the assignment consists of.
 	 */
-	public static class Copy extends OBase  implements Serializable{
-	public static final long serialVersionUID = -1L;
+	public static class Copy extends OAssignOperation implements Serializable {
+	    public static final long serialVersionUID = -1L;
 		private static final String TO = "to";
 		private static final String FROM = "from";
 		private static final String KEEPSRCELEMENTNAME = "keepSrcElementName";
@@ -86,10 +106,12 @@ public class OAssign extends OActivity  implements Serializable{
 		public Copy(){
 			initPrimitive();
 		}
+		
 		public Copy(OProcess owner) {
 			super(owner);
 			initPrimitive();
 		}
+		
 		private void initPrimitive(){
 			setIgnoreMissingFromData(false);
 			setIgnoreUninitializedFromVariable(false);
@@ -107,13 +129,13 @@ public class OAssign extends OActivity  implements Serializable{
 		@JsonIgnore
 		public RValue getFrom() {
 			Object o = fieldContainer.get(FROM);
-		return o == null ? null : (RValue)o;
+			return o == null ? null : (RValue)o;
 		}
 
 		@JsonIgnore
 		public boolean isIgnoreMissingFromData() {
 			Object o = fieldContainer.get(IGNOREMISSINGFROMDATA);
-		return o == null ? false : (Boolean)o;
+			return o == null ? false : (Boolean)o;
 		}
 
 		@JsonIgnore
@@ -125,19 +147,19 @@ public class OAssign extends OActivity  implements Serializable{
 		@JsonIgnore
 		public boolean isInsertMissingToData() {
 			Object o = fieldContainer.get(INSERTMISSINGTODATA);
-		return o == null ? false : (Boolean)o;
+			return o == null ? false : (Boolean)o;
 		}
 
 		@JsonIgnore
 		public boolean isKeepSrcElementName() {
 			Object o = fieldContainer.get(KEEPSRCELEMENTNAME);
-		return o == null ? false : (Boolean)o;
+			return o == null ? false : (Boolean)o;
 		}
 
 		@JsonIgnore
 		public LValue getTo() {
 			Object o = fieldContainer.get(TO);
-		return o == null ? null : (LValue)o;
+			return o == null ? null : (LValue)o;
 		}
 
 		public void setFrom(RValue from) {
@@ -169,7 +191,65 @@ public class OAssign extends OActivity  implements Serializable{
 		public String toString() {
 			return "{OCopy " + getTo() + "=" + getFrom() + "}";
 		}
+		
+		@JsonIgnore
+		public Type getType() {
+        	return Type.Copy;
+        }
 	}
+	
+	/**
+     * Assignment extension operation entry, i.e. what the assignment consists of.
+     */
+    public static class ExtensionAssignOperation extends OAssignOperation {
+        private static final long serialVersionUID = 1L;
+        
+        private static final String EXTENSIONNAME = "extensionName";
+		private static final String NESTEDELEMENT = "nestedElement";
+		
+		@JsonCreator
+		public ExtensionAssignOperation(){
+		}
+
+        public ExtensionAssignOperation(OProcess owner) {
+            super(owner);
+        }
+
+        @JsonIgnore
+		public QName getExtensionName() {
+			Object o = fieldContainer.get(EXTENSIONNAME);
+			return o == null ? null : (QName) o;
+		}
+        
+        @JsonIgnore
+		public String getNestedElement() {
+			Object o = fieldContainer.get(NESTEDELEMENT);
+			return o == null ? null : (String)o;
+		}
+        
+        public void setExtensionName(QName extensionName) {
+			fieldContainer.put(EXTENSIONNAME, extensionName);
+		}
+        
+        public void setNestedElement(String nestedElement) {
+			fieldContainer.put(NESTEDELEMENT, nestedElement);
+		}
+
+        public String toString() {
+            return "{OExtensionAssignOperation; " + getExtensionName() + "}";
+        }
+        
+        @Override
+		public void dehydrate() {
+			super.dehydrate();
+			setExtensionName(null);
+			setNestedElement(null);
+		}
+
+        public Type getType() {
+			return Type.ExtensionOperation;
+		}
+    }
 
 	/**
 	 * Direct reference: selects named child of the message document element.

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OExtensionActivity.java
----------------------------------------------------------------------
diff --git a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OExtensionActivity.java b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OExtensionActivity.java
new file mode 100644
index 0000000..2c3632a
--- /dev/null
+++ b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OExtensionActivity.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.obj;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+/**
+ * Compiled representation of the BPEL <code>&lt;extensionActivity&gt;</code>
+ * activity.
+ * <p>
+ * Adapted initial version for compatibility with new ODE object model (bpel-nobj).
+ * 
+ * @author Tammo van Lessen (University of Stuttgart), Michael Hahn (mhahn.dev@gmail.com)
+ */
+public class OExtensionActivity extends OActivity implements Serializable {
+
+	static final long serialVersionUID = -1L;
+
+	private static final String EXTENSIONNAME = "extensionName";
+	private static final String NESTEDELEMENT = "nestedElement";
+	private static final String CHILDREN = "children";
+	
+	@JsonCreator
+	public OExtensionActivity(){
+	}
+
+    public OExtensionActivity(OProcess owner, OActivity parent) {
+        super(owner, parent);
+        setChildren(new ArrayList<OActivity>());
+    }
+
+    @JsonIgnore
+	public QName getExtensionName() {
+		Object o = fieldContainer.get(EXTENSIONNAME);
+		return o == null ? null : (QName) o;
+	}
+    
+    @JsonIgnore
+	public String getNestedElement() {
+		Object o = fieldContainer.get(NESTEDELEMENT);
+		return o == null ? null : (String)o;
+	}
+    
+    @SuppressWarnings("unchecked")
+	@JsonIgnore
+	public List<OActivity> getChildren() {
+		Object o = fieldContainer.get(CHILDREN);
+		return o == null ? null : (List<OActivity>)o;
+	}
+    
+    public void setExtensionName(QName extensionName) {
+		fieldContainer.put(EXTENSIONNAME, extensionName);
+	}
+    
+    public void setNestedElement(String nestedElement) {
+		fieldContainer.put(NESTEDELEMENT, nestedElement);
+	}
+    
+    void setChildren(List<OActivity> children) {
+    	if (getChildren() == null) {
+		  fieldContainer.put(CHILDREN, children);
+    	}
+	}
+
+    public String toString() {
+        return "{OExtensionActivity; " + getExtensionName() + "}";
+    }
+    
+    @Override
+	public void dehydrate() {
+		super.dehydrate();
+		setExtensionName(null);
+		setNestedElement(null);
+		for (OBase obase : getChildren()) {
+			obase.dehydrate();
+		}
+		getChildren().clear();
+	}
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java
----------------------------------------------------------------------
diff --git a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java
index 2296210..d8f0e67 100644
--- a/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java
+++ b/bpel-nobj/src/main/java/org/apache/ode/bpel/obj/OProcess.java
@@ -20,7 +20,6 @@ package org.apache.ode.bpel.obj;
 
 import java.io.IOException;
 import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.net.URI;
 import java.util.ArrayList;
@@ -92,7 +91,12 @@ public class OProcess extends OBase  implements Serializable{
 	private static final String XSDTYPES = "xsdTypes";
 	private static final String XSLSHEETS = "xslSheets";
 	private static final String NAMESPACECONTEXT = "namespaceContext";
-
+	
+	/** All declared extensions in the process. **/
+	private static final String DECLAREDEXTENSIONS = "declaredExtensions";
+	/** All must-understand extensions in the process. **/
+	private static final String MUSTUNDERSTANDEXTENSIONS = "mustUnderstandExtensions";
+	
 	/**
 	 * This constructor should only be used by Jackson when deserialize.
 	 */
@@ -114,6 +118,9 @@ public class OProcess extends OBase  implements Serializable{
 		setXsdTypes(new HashMap<QName, OXsdTypeVarType>());
 		setXslSheets(new HashMap<URI, OXslSheet>());
 		
+		setDeclaredExtensions(new HashSet<OExtension>());
+		setMustUnderstandExtensions(new HashSet<OExtension>());
+		
 		setChildIdCounter(0);
 	}
 
@@ -130,6 +137,8 @@ public class OProcess extends OBase  implements Serializable{
 		getElementTypes().clear();
 		getXsdTypes().clear();
 		getXslSheets().clear();
+		getDeclaredExtensions().clear();
+		getMustUnderstandExtensions().clear();
 	}
 
 	@Override
@@ -164,6 +173,7 @@ public class OProcess extends OBase  implements Serializable{
 		return o == null ? 0 : (Integer)o;
 	}
 
+	@SuppressWarnings("unchecked")
 	@JsonIgnore
 	public List<OBase> getChildren() {
 		Object o = fieldContainer.get(CHILDREN);
@@ -182,9 +192,9 @@ public class OProcess extends OBase  implements Serializable{
 		return o == null ? null : (OConstants)o;
 	}
 
+	@SuppressWarnings("rawtypes")
 	@ObjectDiffProperty(ignore = true)
 	@JsonIgnore
-	@SuppressWarnings("unchecked")
 	public List<String> getCorrelators() {
 		// MOVED from ProcessSchemaGenerator
 		List<String> correlators = new ArrayList<String>();
@@ -311,6 +321,20 @@ public class OProcess extends OBase  implements Serializable{
 		Object o = fieldContainer.get(XSLSHEETS);
 		return o == null ? null : (HashMap<URI, OXslSheet>)o;
 	}
+	
+	@SuppressWarnings("unchecked")
+	@JsonIgnore
+	public Set<OExtension> getDeclaredExtensions() {
+		return (Set<OExtension>) fieldContainer
+				.get(DECLAREDEXTENSIONS);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@JsonIgnore
+	public Set<OExtension> getMustUnderstandExtensions() {
+		return (Set<OExtension>) fieldContainer
+				.get(MUSTUNDERSTANDEXTENSIONS);
+	}
 
 	public void setAllPartnerLinks(Set<OPartnerLink> allPartnerLinks) {
 		if (getAllPartnerLinks() == null) {
@@ -398,6 +422,18 @@ public class OProcess extends OBase  implements Serializable{
 			fieldContainer.put(XSLSHEETS, xslSheets);
 		}
 	}
+	
+	public void setDeclaredExtensions(Set<OExtension> extensions) {
+		if (getDeclaredExtensions() == null) {
+			fieldContainer.put(DECLAREDEXTENSIONS, extensions);
+		}
+	}
+	
+	public void setMustUnderstandExtensions(Set<OExtension> extensions) {
+		if (getMustUnderstandExtensions() == null) {
+			fieldContainer.put(MUSTUNDERSTANDEXTENSIONS, extensions);
+		}
+	}
 
 	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
 		ois.defaultReadObject();
@@ -535,6 +571,42 @@ public class OProcess extends OBase  implements Serializable{
 		}
 
 	}
+	
+	public static class OExtension extends OBase implements Serializable {
+		public static final long serialVersionUID = -1L  ;
+        
+        private static final String NAMESPACE = "namespaceURI";
+		private static final String MUSTUNDERSTAND = "mustUnderstand";
+        
+        @JsonCreator
+		public OExtension(){}
+        
+        public OExtension(OProcess process) { super(process); }
+        
+        @JsonIgnore
+		public String getNamespace() {
+			Object o = fieldContainer.get(NAMESPACE);
+			return o == null ? null : (String)o;
+		}
+
+		@JsonIgnore
+		public boolean isMustUnderstand() {
+			Object o = fieldContainer.get(MUSTUNDERSTAND);
+			return o == null ? false : (Boolean)o;
+		}
+		
+		public void setNamespace(String namespaceURI) {
+			fieldContainer.put(NAMESPACE, namespaceURI);
+		}
+
+		public void setMustUnderstand(boolean mustUnderstand) {
+			fieldContainer.put(MUSTUNDERSTAND, mustUnderstand);
+		}
+
+        public String toString() {
+            return "{OExtension " + getNamespace() + (isMustUnderstand() ? " mustUnderstand" : "") + "}";
+        }
+    }
 
 	/**
 	 * custom deserializer of OProcess.

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-obj/src/main/java/org/apache/ode/bpel/o/OAssign.java
----------------------------------------------------------------------
diff --git a/bpel-obj/src/main/java/org/apache/ode/bpel/o/OAssign.java b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OAssign.java
index 64248a3..5212a13 100644
--- a/bpel-obj/src/main/java/org/apache/ode/bpel/o/OAssign.java
+++ b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OAssign.java
@@ -26,12 +26,13 @@ import javax.xml.namespace.QName;
 
 import org.apache.ode.bpel.o.OScope.Variable;
 import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.SerializableElement;
 import org.w3c.dom.Document;
 
 public class OAssign extends OActivity {
     static final long serialVersionUID = -1L  ;
 
-    public final List<Copy> copy = new ArrayList<Copy>();
+    public final List<OAssignOperation> operations = new ArrayList<OAssignOperation>();
 
     public OAssign(OProcess owner, OActivity parent) {
         super(owner, parent);
@@ -41,11 +42,26 @@ public class OAssign extends OActivity {
     public String toString() {
         return "{OAssign : " + name + ", joinCondition=" + joinCondition + "}";
     }
+    
+    /** 
+     * Base class for assign operations.
+     */
+    public static abstract class OAssignOperation extends OBase {
+		private static final long serialVersionUID = -3042873658302758854L;
+
+		public enum Type { Copy, ExtensionOperation }
+
+    	public OAssignOperation(OProcess owner) {
+    		super(owner);
+    	}
+    	
+    	public abstract Type getType();
+    }
 
     /**
      * Assignmenet copy entry, i.e. what the assignment consits of.
      */
-    public static class Copy extends OBase {
+    public static class Copy extends OAssignOperation {
         private static final long serialVersionUID = 1L;
         public LValue to;
         public RValue from;
@@ -68,6 +84,38 @@ public class OAssign extends OActivity {
             to = null;
             from = null;
         }
+        
+        public Type getType() {
+        	return Type.Copy;
+        }
+    }
+    
+    /**
+     * Assignment extension operation entry, i.e. what the assignment consists of.
+     */
+    public static class ExtensionAssignOperation extends OAssignOperation {
+        private static final long serialVersionUID = 1L;
+        public SerializableElement nestedElement;
+        public QName extensionName;
+
+        public ExtensionAssignOperation(OProcess owner) {
+            super(owner);
+        }
+
+        public String toString() {
+            return "{OExtensionAssignOperation; " + nestedElement.getElement().getTagName() + "}";
+        }
+        
+        @Override
+		public void dehydrate() {
+			super.dehydrate();
+			nestedElement = null;
+			extensionName = null;
+		}
+
+        public Type getType() {
+			return Type.ExtensionOperation;
+		}
     }
 
     public interface LValue {
@@ -255,8 +303,12 @@ public class OAssign extends OActivity {
     @Override
     public void dehydrate() {
         super.dehydrate();
-        for (Copy copy : this.copy) {
-            copy.dehydrate();
+		for (OAssignOperation operation : this.operations) {
+			if (operation.getType().equals(OAssignOperation.Type.Copy)) {
+				((Copy)operation).dehydrate();
+			} else if (operation.getType().equals(OAssignOperation.Type.ExtensionOperation)) {
+				((ExtensionAssignOperation)operation).dehydrate();
+			}
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-obj/src/main/java/org/apache/ode/bpel/o/OExtensionActivity.java
----------------------------------------------------------------------
diff --git a/bpel-obj/src/main/java/org/apache/ode/bpel/o/OExtensionActivity.java b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OExtensionActivity.java
new file mode 100644
index 0000000..deb73cf
--- /dev/null
+++ b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OExtensionActivity.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ode.bpel.o;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ode.utils.SerializableElement;
+
+/**
+ * Compiled representation of the BPEL <code>&lt;extensionActivity&gt;</code>
+ * activity.
+ * 
+ * @author Tammo van Lessen (University of Stuttgart)
+ */
+public class OExtensionActivity extends OActivity {
+
+	static final long serialVersionUID = -1L;
+	public final List<OActivity> children = new ArrayList<OActivity>();
+	public SerializableElement nestedElement;
+	public QName extensionName;
+
+	public OExtensionActivity(OProcess owner, OActivity parent) {
+		super(owner, parent);
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/ode/blob/acb7e8ee/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java
----------------------------------------------------------------------
diff --git a/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java
index 717b9e2..7b95919 100644
--- a/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java
+++ b/bpel-obj/src/main/java/org/apache/ode/bpel/o/OProcess.java
@@ -76,6 +76,12 @@ public class OProcess extends OBase {
 
     public final HashMap<URI, OXslSheet> xslSheets = new HashMap<URI, OXslSheet>();
 
+    /** All declared extensions in the process. **/
+    public final Set<OExtension> declaredExtensions = new HashSet<OExtension>();
+
+    /** All must-understand extensions in the process. **/
+    public final Set<OExtension> mustUnderstandExtensions = new HashSet<OExtension>();
+
     public OProcess(String bpelVersion) {
         super(null);
         this.version = bpelVersion;
@@ -114,12 +120,12 @@ public class OProcess extends OBase {
         return processName;
     }
 
-    @SuppressWarnings("unchecked")
-    public Collection getExpressionLanguages() {
+    @SuppressWarnings("rawtypes")
+	public Collection getExpressionLanguages() {
         throw new UnsupportedOperationException(); // TODO: implement me!
     }
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings("rawtypes")
     public List<String> getCorrelators() {
         // MOVED from ProcessSchemaGenerator
         List<String> correlators = new ArrayList<String>();
@@ -186,6 +192,18 @@ public class OProcess extends OBase {
         }
 
     }
+    
+    public static class OExtension extends OBase {
+        static final long serialVersionUID = -1L  ;
+        public String namespaceURI;
+        public boolean mustUnderstand;
+        
+        public OExtension(OProcess process) { super(process); }
+
+        public String toString() {
+            return "{OExtension " + namespaceURI + (mustUnderstand ? " mustUnderstand" : "") + "}";
+        }
+    }
 
     public QName getQName() {
         return new QName(targetNamespace, processName);