diff --git a/itest/wsdlgen-verify/src/main/java/wsdlgen/verify/ComplexNumber.java b/itest/wsdlgen-verify/src/main/java/wsdlgen/verify/ComplexNumber.java
new file mode 100644
index 0000000..30ed33d
--- /dev/null
+++ b/itest/wsdlgen-verify/src/main/java/wsdlgen/verify/ComplexNumber.java
@@ -0,0 +1,48 @@
+/*
+ * 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 wsdlgen.verify;
+
+public class ComplexNumber {
+    private double real, imaginary;
+
+    public ComplexNumber(double real, double imaginary) {
+        this.real = real;
+        this.imaginary = imaginary;
+    }
+
+    public ComplexNumber() {
+    }
+
+    public double getReal() {
+        return real;
+    }
+
+    public void setReal(double real) {
+        this.real = real;
+    }
+
+    public double getImaginary() {
+        return imaginary;
+    }
+
+    public void setImaginary(double imaginary) {
+        this.imaginary = imaginary;
+    }
+}
diff --git a/itest/wsdlgen-verify/src/main/java/wsdlgen/verify/DataTypes.java b/itest/wsdlgen-verify/src/main/java/wsdlgen/verify/DataTypes.java
new file mode 100644
index 0000000..f3d689e
--- /dev/null
+++ b/itest/wsdlgen-verify/src/main/java/wsdlgen/verify/DataTypes.java
@@ -0,0 +1,42 @@
+/*
+ * 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 wsdlgen.verify;
+
+import java.util.List;
+import commonj.sdo.DataObject;
+import org.osoa.sca.annotations.Remotable;
+
+@Remotable
+public interface DataTypes {
+
+    void testSimpleInt(int simple);
+
+    void testSimpleArrayInt(int[] simple);
+
+    void testSimpleListString(List<String> simple);
+
+    void testComplex(ComplexNumber complex);
+
+    void testByteArray(byte[] byteArray);
+
+    void testException() throws Exception;
+
+    DataObject testDynamicSDO();
+}
diff --git a/itest/wsdlgen-verify/src/main/java/wsdlgen/verify/impl/DataTypesImpl.java b/itest/wsdlgen-verify/src/main/java/wsdlgen/verify/impl/DataTypesImpl.java
new file mode 100644
index 0000000..71fc96c
--- /dev/null
+++ b/itest/wsdlgen-verify/src/main/java/wsdlgen/verify/impl/DataTypesImpl.java
@@ -0,0 +1,50 @@
+/*
+ * 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 wsdlgen.verify.impl;
+
+import java.util.List;
+import commonj.sdo.DataObject;
+import wsdlgen.verify.ComplexNumber;
+import wsdlgen.verify.DataTypes;
+
+public class DataTypesImpl implements DataTypes {
+
+    public void testSimpleInt(int simple) {
+    }
+
+    public void testSimpleArrayInt(int[] simple) {
+    }
+
+    public void testSimpleListString(List<String> simple) {
+    }
+
+    public void testComplex(ComplexNumber complex) {
+    }
+
+    public void testByteArray(byte[] byteArray) {
+    }
+
+    public void testException() throws Exception {
+    }
+
+    public DataObject testDynamicSDO() {
+        return null;
+    }
+}
diff --git a/itest/wsdlgen-verify/src/main/resources/DataTypes.composite b/itest/wsdlgen-verify/src/main/resources/DataTypes.composite
new file mode 100644
index 0000000..a88d276
--- /dev/null
+++ b/itest/wsdlgen-verify/src/main/resources/DataTypes.composite
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+           targetNamespace="http://verify.wsdlgen/"
+           name="DataTypes">
+
+    <component name="DataTypes">
+        <implementation.java class="wsdlgen.verify.impl.DataTypesImpl" />
+        <service name="DataTypes">
+            <binding.ws uri="http://localhost:8085/DataTypes" />
+        </service>
+    </component>
+
+</composite>
diff --git a/itest/wsdlgen-verify/src/test/java/wsdlgen/verify/DataTypesTestCase.java b/itest/wsdlgen-verify/src/test/java/wsdlgen/verify/DataTypesTestCase.java
new file mode 100644
index 0000000..3ebe408
--- /dev/null
+++ b/itest/wsdlgen-verify/src/test/java/wsdlgen/verify/DataTypesTestCase.java
@@ -0,0 +1,303 @@
+/*
+ * 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 wsdlgen.verify;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.wsdl.Binding;
+import javax.wsdl.Definition;
+import javax.wsdl.Fault;
+import javax.wsdl.Input;
+import javax.wsdl.Message;
+import javax.wsdl.Operation;
+import javax.wsdl.Output;
+import javax.wsdl.Part;
+import javax.wsdl.Port;
+import javax.wsdl.PortType;
+import javax.wsdl.Service;
+import javax.wsdl.Types;
+import javax.wsdl.extensions.ExtensibilityElement;
+import javax.wsdl.extensions.schema.Schema;
+import javax.wsdl.factory.WSDLFactory;
+import javax.wsdl.xml.WSDLReader;
+import javax.xml.namespace.QName;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.tuscany.sca.host.embedded.SCADomain;
+
+/**
+ * Test ?wsdl works and that the returned WSDL is correct
+ *
+ * @version $Rev: 814373 $ $Date: 2009-09-13 19:06:29 +0100 (Sun, 13 Sep 2009) $
+ */
+public class DataTypesTestCase {
+    private static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
+    private static final String SCHEMA_NAME = "schema";
+    private static final QName SCHEMA_QNAME = new QName(SCHEMA_NS, SCHEMA_NAME);
+
+    private static SCADomain domain;
+    private static Map<String, Element> schemaMap;
+    private static PortType portType;
+
+    private Map<String, String> prefixMap;
+
+    public DataTypesTestCase() {
+        // create a new instance of this for each of the tests
+        prefixMap = new HashMap<String, String>();
+    }
+
+    @Test
+    public void testSimpleInt() throws Exception {
+        assertEquals("xs:int", parameterType("testSimpleInt"));
+    }
+
+    @Test
+    public void testSimpleArrayInt() throws Exception {
+        Element paramElement = parameterElement("testSimpleArrayInt");
+        assertEquals("xs:int", paramElement.getAttribute("type"));
+        assertEquals("unbounded", paramElement.getAttribute("maxOccurs"));
+    }
+
+    @Test
+    @Ignore("TUSCANY-3799")
+    public void testSimpleListString() throws Exception {
+        Element paramElement = parameterElement("testSimpleListString");
+        assertEquals("xs:string", paramElement.getAttribute("type"));
+        assertEquals("unbounded", paramElement.getAttribute("maxOccurs"));
+    }
+
+    @Test
+    public void testComplex() throws Exception {
+        String paramType = parameterType("testComplex");
+        assertEquals("tns:complexNumber", paramType);
+        assertEquals("xs:double", firstChild(typeDefinition(paramType)).getAttribute("type"));
+    }
+
+    @Test
+    public void testByteArray() throws Exception {
+        assertEquals("xs:base64Binary", parameterType("testByteArray"));
+    }
+
+    @Test
+    public void testException() throws Exception {
+        assertEquals("xs:string", faultType("testException", "Exception"));
+    }
+
+    @Test
+    public void testDynamicSDO() throws Exception {
+        assertEquals("xs:anyType", returnType("testDynamicSDO"));
+    }
+
+    private Element parameterElement(String methodName) {
+        Operation op = portType.getOperation(methodName, null, null);
+        Input in = op.getInput();
+        Message msg = in.getMessage();
+        Part part = msg.getPart(msg.getQName().getLocalPart());
+        QName elementQName = part.getElementName();
+        return schemaElement(elementQName);
+    }
+
+    private String parameterType(String methodName) {
+        return parameterElement(methodName).getAttribute("type");
+    }
+
+    private Element returnElement(String methodName) {
+        Operation op = portType.getOperation(methodName, null, null);
+        Output out = op.getOutput();
+        Message msg = out.getMessage();
+        Part part = msg.getPart(msg.getQName().getLocalPart());
+        QName elementQName = part.getElementName();
+        return schemaElement(elementQName);
+    }
+
+    private String returnType(String methodName) {
+        return returnElement(methodName).getAttribute("type");
+    }
+
+    private Element faultElement(String methodName, String faultName) {
+        Operation op = portType.getOperation(methodName, null, null);
+        Fault fault = op.getFault(faultName);
+        Message msg = fault.getMessage();
+        Part part = msg.getPart(msg.getQName().getLocalPart());
+        QName elementQName = part.getElementName();
+        return schemaElement(elementQName);
+    }
+
+    private String faultType(String methodName, String faultName) {
+        return faultElement(methodName, faultName).getAttribute("type");
+    }
+
+    private Element schemaElement(QName elementQName) {
+        // find schema definition for wrapper element
+        Element schema = schemaMap.get(elementQName.getNamespaceURI());
+
+        // find namespace prefixes for this schema definition
+        NamedNodeMap attrNodes = schema.getAttributes();
+        for (int i = 0; i < attrNodes.getLength(); i++) {
+            Attr attr = (Attr)attrNodes.item(i);
+            String attrName = attr.getName();
+            if (attrName.startsWith("xmlns:")) {
+                prefixMap.put(attrName.substring(6), attr.getValue());
+            }
+        }
+
+        // find wrapper element definition in schema
+        String elementName = elementQName.getLocalPart();
+        Element wrapper = null;
+        NodeList childNodes = schema.getElementsByTagNameNS(SCHEMA_NS, "element");
+        for (int i = 0; i < childNodes.getLength(); i++) {
+            Node childNode = childNodes.item(i);
+            if (childNode instanceof Element) {
+                String name = ((Element)childNode).getAttribute("name");
+                if (elementName.equals(name)) {
+                    wrapper = (Element)childNode;
+                    break;
+                }
+            }
+        }
+
+        // find type definition for wrapper element
+        String typeName = wrapper.getAttribute("type");
+        Element wrapperType = null;
+        if ("".equals(typeName)) {
+            childNodes = wrapper.getElementsByTagNameNS(SCHEMA_NS, "complexType");
+            wrapperType = (Element)childNodes.item(0);
+        } else {
+            wrapperType = typeDefinition(typeName);
+        }
+
+        return firstChild(wrapperType);
+    }
+
+    private Element typeDefinition(String typeName) {
+        String typePrefix = typeName.substring(0, typeName.indexOf(":"));
+        String typeLocalName = typeName.substring(typeName.indexOf(":") + 1);
+        Element typeSchema = schemaMap.get(prefixMap.get(typePrefix));
+        Element typeElement = null;
+        NodeList childNodes = typeSchema.getElementsByTagNameNS(SCHEMA_NS, "complexType");
+        for (int i = 0; i < childNodes.getLength(); i++) {
+            Node childNode = childNodes.item(i);
+            if (childNode instanceof Element) {
+                String name = ((Element)childNode).getAttribute("name");
+                if (typeLocalName.equals(name)) {
+                    typeElement = (Element)childNode;
+                    break;
+                }
+            }
+        }
+        return typeElement;
+    }
+
+    private Element firstChild(Element complexType) {
+        // find xs:sequence child element
+        NodeList childNodes = complexType.getElementsByTagNameNS(SCHEMA_NS, "sequence");
+        Element sequence = (Element)childNodes.item(0);
+
+        // find first xs:element child element
+        childNodes = sequence.getElementsByTagNameNS(SCHEMA_NS, "element");
+        return (Element)childNodes.item(0);
+    }
+
+    private static void readWSDL() throws Exception {
+        if (portType == null) {
+            InputStream inp = new URL("http://localhost:8085/DataTypes?wsdl").openStream();
+            BufferedReader br = new BufferedReader(new InputStreamReader(inp));
+            String line;
+            while((line = br.readLine()) != null) {
+                System.out.println(line);
+            }
+            br.close();
+
+            WSDLReader wsdlReader = WSDLFactory.newInstance().newWSDLReader();
+            wsdlReader.setFeature("javax.wsdl.verbose",false);
+            wsdlReader.setFeature("javax.wsdl.importDocuments",true);
+
+            Definition definition = wsdlReader.readWSDL("http://localhost:8085/DataTypes?wsdl");
+            assertNotNull(definition);
+
+            // find portType
+            Service service = definition.getService(new QName("http://verify.wsdlgen/", "DataTypesService"));
+            Port port = service.getPort("DataTypesPort");
+            Binding binding = port.getBinding();
+            portType = binding.getPortType();
+
+            // find schema definitions
+            Types types = definition.getTypes();
+            schemaMap = new HashMap<String, Element>();
+            for (Object ext : types.getExtensibilityElements()) {
+                ExtensibilityElement extElement = (ExtensibilityElement)ext;
+                if (SCHEMA_QNAME.equals(extElement.getElementType())) {
+                    if (extElement instanceof Schema) {
+                        Element schemaElement = ((Schema)extElement).getElement();
+                        schemaMap.put(schemaElement.getAttribute("targetNamespace"), schemaElement);
+                    }
+                }
+            }
+        }
+    }
+
+    /*
+     * Used for debugging DOM problems
+     */
+    private void printDOM(Node node){
+        try {
+            Transformer transformer = TransformerFactory.newInstance().newTransformer();
+            Source source = new DOMSource(node);
+            Result result = new StreamResult(System.out);
+            transformer.transform(source, result);
+        } catch (Exception ex){
+            ex.printStackTrace();
+        }
+    }
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        domain = SCADomain.newInstance("DataTypes.composite");
+        readWSDL();
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {
+        domain.close();
+    }
+}
