diff --git a/tomee/tomee-plume-webapp/pom.xml b/tomee/tomee-plume-webapp/pom.xml
index 2e727e5..c49a4a1 100644
--- a/tomee/tomee-plume-webapp/pom.xml
+++ b/tomee/tomee-plume-webapp/pom.xml
@@ -551,10 +551,17 @@
           <source>1.8</source>
           <target>1.8</target>
           <dependencies>
+            <dependency>org.apache.aries.blueprint:blueprint-parser:jar:1.6.0</dependency>
+            <dependency>org.apache.aries.blueprint:org.apache.aries.blueprint.api:jar:1.0.1</dependency>
+            <dependency>org.apache.aries.blueprint:org.apache.aries.blueprint.core:jar:1.10.2</dependency>
             <dependency>org.apache.tomcat:tomcat-servlet-api:jar:10.0.4</dependency>
-            <dependency>org.springframework:spring-core:jar:5.3.6</dependency>
-            <dependency>org.springframework:spring-context:jar:5.3.6</dependency>
+            <dependency>org.osgi:org.osgi.core:jar:6.0.0</dependency>
+            <dependency>org.osgi:osgi.cmpn:jar:6.0.0</dependency>
+            <dependency>org.ow2.asm:asm:jar:9.1</dependency>
+            <dependency>org.springframework:spring-aop:jar:5.3.6</dependency>
             <dependency>org.springframework:spring-beans:jar:5.3.6</dependency>
+            <dependency>org.springframework:spring-context:jar:5.3.6</dependency>
+            <dependency>org.springframework:spring-core:jar:5.3.6</dependency>
             <dependency>org.springframework:spring-webmvc:jar:5.3.6</dependency>
           </dependencies>
         </configuration>
diff --git a/transform/src/patch/java/org/apache/cxf/annotations/Policy.java b/transform/src/patch/java/org/apache/cxf/annotations/Policy.java
new file mode 100644
index 0000000..a0d4a75
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/annotations/Policy.java
@@ -0,0 +1,80 @@
+/**
+ * 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.cxf.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Attaches a Policy to a service or method
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Inherited
+public @interface Policy {
+
+    String uri();
+
+    boolean includeInWSDL() default true;
+
+
+    /**
+     * The place to put the PolicyReference.  The Default depends on the
+     * location of the annotation.   On the method in the SEI, it would be
+     * the binding/operation, on the SEI, it would be the binding, on the
+     * service impl, the service element.
+     * @return location
+     */
+    Placement placement() default Placement.DEFAULT;
+
+    /**
+     * If Placement is PORT_TYPE_OPERATION_FAULT, or BINDING_OPERATION_FAULT,
+     * return the fault class associated with this documentation
+     * @return the fault class
+     */
+    Class<?> faultClass() default DEFAULT.class;
+
+    enum Placement {
+        DEFAULT,
+
+        PORT_TYPE,
+        PORT_TYPE_OPERATION,
+        PORT_TYPE_OPERATION_INPUT,
+        PORT_TYPE_OPERATION_OUTPUT,
+        PORT_TYPE_OPERATION_FAULT,
+
+        BINDING,
+        BINDING_OPERATION,
+        BINDING_OPERATION_INPUT,
+        BINDING_OPERATION_OUTPUT,
+        BINDING_OPERATION_FAULT,
+
+        SERVICE,
+        SERVICE_PORT,
+    }
+
+    final class DEFAULT { }
+}
+
diff --git a/transform/src/patch/java/org/apache/cxf/annotations/WSDLDocumentation.java b/transform/src/patch/java/org/apache/cxf/annotations/WSDLDocumentation.java
new file mode 100644
index 0000000..9116f1c
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/annotations/WSDLDocumentation.java
@@ -0,0 +1,88 @@
+/**
+ * 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.cxf.annotations;
+
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * Adds documentation nodes to the generated WSDL
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Inherited
+public @interface WSDLDocumentation {
+    /**
+     * The documentation to add
+     * @return documentation string
+     */
+    String value();
+
+    /**
+     * The place to put the documentation.  The Default depends on the
+     * location of the annotation.   On the method in the SEI, it would be
+     * the portType/operation, on the SEI, it would be the portType, on the
+     * service impl, the service element.
+     * @return location
+     */
+    Placement placement() default Placement.DEFAULT;
+
+    /**
+     * If Placement is FAULT_MESSAGE, PORT_FAULT, or BINDING_FAULT,
+     * return the fault class associated with this documentation
+     * @return the fault class
+     */
+    Class<?> faultClass() default DEFAULT.class;
+
+    enum Placement {
+        DEFAULT,
+        TOP,
+
+        INPUT_MESSAGE,
+        OUTPUT_MESSAGE,
+        FAULT_MESSAGE,
+
+        PORT_TYPE,
+        PORT_TYPE_OPERATION,
+        PORT_TYPE_OPERATION_INPUT,
+        PORT_TYPE_OPERATION_OUTPUT,
+        PORT_TYPE_OPERATION_FAULT,
+
+        BINDING,
+        BINDING_OPERATION,
+        BINDING_OPERATION_INPUT,
+        BINDING_OPERATION_OUTPUT,
+        BINDING_OPERATION_FAULT,
+
+        SERVICE,
+        SERVICE_PORT,
+
+    }
+
+
+    final class DEFAULT { }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/attachment/AttachmentDataSource.java b/transform/src/patch/java/org/apache/cxf/attachment/AttachmentDataSource.java
new file mode 100644
index 0000000..6e4fa1a
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/attachment/AttachmentDataSource.java
@@ -0,0 +1,107 @@
+/**
+ * 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.cxf.attachment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.activation.DataSource;
+
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.io.CacheSizeExceededException;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.message.Message;
+
+public class AttachmentDataSource implements DataSource {
+
+    private final String ct;
+    private CachedOutputStream cache;
+    private InputStream ins;
+    private DelegatingInputStream delegate;
+    private String name;
+
+    public AttachmentDataSource(String ctParam, InputStream inParam) {
+        this.ct = ctParam;
+        ins = inParam;
+    }
+
+    public boolean isCached() {
+        return cache != null;
+    }
+    public void cache(Message message) throws IOException {
+        if (cache == null) {
+            cache = new CachedOutputStream();
+            AttachmentUtil.setStreamedAttachmentProperties(message, cache);
+            try {
+                IOUtils.copyAndCloseInput(ins, cache);
+                cache.lockOutputStream();
+                if (delegate != null) {
+                    delegate.setInputStream(cache.getInputStream());
+                }
+            } catch (CacheSizeExceededException | IOException cee) {
+                cache.close();
+                cache = null;
+                throw cee;
+            } finally {
+                ins = null;
+            }
+        }
+    }
+    public void hold(Message message) throws IOException {
+        cache(message);
+        cache.holdTempFile();
+    }
+    public void release() {
+        if (cache != null) {
+            cache.releaseTempFileHold();
+        }
+    }
+
+    public String getContentType() {
+        return ct;
+    }
+
+    public InputStream getInputStream() {
+        try {
+            if (cache != null) {
+                return cache.getInputStream();
+            }
+            if (delegate == null) {
+                delegate = new DelegatingInputStream(ins);
+            }
+            return delegate;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public OutputStream getOutputStream() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/attachment/AttachmentDeserializer.java b/transform/src/patch/java/org/apache/cxf/attachment/AttachmentDeserializer.java
new file mode 100644
index 0000000..55a1dcc
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/attachment/AttachmentDeserializer.java
@@ -0,0 +1,462 @@
+/**
+ * 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.cxf.attachment;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.activation.DataSource;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.common.util.SystemPropertyAction;
+import org.apache.cxf.helpers.HttpHeaderHelper;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.message.Attachment;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+
+public class AttachmentDeserializer {
+    public static final String ATTACHMENT_PART_HEADERS = AttachmentDeserializer.class.getName() + ".headers";
+
+    /**
+     * Allowed value is any instance of {@link File} or {@link String}.
+     */
+    public static final String ATTACHMENT_DIRECTORY = "attachment-directory";
+
+    /**
+     * The memory threshold of attachments. Allowed value is any instance of {@link Number} or {@link String}.
+     * The default is {@link AttachmentDeserializer#THRESHOLD}.
+     */
+    public static final String ATTACHMENT_MEMORY_THRESHOLD = "attachment-memory-threshold";
+
+    /**
+     * The maximum size of the attachment. Allowed value is any of {@link Number} or {@link String}.
+     */
+    public static final String ATTACHMENT_MAX_SIZE = "attachment-max-size";
+
+    /**
+     * The maximum number of attachments permitted in a message. The default is 50.
+     */
+    public static final String ATTACHMENT_MAX_COUNT = "attachment-max-count";
+
+    /**
+     * The maximum MIME Header Length. The default is 300.
+     */
+    public static final String ATTACHMENT_MAX_HEADER_SIZE = "attachment-max-header-size";
+    public static final int DEFAULT_MAX_HEADER_SIZE =
+        SystemPropertyAction.getInteger("org.apache.cxf.attachment-max-header-size", 300);
+
+    public static final int THRESHOLD = 1024 * 100; //100K (byte unit)
+
+    private static final Pattern CONTENT_TYPE_BOUNDARY_PATTERN = Pattern.compile("boundary=\"?([^\";]*)");
+
+    private static final Pattern INPUT_STREAM_BOUNDARY_PATTERN =
+            Pattern.compile("^--(\\S*)$", Pattern.MULTILINE);
+
+    private static final Logger LOG = LogUtils.getL7dLogger(AttachmentDeserializer.class);
+
+    private static final int PUSHBACK_AMOUNT = 2048;
+
+    private boolean lazyLoading = true;
+
+    private PushbackInputStream stream;
+    private int createCount;
+    private int closedCount;
+    private boolean closed;
+
+    private byte[] boundary;
+
+    private LazyAttachmentCollection attachments;
+
+    private Message message;
+
+    private InputStream body;
+
+    private Set<DelegatingInputStream> loaded = new HashSet<>();
+    private List<String> supportedTypes;
+
+    private int maxHeaderLength = DEFAULT_MAX_HEADER_SIZE;
+
+    public AttachmentDeserializer(Message message) {
+        this(message, Collections.singletonList("multipart/related"));
+    }
+
+    public AttachmentDeserializer(Message message, List<String> supportedTypes) {
+        this.message = message;
+        this.supportedTypes = supportedTypes;
+
+        // Get the maximum Header length from configuration
+        maxHeaderLength = MessageUtils.getContextualInteger(message, ATTACHMENT_MAX_HEADER_SIZE,
+                                                            DEFAULT_MAX_HEADER_SIZE);
+    }
+
+    public void initializeAttachments() throws IOException {
+        initializeRootMessage();
+
+        Object maxCountProperty = message.getContextualProperty(AttachmentDeserializer.ATTACHMENT_MAX_COUNT);
+        int maxCount = 50;
+        if (maxCountProperty != null) {
+            if (maxCountProperty instanceof Integer) {
+                maxCount = (Integer)maxCountProperty;
+            } else {
+                maxCount = Integer.parseInt((String)maxCountProperty);
+            }
+        }
+
+        attachments = new LazyAttachmentCollection(this, maxCount);
+        message.setAttachments(attachments);
+    }
+
+    protected void initializeRootMessage() throws IOException {
+        String contentType = (String) message.get(Message.CONTENT_TYPE);
+
+        if (contentType == null) {
+            throw new IllegalStateException("Content-Type can not be empty!");
+        }
+
+        if (message.getContent(InputStream.class) == null) {
+            throw new IllegalStateException("An InputStream must be provided!");
+        }
+
+        if (AttachmentUtil.isTypeSupported(contentType.toLowerCase(), supportedTypes)) {
+            String boundaryString = findBoundaryFromContentType(contentType);
+            if (null == boundaryString) {
+                boundaryString = findBoundaryFromInputStream();
+            }
+            // If a boundary still wasn't found, throw an exception
+            if (null == boundaryString) {
+                throw new IOException("Couldn't determine the boundary from the message!");
+            }
+            boundary = boundaryString.getBytes(StandardCharsets.UTF_8);
+
+            stream = new PushbackInputStream(message.getContent(InputStream.class), PUSHBACK_AMOUNT);
+            if (!readTillFirstBoundary(stream, boundary)) {
+                throw new IOException("Couldn't find MIME boundary: " + boundaryString);
+            }
+
+            Map<String, List<String>> ih = loadPartHeaders(stream);
+            message.put(ATTACHMENT_PART_HEADERS, ih);
+            String val = AttachmentUtil.getHeader(ih, "Content-Type", "; ");
+            if (!StringUtils.isEmpty(val)) {
+                String cs = HttpHeaderHelper.findCharset(val);
+                if (!StringUtils.isEmpty(cs)) {
+                    message.put(Message.ENCODING, HttpHeaderHelper.mapCharset(cs));
+                }
+            }
+            val = AttachmentUtil.getHeader(ih, "Content-Transfer-Encoding");
+
+            MimeBodyPartInputStream mmps = new MimeBodyPartInputStream(stream, boundary, PUSHBACK_AMOUNT);
+            InputStream ins = AttachmentUtil.decode(mmps, val);
+            if (ins != mmps) {
+                ih.remove("Content-Transfer-Encoding");
+            }
+            body = new DelegatingInputStream(ins, this);
+            createCount++;
+            message.setContent(InputStream.class, body);
+        }
+    }
+
+    private String findBoundaryFromContentType(String ct) {
+        // Use regex to get the boundary and return null if it's not found
+        Matcher m = CONTENT_TYPE_BOUNDARY_PATTERN.matcher(ct);
+        return m.find() ? "--" + m.group(1) : null;
+    }
+
+    private String findBoundaryFromInputStream() throws IOException {
+        InputStream is = message.getContent(InputStream.class);
+        //boundary should definitely be in the first 2K;
+        PushbackInputStream in = new PushbackInputStream(is, 4096);
+        byte[] buf = new byte[2048];
+        int i = in.read(buf);
+        int len = i;
+        while (i > 0 && len < buf.length) {
+            i = in.read(buf, len, buf.length - len);
+            if (i > 0) {
+                len += i;
+            }
+        }
+        String msg = IOUtils.newStringFromBytes(buf, 0, len);
+        in.unread(buf, 0, len);
+
+        // Reset the input stream since we'll need it again later
+        message.setContent(InputStream.class, in);
+
+        // Use regex to get the boundary and return null if it's not found
+        Matcher m = INPUT_STREAM_BOUNDARY_PATTERN.matcher(msg);
+        return m.find() ? "--" + m.group(1) : null;
+    }
+
+    public AttachmentImpl readNext() throws IOException {
+        // Cache any mime parts that are currently being streamed
+        cacheStreamedAttachments();
+        if (closed) {
+            return null;
+        }
+
+        int v = stream.read();
+        if (v == -1) {
+            return null;
+        }
+        stream.unread(v);
+
+        Map<String, List<String>> headers = loadPartHeaders(stream);
+        return (AttachmentImpl)createAttachment(headers);
+    }
+
+    private void cacheStreamedAttachments() throws IOException {
+        if (body instanceof DelegatingInputStream
+            && !((DelegatingInputStream) body).isClosed()) {
+
+            cache((DelegatingInputStream) body);
+        }
+
+        List<Attachment> atts = new ArrayList<>(attachments.getLoadedAttachments());
+        for (Attachment a : atts) {
+            DataSource s = a.getDataHandler().getDataSource();
+            if (s instanceof AttachmentDataSource) {
+                AttachmentDataSource ads = (AttachmentDataSource)s;
+                if (!ads.isCached()) {
+                    ads.cache(message);
+                }
+            } else if (s.getInputStream() instanceof DelegatingInputStream) {
+                cache((DelegatingInputStream) s.getInputStream());
+            } else {
+                //assume a normal stream that is already cached
+            }
+        }
+    }
+
+    private void cache(DelegatingInputStream input) throws IOException {
+        if (loaded.contains(input)) {
+            return;
+        }
+        loaded.add(input);
+        InputStream origIn = input.getInputStream();
+        try (CachedOutputStream out = new CachedOutputStream()) {
+            AttachmentUtil.setStreamedAttachmentProperties(message, out);
+            IOUtils.copy(input, out);
+            input.setInputStream(out.getInputStream());
+            origIn.close();
+        }
+    }
+
+    /**
+     * Move the read pointer to the begining of the first part read till the end
+     * of first boundary
+     *
+     * @param pushbackInStream
+     * @param boundary
+     * @throws IOException
+     */
+    private static boolean readTillFirstBoundary(PushbackInputStream pushbackInStream,
+        byte[] boundary) throws IOException {
+
+        // work around a bug in PushBackInputStream where the buffer isn't
+        // initialized
+        // and available always returns 0.
+        int value = pushbackInStream.read();
+        pushbackInStream.unread(value);
+        while (value != -1) {
+            value = pushbackInStream.read();
+            if ((byte) value == boundary[0]) {
+                int boundaryIndex = 0;
+                while (value != -1 && (boundaryIndex < boundary.length) && ((byte) value == boundary[boundaryIndex])) {
+
+                    value = pushbackInStream.read();
+                    if (value == -1) {
+                        throw new IOException("Unexpected End while searching for first Mime Boundary");
+                    }
+                    boundaryIndex++;
+                }
+                if (boundaryIndex == boundary.length) {
+                    // boundary found, read the newline
+                    if (value == 13) {
+                        pushbackInStream.read();
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Create an Attachment from the MIME stream. If there is a previous attachment
+     * that is not read, cache that attachment.
+     *
+     * @throws IOException
+     */
+    private Attachment createAttachment(Map<String, List<String>> headers) throws IOException {
+        InputStream partStream =
+            new DelegatingInputStream(new MimeBodyPartInputStream(stream, boundary, PUSHBACK_AMOUNT),
+                                      this);
+        createCount++;
+
+        return AttachmentUtil.createAttachment(partStream, headers);
+    }
+
+    public boolean isLazyLoading() {
+        return lazyLoading;
+    }
+
+    public void setLazyLoading(boolean lazyLoading) {
+        this.lazyLoading = lazyLoading;
+    }
+
+    public void markClosed(DelegatingInputStream delegatingInputStream) throws IOException {
+        closedCount++;
+        if (closedCount == createCount && !attachments.hasNext(false)) {
+            int x = stream.read();
+            while (x != -1) {
+                x = stream.read();
+            }
+            stream.close();
+            closed = true;
+        }
+    }
+    /**
+     *  Check for more attachment.
+     *
+     * @return whether there is more attachment or not.  It will not deserialize the next attachment.
+     * @throws IOException
+     */
+    public boolean hasNext() throws IOException {
+        cacheStreamedAttachments();
+        if (closed) {
+            return false;
+        }
+
+        int v = stream.read();
+        if (v == -1) {
+            return false;
+        }
+        stream.unread(v);
+        return true;
+    }
+
+
+
+    private Map<String, List<String>> loadPartHeaders(InputStream in) throws IOException {
+        StringBuilder buffer = new StringBuilder(128);
+        StringBuilder b = new StringBuilder(128);
+        Map<String, List<String>> heads = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+        // loop until we hit the end or a null line
+        while (readLine(in, b)) {
+            // lines beginning with white space get special handling
+            char c = b.charAt(0);
+            if (c == ' ' || c == '\t') {
+                if (buffer.length() != 0) {
+                    // preserve the line break and append the continuation
+                    buffer.append("\r\n");
+                    buffer.append(b);
+                }
+            } else {
+                // if we have a line pending in the buffer, flush it
+                if (buffer.length() > 0) {
+                    addHeaderLine(heads, buffer);
+                    buffer.setLength(0);
+                }
+                // add this to the accumulator
+                buffer.append(b);
+            }
+        }
+
+        // if we have a line pending in the buffer, flush it
+        if (buffer.length() > 0) {
+            addHeaderLine(heads, buffer);
+        }
+        return heads;
+    }
+
+    private boolean readLine(InputStream in, StringBuilder buffer) throws IOException {
+        if (buffer.length() != 0) {
+            buffer.setLength(0);
+        }
+        int c;
+
+        while ((c = in.read()) != -1) {
+            // a linefeed is a terminator, always.
+            if (c == '\n') {
+                break;
+            } else if (c == '\r') {
+                //just ignore the CR.  The next character SHOULD be an NL.  If not, we're
+                //just going to discard this
+                continue;
+            } else {
+                // just add to the buffer
+                buffer.append((char)c);
+            }
+
+            if (buffer.length() > maxHeaderLength) {
+                LOG.fine("The attachment header size has exceeded the configured parameter: " + maxHeaderLength);
+                throw new HeaderSizeExceededException();
+            }
+        }
+
+        // no characters found...this was either an eof or a null line.
+        return buffer.length() != 0;
+    }
+
+    private void addHeaderLine(Map<String, List<String>> heads, StringBuilder line) {
+        // null lines are a nop
+        final int size = line.length();
+        if (size == 0) {
+            return;
+        }
+        int separator = line.indexOf(":");
+        final String name;
+        String value = "";
+        if (separator == -1) {
+            name = line.toString().trim();
+        } else {
+            name = line.substring(0, separator);
+            // step past the separator.  Now we need to remove any leading white space characters.
+            separator++;
+
+            while (separator < size) {
+                char ch = line.charAt(separator);
+                if (ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n') {
+                    break;
+                }
+                separator++;
+            }
+            value = line.substring(separator);
+        }
+        List<String> v = heads.computeIfAbsent(name, k -> new ArrayList<>(1));
+        v.add(value);
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/attachment/AttachmentSerializer.java b/transform/src/patch/java/org/apache/cxf/attachment/AttachmentSerializer.java
new file mode 100644
index 0000000..3e65de3
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/attachment/AttachmentSerializer.java
@@ -0,0 +1,345 @@
+/**
+ * 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.cxf.attachment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.DataHandler;
+
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.message.Attachment;
+import org.apache.cxf.message.Message;
+
+
+
+
+public class AttachmentSerializer {
+    // http://tools.ietf.org/html/rfc2387
+    private static final String DEFAULT_MULTIPART_TYPE = "multipart/related";
+
+    private String contentTransferEncoding = AttachmentUtil.BINARY;
+
+    private Message message;
+    private String bodyBoundary;
+    private OutputStream out;
+    private String encoding;
+
+    private String multipartType;
+    private Map<String, List<String>> rootHeaders = Collections.emptyMap();
+    private boolean xop = true;
+    private boolean writeOptionalTypeParameters = true;
+
+
+    public AttachmentSerializer(Message messageParam) {
+        message = messageParam;
+    }
+
+    public AttachmentSerializer(Message messageParam,
+                                String multipartType,
+                                boolean writeOptionalTypeParameters,
+                                Map<String, List<String>> headers) {
+        message = messageParam;
+        this.multipartType = multipartType;
+        this.writeOptionalTypeParameters = writeOptionalTypeParameters;
+        this.rootHeaders = headers;
+    }
+
+    /**
+     * Serialize the beginning of the attachment which includes the MIME
+     * beginning and headers for the root message.
+     */
+    public void writeProlog() throws IOException {
+        // Create boundary for body
+        bodyBoundary = AttachmentUtil.getUniqueBoundaryValue();
+
+        String bodyCt = (String) message.get(Message.CONTENT_TYPE);
+        String bodyCtParams = null;
+        String bodyCtParamsEscaped = null;
+        // split the bodyCt to its head that is the type and its properties so that we
+        // can insert the values at the right places based on the soap version and the mtom option
+        // bodyCt will be of the form
+        // soap11 -> text/xml
+        // soap12 -> application/soap+xml; action="urn:ihe:iti:2007:RetrieveDocumentSet"
+        if (bodyCt.indexOf(';') != -1) {
+            int pos = bodyCt.indexOf(';');
+            // get everything from the semi-colon
+            bodyCtParams = bodyCt.substring(pos);
+            bodyCtParamsEscaped = escapeQuotes(bodyCtParams);
+            // keep the type/subtype part in bodyCt
+            bodyCt = bodyCt.substring(0, pos);
+        }
+        // Set transport mime type
+        String requestMimeType = multipartType == null ? DEFAULT_MULTIPART_TYPE : multipartType;
+
+        StringBuilder ct = new StringBuilder(32);
+        ct.append(requestMimeType);
+
+        // having xop set to true implies multipart/related, but just in case...
+        boolean xopOrMultipartRelated = xop
+            || DEFAULT_MULTIPART_TYPE.equalsIgnoreCase(requestMimeType)
+            || DEFAULT_MULTIPART_TYPE.startsWith(requestMimeType);
+
+        // type is a required parameter for multipart/related only
+        if (xopOrMultipartRelated
+            && requestMimeType.indexOf("type=") == -1) {
+            if (xop) {
+                ct.append("; type=\"application/xop+xml\"");
+            } else {
+                ct.append("; type=\"").append(bodyCt).append('"');
+            }
+        }
+
+        // boundary
+        ct.append("; boundary=\"")
+            .append(bodyBoundary)
+            .append('"');
+
+        String rootContentId = getHeaderValue("Content-ID", AttachmentUtil.BODY_ATTACHMENT_ID);
+
+        // 'start' is a required parameter for XOP/MTOM, clearly defined
+        // for simpler multipart/related payloads but is not needed for
+        // multipart/mixed, multipart/form-data
+        if (xopOrMultipartRelated) {
+            ct.append("; start=\"<")
+                .append(checkAngleBrackets(rootContentId))
+                .append(">\"");
+        }
+
+        // start-info is a required parameter for XOP/MTOM, may be needed for
+        // other WS cases but is redundant in simpler multipart/related cases
+        // the parameters need to be included within the start-info's value in the escaped form
+        if (writeOptionalTypeParameters || xop) {
+            ct.append("; start-info=\"")
+                .append(bodyCt);
+            if (bodyCtParamsEscaped != null) {
+                ct.append(bodyCtParamsEscaped);
+            }
+            ct.append('"');
+        }
+
+
+        message.put(Message.CONTENT_TYPE, ct.toString());
+
+
+        // 2. write headers
+        out = message.getContent(OutputStream.class);
+        encoding = (String) message.get(Message.ENCODING);
+        if (encoding == null) {
+            encoding = StandardCharsets.UTF_8.name();
+        }
+        StringWriter writer = new StringWriter();
+        writer.write("\r\n");
+        writer.write("--");
+        writer.write(bodyBoundary);
+
+        StringBuilder mimeBodyCt = new StringBuilder();
+        String bodyType = getHeaderValue("Content-Type", null);
+        if (bodyType == null) {
+            mimeBodyCt.append(xop ? "application/xop+xml" : bodyCt)
+                .append("; charset=").append(encoding);
+            if (xop) {
+                mimeBodyCt.append("; type=\"").append(bodyCt);
+                if (bodyCtParamsEscaped != null) {
+                    mimeBodyCt.append(bodyCtParamsEscaped);
+                }
+                mimeBodyCt.append('"');
+            } else if (bodyCtParams != null) {
+                mimeBodyCt.append(bodyCtParams);
+            }
+        } else {
+            mimeBodyCt.append(bodyType);
+        }
+
+        writeHeaders(mimeBodyCt.toString(), rootContentId, rootHeaders, writer);
+        out.write(writer.getBuffer().toString().getBytes(encoding));
+    }
+
+    private static String escapeQuotes(String s) {
+        return s.indexOf('"') != 0 ? s.replace("\"", "\\\"") : s;
+    }
+
+    public void setContentTransferEncoding(String cte) {
+        contentTransferEncoding = cte;
+    }
+
+    private String getHeaderValue(String name, String defaultValue) {
+        List<String> value = rootHeaders.get(name);
+        if (value == null || value.isEmpty()) {
+            return defaultValue;
+        }
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < value.size(); i++) {
+            sb.append(value.get(i));
+            if (i + 1 < value.size()) {
+                sb.append(',');
+            }
+        }
+        return sb.toString();
+    }
+
+    private void writeHeaders(String contentType, String attachmentId,
+                                     Map<String, List<String>> headers, Writer writer) throws IOException {
+        writer.write("\r\nContent-Type: ");
+        writer.write(contentType);
+        writer.write("\r\nContent-Transfer-Encoding: " + contentTransferEncoding + "\r\n");
+
+        if (attachmentId != null) {
+            attachmentId = checkAngleBrackets(attachmentId);
+            writer.write("Content-ID: <");
+            writer.write(URLDecoder.decode(attachmentId, StandardCharsets.UTF_8.name()));
+            writer.write(">\r\n");
+        }
+        // headers like Content-Disposition need to be serialized
+        for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
+            String name = entry.getKey();
+            if ("Content-Type".equalsIgnoreCase(name) || "Content-ID".equalsIgnoreCase(name)
+                || "Content-Transfer-Encoding".equalsIgnoreCase(name)) {
+                continue;
+            }
+            writer.write(name);
+            writer.write(": ");
+            List<String> values = entry.getValue();
+            for (int i = 0; i < values.size(); i++) {
+                writer.write(values.get(i));
+                if (i + 1 < values.size()) {
+                    writer.write(",");
+                }
+            }
+            writer.write("\r\n");
+        }
+
+        writer.write("\r\n");
+    }
+
+    private static String checkAngleBrackets(String value) {
+        if (value.charAt(0) == '<' && value.charAt(value.length() - 1) == '>') {
+            return value.substring(1, value.length() - 1);
+        }
+        return value;
+    }
+
+    /**
+     * Write the end of the body boundary and any attachments included.
+     * @throws IOException
+     */
+    public void writeAttachments() throws IOException {
+        if (message.getAttachments() != null) {
+            for (Attachment a : message.getAttachments()) {
+                StringWriter writer = new StringWriter();
+                writer.write("\r\n--");
+                writer.write(bodyBoundary);
+
+                final Map<String, List<String>> headers;
+                Iterator<String> it = a.getHeaderNames();
+                if (it.hasNext()) {
+                    headers = new LinkedHashMap<>();
+                    while (it.hasNext()) {
+                        String key = it.next();
+                        headers.put(key, Collections.singletonList(a.getHeader(key)));
+                    }
+                } else {
+                    headers = Collections.emptyMap();
+                }
+
+
+                DataHandler handler = a.getDataHandler();
+                handler.setCommandMap(AttachmentUtil.getCommandMap());
+
+                writeHeaders(handler.getContentType(), a.getId(),
+                             headers, writer);
+                out.write(writer.getBuffer().toString().getBytes(encoding));
+                if ("base64".equals(contentTransferEncoding)) {
+                    try (InputStream inputStream = handler.getInputStream()) {
+                        encodeBase64(inputStream, out, IOUtils.DEFAULT_BUFFER_SIZE);
+                    }
+                } else {
+                    handler.writeTo(out);
+                }
+            }
+        }
+        StringWriter writer = new StringWriter();
+        writer.write("\r\n--");
+        writer.write(bodyBoundary);
+        writer.write("--");
+        out.write(writer.getBuffer().toString().getBytes(encoding));
+        out.flush();
+    }
+
+    private int encodeBase64(InputStream input, OutputStream output, int bufferSize) throws IOException {
+        int avail = input.available();
+        if (avail > 262143) {
+            //must be divisible by 3
+            avail = 262143;
+        }
+        if (avail > bufferSize) {
+            bufferSize = avail;
+        }
+        final byte[] buffer = new byte[bufferSize];
+        int n = input.read(buffer);
+        int total = 0;
+        while (-1 != n) {
+            if (n == 0) {
+                throw new IOException("0 bytes read in violation of InputStream.read(byte[])");
+            }
+            //make sure n is divisible by 3
+            int left = n % 3;
+            n -= left;
+            if (n > 0) {
+                Base64Utility.encodeAndStream(buffer, 0, n, output);
+                total += n;
+            }
+            if (left != 0) {
+                for (int x = 0; x < left; ++x) {
+                    buffer[x] = buffer[n + x];
+                }
+                n = input.read(buffer, left, buffer.length - left);
+                if (n == -1) {
+                    // we've hit the end, but still have stuff left, write it out
+                    Base64Utility.encodeAndStream(buffer, 0, left, output);
+                    total += left;
+                }
+            } else {
+                n = input.read(buffer);
+            }
+        }
+        return total;
+    }
+
+    public boolean isXop() {
+        return xop;
+    }
+
+    public void setXop(boolean xop) {
+        this.xop = xop;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/attachment/AttachmentUtil.java b/transform/src/patch/java/org/apache/cxf/attachment/AttachmentUtil.java
new file mode 100644
index 0000000..7c72f00
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/attachment/AttachmentUtil.java
@@ -0,0 +1,572 @@
+/**
+ * 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.cxf.attachment;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Logger;
+
+import javax.activation.CommandInfo;
+import javax.activation.CommandMap;
+import javax.activation.DataContentHandler;
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.activation.FileDataSource;
+import javax.activation.MailcapCommandMap;
+import javax.activation.URLDataSource;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.helpers.FileUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.message.Attachment;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+
+public final class AttachmentUtil {
+    public static final String BODY_ATTACHMENT_ID = "root.message@cxf.apache.org";
+
+    static final String BINARY = "binary";
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(AttachmentUtil.class);
+
+    private static final AtomicInteger COUNTER = new AtomicInteger();
+    private static final String ATT_UUID = UUID.randomUUID().toString();
+
+    private static final Random BOUND_RANDOM = new Random();
+    private static final CommandMap DEFAULT_COMMAND_MAP = CommandMap.getDefaultCommandMap();
+    private static final MailcapCommandMap COMMAND_MAP = new EnhancedMailcapCommandMap();
+    
+    
+    static final class EnhancedMailcapCommandMap extends MailcapCommandMap {
+        @Override
+        public synchronized DataContentHandler createDataContentHandler(
+                String mimeType) {
+            DataContentHandler dch = super.createDataContentHandler(mimeType);
+            if (dch == null) {
+                dch = DEFAULT_COMMAND_MAP.createDataContentHandler(mimeType);
+            }
+            return dch;
+        }
+
+        @Override
+        public DataContentHandler createDataContentHandler(String mimeType,
+                DataSource ds) {
+            DataContentHandler dch = super.createDataContentHandler(mimeType);
+            if (dch == null) {
+                dch = DEFAULT_COMMAND_MAP.createDataContentHandler(mimeType, ds);
+            }
+            return dch;
+        }
+
+        @Override
+        public synchronized CommandInfo[] getAllCommands(String mimeType) {
+            CommandInfo[] commands = super.getAllCommands(mimeType);
+            CommandInfo[] defaultCommands = DEFAULT_COMMAND_MAP.getAllCommands(mimeType);
+            List<CommandInfo> cmdList = new ArrayList<>(Arrays.asList(commands));
+
+            // Add CommandInfo which does not exist in current command map.
+            for (CommandInfo defCmdInfo : defaultCommands) {
+                String defCmdName = defCmdInfo.getCommandName();
+                boolean cmdNameExist = false;
+                for (CommandInfo cmdInfo : commands) {
+                    if (cmdInfo.getCommandName().equals(defCmdName)) {
+                        cmdNameExist = true;
+                        break;
+                    }
+                }
+                if (!cmdNameExist) {
+                    cmdList.add(defCmdInfo);
+                }
+            }
+
+            CommandInfo[] allCommandArray = new CommandInfo[0];
+            return cmdList.toArray(allCommandArray);
+        }
+
+        @Override
+        public synchronized CommandInfo getCommand(String mimeType, String cmdName) {
+            CommandInfo cmdInfo = super.getCommand(mimeType, cmdName);
+            if (cmdInfo == null) {
+                cmdInfo = DEFAULT_COMMAND_MAP.getCommand(mimeType, cmdName);
+            }
+            return cmdInfo;
+        }
+
+        /**
+         * Merge current mime types and default mime types.
+         */
+        @Override
+        public synchronized String[] getMimeTypes() {
+            String[] mimeTypes = super.getMimeTypes();
+            String[] defMimeTypes = DEFAULT_COMMAND_MAP.getMimeTypes();
+            Set<String> mimeTypeSet = new HashSet<>();
+            Collections.addAll(mimeTypeSet, mimeTypes);
+            Collections.addAll(mimeTypeSet, defMimeTypes);
+            String[] mimeArray = new String[0];
+            return mimeTypeSet.toArray(mimeArray);
+        }
+    }
+
+
+    private AttachmentUtil() {
+
+    }
+
+    static {
+        COMMAND_MAP.addMailcap("image/*;;x-java-content-handler="
+                               + ImageDataContentHandler.class.getName());
+    }
+
+    public static CommandMap getCommandMap() {
+        return COMMAND_MAP;
+    }
+
+    public static boolean isMtomEnabled(Message message) {
+        return MessageUtils.getContextualBoolean(message, Message.MTOM_ENABLED, false);
+    }
+
+    public static void setStreamedAttachmentProperties(Message message, CachedOutputStream bos)
+        throws IOException {
+        Object directory = message.getContextualProperty(AttachmentDeserializer.ATTACHMENT_DIRECTORY);
+        if (directory != null) {
+            if (directory instanceof File) {
+                bos.setOutputDir((File) directory);
+            } else if (directory instanceof String) {
+                bos.setOutputDir(new File((String) directory));
+            } else {
+                throw new IOException("The value set as " + AttachmentDeserializer.ATTACHMENT_DIRECTORY
+                        + " should be either an instance of File or String");
+            }
+        }
+
+        Object threshold = message.getContextualProperty(AttachmentDeserializer.ATTACHMENT_MEMORY_THRESHOLD);
+        if (threshold != null) {
+            if (threshold instanceof Number) {
+                long t = ((Number) threshold).longValue();
+                if (t >= 0) {
+                    bos.setThreshold(t);
+                } else {
+                    LOG.warning("Threshold value overflowed long. Setting default value!");
+                    bos.setThreshold(AttachmentDeserializer.THRESHOLD);
+                }
+            } else if (threshold instanceof String) {
+                try {
+                    bos.setThreshold(Long.parseLong((String) threshold));
+                } catch (NumberFormatException e) {
+                    throw new IOException("Provided threshold String is not a number", e);
+                }
+            } else {
+                throw new IOException("The value set as " + AttachmentDeserializer.ATTACHMENT_MEMORY_THRESHOLD
+                        + " should be either an instance of Number or String");
+            }
+        } else if (!CachedOutputStream.isThresholdSysPropSet()) {
+            // Use the default AttachmentDeserializer Threshold only if there is no system property defined
+            bos.setThreshold(AttachmentDeserializer.THRESHOLD);
+        }
+
+        Object maxSize = message.getContextualProperty(AttachmentDeserializer.ATTACHMENT_MAX_SIZE);
+        if (maxSize != null) {
+            if (maxSize instanceof Number) {
+                long size = ((Number) maxSize).longValue();
+                if (size >= 0) {
+                    bos.setMaxSize(size);
+                } else {
+                    LOG.warning("Max size value overflowed long. Do not set max size!");
+                }
+            } else if (maxSize instanceof String) {
+                try {
+                    bos.setMaxSize(Long.parseLong((String) maxSize));
+                } catch (NumberFormatException e) {
+                    throw new IOException("Provided threshold String is not a number", e);
+                }
+            } else {
+                throw new IOException("The value set as " + AttachmentDeserializer.ATTACHMENT_MAX_SIZE
+                        + " should be either an instance of Number or String");
+            }
+        }
+    }
+
+    public static String createContentID(String ns) throws UnsupportedEncodingException {
+        // tend to change
+        String cid = "cxf.apache.org";
+        if (ns != null && !ns.isEmpty()) {
+            try {
+                URI uri = new URI(ns);
+                String host = uri.getHost();
+                if (host != null) {
+                    cid = host;
+                } else {
+                    cid = ns;
+                }
+            } catch (Exception e) {
+                cid = ns;
+            }
+        }
+        return ATT_UUID + '-' + Integer.toString(COUNTER.incrementAndGet()) + '@'
+            + URLEncoder.encode(cid, StandardCharsets.UTF_8.name());
+    }
+
+    public static String getUniqueBoundaryValue() {
+        //generate a random UUID.
+        //we don't need the cryptographically secure random uuid that
+        //UUID.randomUUID() will produce.  Thus, use a faster
+        //pseudo-random thing
+        long leastSigBits;
+        long mostSigBits;
+        synchronized (BOUND_RANDOM) {
+            mostSigBits = BOUND_RANDOM.nextLong();
+            leastSigBits = BOUND_RANDOM.nextLong();
+        }
+
+        mostSigBits &= 0xFFFFFFFFFFFF0FFFL;  //clear version
+        mostSigBits |= 0x0000000000004000L;  //set version
+
+        leastSigBits &= 0x3FFFFFFFFFFFFFFFL; //clear the variant
+        leastSigBits |= 0x8000000000000000L; //set to IETF variant
+
+        UUID result = new UUID(mostSigBits, leastSigBits);
+
+        return "uuid:" + result.toString();
+    }
+
+    public static Map<String, DataHandler> getDHMap(final Collection<Attachment> attachments) {
+        Map<String, DataHandler> dataHandlers = null;
+        if (attachments != null) {
+            if (attachments instanceof LazyAttachmentCollection) {
+                dataHandlers = ((LazyAttachmentCollection)attachments).createDataHandlerMap();
+            } else {
+                dataHandlers = new DHMap(attachments);
+            }
+        }
+        return dataHandlers == null ? new LinkedHashMap<>() : dataHandlers;
+    }
+
+    static class DHMap extends AbstractMap<String, DataHandler> {
+        final Collection<Attachment> list;
+        DHMap(Collection<Attachment> l) {
+            list = l;
+        }
+        public Set<Map.Entry<String, DataHandler>> entrySet() {
+            return new AbstractSet<Map.Entry<String, DataHandler>>() {
+                @Override
+                public Iterator<Map.Entry<String, DataHandler>> iterator() {
+                    final Iterator<Attachment> it = list.iterator();
+                    return new Iterator<Map.Entry<String, DataHandler>>() {
+                        public boolean hasNext() {
+                            return it.hasNext();
+                        }
+                        public Map.Entry<String, DataHandler> next() {
+                            final Attachment a = it.next();
+                            return new Map.Entry<String, DataHandler>() {
+                                @Override
+                                public String getKey() {
+                                    return a.getId();
+                                }
+
+                                @Override
+                                public DataHandler getValue() {
+                                    return a.getDataHandler();
+                                }
+
+                                @Override
+                                public DataHandler setValue(DataHandler value) {
+                                    return null;
+                                }
+                            };
+                        }
+                        @Override
+                        public void remove() {
+                            it.remove();
+                        }
+                    };
+                }
+
+                @Override
+                public int size() {
+                    return list.size();
+                }
+            };
+        }
+        
+        @Override
+        public DataHandler put(String key, DataHandler value) {
+            Iterator<Attachment> i = list.iterator();
+            DataHandler ret = null;
+            while (i.hasNext()) {
+                Attachment a = i.next();
+                if (a.getId().equals(key)) {
+                    i.remove();
+                    ret = a.getDataHandler();
+                    break;
+                }
+            }
+            list.add(new AttachmentImpl(key, value));
+            return ret;
+        }
+    }
+
+    public static String cleanContentId(String id) {
+        if (id != null) {
+            if (id.startsWith("<")) {
+                // strip <>
+                id = id.substring(1, id.length() - 1);
+            }
+            // strip cid:
+            if (id.startsWith("cid:")) {
+                id = id.substring(4);
+            }
+            // urldecode. Is this bad even without cid:? What does decode do with malformed %-signs, anyhow?
+            try {
+                id = URLDecoder.decode(id, StandardCharsets.UTF_8.name());
+            } catch (UnsupportedEncodingException e) {
+                //ignore, keep id as is
+            }
+        }
+        if (id == null) {
+            //no Content-ID, set cxf default ID
+            id =  BODY_ATTACHMENT_ID;
+        }
+        return id;
+    }
+
+    static String getHeaderValue(List<String> v) {
+        if (v != null && !v.isEmpty()) {
+            return v.get(0);
+        }
+        return null;
+    }
+    static String getHeaderValue(List<String> v, String delim) {
+        if (v != null && !v.isEmpty()) {
+            return String.join(delim, v);
+        }
+        return null;
+    }
+    static String getHeader(Map<String, List<String>> headers, String h) {
+        return getHeaderValue(headers.get(h));
+    }
+    static String getHeader(Map<String, List<String>> headers, String h, String delim) {
+        return getHeaderValue(headers.get(h), delim);
+    }
+    public static Attachment createAttachment(InputStream stream, Map<String, List<String>> headers)
+        throws IOException {
+
+        String id = cleanContentId(getHeader(headers, "Content-ID"));
+
+        AttachmentImpl att = new AttachmentImpl(id);
+
+        final String ct = getHeader(headers, "Content-Type");
+        String cd = getHeader(headers, "Content-Disposition");
+        String fileName = getContentDispositionFileName(cd);
+
+        String encoding = null;
+
+        for (Map.Entry<String, List<String>> e : headers.entrySet()) {
+            String name = e.getKey();
+            if ("Content-Transfer-Encoding".equalsIgnoreCase(name)) {
+                encoding = getHeader(headers, name);
+                if (BINARY.equalsIgnoreCase(encoding)) {
+                    att.setXOP(true);
+                }
+            }
+            att.setHeader(name, getHeaderValue(e.getValue()));
+        }
+        if (encoding == null) {
+            encoding = BINARY;
+        }
+        InputStream ins = decode(stream, encoding);
+        if (ins != stream) {
+            headers.remove("Content-Transfer-Encoding");
+        }
+        DataSource source = new AttachmentDataSource(ct, ins);
+        if (!StringUtils.isEmpty(fileName)) {
+            ((AttachmentDataSource)source).setName(FileUtils.stripPath(fileName));
+        }
+        att.setDataHandler(new DataHandler(source));
+        return att;
+    }
+
+    static String getContentDispositionFileName(String cd) {
+        if (StringUtils.isEmpty(cd)) {
+            return null;
+        }
+        ContentDisposition c = new ContentDisposition(cd);
+        String s = c.getParameter("filename");
+        if (s == null) {
+            s = c.getParameter("name");
+        }
+        return s;
+    }
+
+    public static InputStream decode(InputStream in, String encoding) throws IOException {
+        if (encoding == null) {
+            return in;
+        }
+        encoding = encoding.toLowerCase();
+
+        // some encodings are just pass-throughs, with no real decoding.
+        if (BINARY.equals(encoding)
+            || "7bit".equals(encoding)
+            || "8bit".equals(encoding)) {
+            return in;
+        } else if ("base64".equals(encoding)) {
+            return new Base64DecoderStream(in);
+        } else if ("quoted-printable".equals(encoding)) {
+            return new QuotedPrintableDecoderStream(in);
+        } else {
+            throw new IOException("Unknown encoding " + encoding);
+        }
+    }
+    public static boolean isTypeSupported(String contentType, List<String> types) {
+        if (contentType == null) {
+            return false;
+        }
+        contentType = contentType.toLowerCase();
+        for (String s : types) {
+            if (contentType.indexOf(s) != -1) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static Attachment createMtomAttachment(boolean isXop, String mimeType, String elementNS,
+                                                 byte[] data, int offset, int length, int threshold) {
+        if (!isXop || length <= threshold) {
+            return null;
+        }
+        if (mimeType == null) {
+            mimeType = "application/octet-stream";
+        }
+
+        ByteDataSource source = new ByteDataSource(data, offset, length);
+        source.setContentType(mimeType);
+        DataHandler handler = new DataHandler(source);
+
+        String id;
+        try {
+            id = AttachmentUtil.createContentID(elementNS);
+        } catch (UnsupportedEncodingException e) {
+            throw new Fault(e);
+        }
+        AttachmentImpl att = new AttachmentImpl(id, handler);
+        att.setXOP(isXop);
+        return att;
+    }
+
+    public static Attachment createMtomAttachmentFromDH(
+        boolean isXop, DataHandler handler, String elementNS, int threshold) {
+        if (!isXop) {
+            return null;
+        }
+
+        // The following is just wrong. Even if the DataHandler has a stream, we should still
+        // apply the threshold.
+        try {
+            DataSource ds = handler.getDataSource();
+            if (ds instanceof FileDataSource) {
+                FileDataSource fds = (FileDataSource)ds;
+                File file = fds.getFile();
+                if (file.length() < threshold) {
+                    return null;
+                }
+            } else if (ds.getClass().getName().endsWith("ObjectDataSource")) {
+                Object o = handler.getContent();
+                if (o instanceof String
+                    && ((String)o).length() < threshold) {
+                    return null;
+                } else if (o instanceof byte[] && ((byte[])o).length < threshold) {
+                    return null;
+                }
+            }
+        } catch (IOException e1) {
+        //      ignore, just do the normal attachment thing
+        }
+
+        String id;
+        try {
+            id = AttachmentUtil.createContentID(elementNS);
+        } catch (UnsupportedEncodingException e) {
+            throw new Fault(e);
+        }
+        AttachmentImpl att = new AttachmentImpl(id, handler);
+        if (!StringUtils.isEmpty(handler.getName())) {
+            //set Content-Disposition attachment header if filename isn't null
+            String file = handler.getName();
+            File f = new File(file);
+            if (f.exists() && f.isFile()) {
+                file = f.getName();
+            }
+            att.setHeader("Content-Disposition", "attachment;name=\"" + file + "\"");
+        }
+        att.setXOP(isXop);
+        return att;
+    }
+
+    public static DataSource getAttachmentDataSource(String contentId, Collection<Attachment> atts) {
+        // Is this right? - DD
+        if (contentId.startsWith("cid:")) {
+            try {
+                contentId = URLDecoder.decode(contentId.substring(4), StandardCharsets.UTF_8.name());
+            } catch (UnsupportedEncodingException ue) {
+                contentId = contentId.substring(4);
+            }
+            return loadDataSource(contentId, atts);
+        } else if (contentId.indexOf("://") == -1) {
+            return loadDataSource(contentId, atts);
+        } else {
+            try {
+                return new URLDataSource(new URL(contentId));
+            } catch (MalformedURLException e) {
+                throw new Fault(e);
+            }
+        }
+
+    }
+
+    private static DataSource loadDataSource(String contentId, Collection<Attachment> atts) {
+        return new LazyDataSource(contentId, atts);
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/attachment/Base64DecoderStream.java b/transform/src/patch/java/org/apache/cxf/attachment/Base64DecoderStream.java
new file mode 100644
index 0000000..134553f
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/attachment/Base64DecoderStream.java
@@ -0,0 +1,196 @@
+/**
+ * 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.cxf.attachment;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64Utility;
+
+/**
+ * An implementation of a FilterInputStream that decodes the
+ * stream data in BASE64 encoding format.  This version does the
+ * decoding "on the fly" rather than decoding a single block of
+ * data.  Since this version is intended for use by the MimeUtilty class,
+ * it also handles line breaks in the encoded data.
+ */
+public class Base64DecoderStream extends FilterInputStream {
+
+    static final String MAIL_BASE64_IGNOREERRORS = "mail.mime.base64.ignoreerrors";
+
+    // number of decodeable units we'll try to process at one time.  We'll attempt to read that much
+    // data from the input stream and decode in blocks.
+    static final int BUFFERED_UNITS = 2000;
+
+    // can be overridden by a system property.
+    protected boolean ignoreErrors;
+
+    // buffer for reading in chars for decoding (which can support larger bulk reads)
+    protected char[] encodedChars = new char[BUFFERED_UNITS * 4];
+    // a buffer for one decoding unit's worth of data (3 bytes).
+    protected byte[] decodedChars;
+    // count of characters in the buffer
+    protected int decodedCount;
+    // index of the next decoded character
+    protected int decodedIndex;
+
+
+    public Base64DecoderStream(InputStream in) {
+        super(in);
+    }
+
+    /**
+     * Test for the existance of decoded characters in our buffer
+     * of decoded data.
+     *
+     * @return True if we currently have buffered characters.
+     */
+    private boolean dataAvailable() {
+        return decodedCount != 0;
+    }
+
+    /**
+     * Decode a requested number of bytes of data into a buffer.
+     *
+     * @return true if we were able to obtain more data, false otherwise.
+     */
+    private boolean decodeStreamData() throws IOException {
+        decodedIndex = 0;
+
+        // fill up a data buffer with input data
+        int readCharacters = fillEncodedBuffer();
+
+        if (readCharacters > 0) {
+            try {
+                decodedChars = Base64Utility.decodeChunk(encodedChars, 0, readCharacters);
+            } catch (Base64Exception e) {
+                throw new IOException(e);
+            }
+            decodedCount = decodedChars.length;
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Retrieve a single byte from the decoded characters buffer.
+     *
+     * @return The decoded character or -1 if there was an EOF condition.
+     */
+    private int getByte() throws IOException {
+        if (!dataAvailable() && !decodeStreamData()) {
+            return -1;
+        }
+        decodedCount--;
+        // we need to ensure this doesn't get sign extended
+        return decodedChars[decodedIndex++] & 0xff;
+    }
+
+    private int getBytes(byte[] data, int offset, int length) throws IOException {
+
+        int readCharacters = 0;
+        while (length > 0) {
+            // need data?  Try to get some
+            if (!dataAvailable() && !decodeStreamData()) {
+                // if we can't get this, return a count of how much we did get (which may be -1).
+                return readCharacters > 0 ? readCharacters : -1;
+            }
+
+            // now copy some of the data from the decoded buffer to the target buffer
+            int copyCount = Math.min(decodedCount, length);
+            System.arraycopy(decodedChars, decodedIndex, data, offset, copyCount);
+            decodedIndex += copyCount;
+            decodedCount -= copyCount;
+            offset += copyCount;
+            length -= copyCount;
+            readCharacters += copyCount;
+        }
+        return readCharacters;
+    }
+
+
+    /**
+     * Fill our buffer of input characters for decoding from the
+     * stream.  This will attempt read a full buffer, but will
+     * terminate on an EOF or read error.  This will filter out
+     * non-Base64 encoding chars and will only return a valid
+     * multiple of 4 number of bytes.
+     *
+     * @return The count of characters read.
+     */
+    private int fillEncodedBuffer() throws IOException {
+        int readCharacters = 0;
+
+        while (true) {
+            // get the next character from the stream
+            int ch = in.read();
+            // did we hit an EOF condition?
+            if (ch == -1) {
+                // now check to see if this is normal, or potentially an error
+                // if we didn't get characters as a multiple of 4, we may need to complain about this.
+                if ((readCharacters % 4) != 0) {
+                    throw new IOException("Base64 encoding error, data truncated: " + readCharacters + " "
+                                          + new String(encodedChars, 0, readCharacters));
+                }
+                // return the count.
+                return readCharacters;
+            } else if (Base64Utility.isValidBase64(ch)) {
+                // if this character is valid in a Base64 stream, copy it to the buffer.
+                encodedChars[readCharacters++] = (char)ch;
+                // if we've filled up the buffer, time to quit.
+                if (readCharacters >= encodedChars.length) {
+                    return readCharacters;
+                }
+            }
+
+            // we're filtering out whitespace and CRLF characters, so just ignore these
+        }
+    }
+
+
+    // in order to function as a filter, these streams need to override the different
+    // read() signature.
+
+    @Override
+    public int read() throws IOException {
+        return getByte();
+    }
+
+
+    @Override
+    public int read(byte [] buffer, int offset, int length) throws IOException {
+        return getBytes(buffer, offset, length);
+    }
+
+    
+    @Override
+    public boolean markSupported() {
+        return false;
+    }
+
+
+    @Override
+    public int available() throws IOException {
+        return ((in.available() / 4) * 3) + decodedCount;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/attachment/ContentDisposition.java b/transform/src/patch/java/org/apache/cxf/attachment/ContentDisposition.java
new file mode 100644
index 0000000..f9d4524
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/attachment/ContentDisposition.java
@@ -0,0 +1,144 @@
+/**
+ * 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.cxf.attachment;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ContentDisposition {
+    private static final String CD_HEADER_PARAMS_EXPRESSION =
+       "[\\w-]++( )?\\*?=( )?((\"[^\"]++\")|([^;]+))";
+    private static final Pattern CD_HEADER_PARAMS_PATTERN =
+            Pattern.compile(CD_HEADER_PARAMS_EXPRESSION);
+
+    private static final String CD_HEADER_EXT_PARAMS_EXPRESSION =
+            "(?i)(UTF-8|ISO-8859-1)''((?:%[0-9a-f]{2}|\\S)+)";
+    private static final Pattern CD_HEADER_EXT_PARAMS_PATTERN =
+            Pattern.compile(CD_HEADER_EXT_PARAMS_EXPRESSION);
+    private static final Pattern CODEPOINT_ENCODED_VALUE_PATTERN = Pattern.compile("&#[0-9]{4};|\\S");
+    
+    private static final String FILE_NAME = "filename";
+
+    private String value;
+    private String type;
+    private Map<String, String> params = new LinkedHashMap<>();
+
+    public ContentDisposition(String value) {
+        this.value = value;
+
+        String tempValue = value;
+
+        int index = tempValue.indexOf(';');
+        if (index > 0 && (tempValue.indexOf('=') >= index)) {
+            type = tempValue.substring(0, index).trim();
+            tempValue = tempValue.substring(index + 1);
+        }
+
+        String extendedFilename = null;
+        Matcher m = CD_HEADER_PARAMS_PATTERN.matcher(tempValue);
+        while (m.find()) {
+            final String paramName;
+            String paramValue = "";
+
+            String groupValue = m.group().trim();
+            int eqIndex = groupValue.indexOf('=');
+            if (eqIndex > 0) {
+                paramName = groupValue.substring(0, eqIndex).trim();
+                if (eqIndex + 1 != groupValue.length()) {
+                    paramValue = groupValue.substring(eqIndex + 1).trim().replace("\"", "");
+                }
+            } else {
+                paramName = groupValue;
+            }
+            // filename* looks like the only CD param that is human readable
+            // and worthy of the extended encoding support. Other parameters
+            // can be supported if needed, see the complete list below
+            /*
+                http://www.iana.org/assignments/cont-disp/cont-disp.xhtml#cont-disp-2
+
+                filename            name to be used when creating file [RFC2183]
+                creation-date       date when content was created [RFC2183]
+                modification-date   date when content was last modified [RFC2183]
+                read-date           date when content was last read [RFC2183]
+                size                approximate size of content in octets [RFC2183]
+                name                original field name in form [RFC2388]
+                voice               type or use of audio content [RFC2421]
+                handling            whether or not processing is required [RFC3204]
+             */
+            if ("filename*".equalsIgnoreCase(paramName)) {
+                // try to decode the value if it matches the spec
+                try {
+                    Matcher matcher = CD_HEADER_EXT_PARAMS_PATTERN.matcher(paramValue);
+                    if (matcher.matches()) {
+                        String encodingScheme = matcher.group(1);
+                        String encodedValue = matcher.group(2);
+                        paramValue = Rfc5987Util.decode(encodedValue, encodingScheme);
+                        extendedFilename = paramValue;
+                    }
+                } catch (UnsupportedEncodingException e) {
+                    // would be odd not to support UTF-8 or 8859-1
+                }
+            } else if (FILE_NAME.equalsIgnoreCase(paramName) && paramValue.contains("&#")) {
+                Matcher matcher = CODEPOINT_ENCODED_VALUE_PATTERN.matcher(paramValue);
+                StringBuilder sb = new StringBuilder();
+                while (matcher.find()) {
+                    String matched = matcher.group();
+                    if (matched.startsWith("&#")) {
+                        int codePoint = Integer.parseInt(matched.substring(2, 6));
+                        sb.append(Character.toChars(codePoint));
+                    } else {
+                        sb.append(matched.charAt(0));
+                    }
+                }
+                if (sb.length() > 0) {
+                    paramValue = sb.toString();
+                }
+            }
+            params.put(paramName.toLowerCase(), paramValue);
+        }
+        if (extendedFilename != null) {
+            params.put(FILE_NAME, extendedFilename);
+        }
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getFilename() {
+        return params.get(FILE_NAME);
+    }
+
+    public String getParameter(String name) {
+        return params.get(name);
+    }
+
+    public Map<String, String> getParameters() {
+        return Collections.unmodifiableMap(params);
+    }
+
+    public String toString() {
+        return value;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/attachment/LazyAttachmentCollection.java b/transform/src/patch/java/org/apache/cxf/attachment/LazyAttachmentCollection.java
new file mode 100644
index 0000000..8dd4ace
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/attachment/LazyAttachmentCollection.java
@@ -0,0 +1,362 @@
+/**
+ * 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.cxf.attachment;
+
+import java.io.IOException;
+import java.util.AbstractCollection;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.activation.DataHandler;
+
+import org.apache.cxf.message.Attachment;
+
+public class LazyAttachmentCollection
+    implements Collection<Attachment> {
+
+    private AttachmentDeserializer deserializer;
+    private final List<Attachment> attachments = new ArrayList<>();
+    private final int maxAttachmentCount;
+
+    public LazyAttachmentCollection(AttachmentDeserializer deserializer, int maxAttachmentCount) {
+        super();
+        this.deserializer = deserializer;
+        this.maxAttachmentCount = maxAttachmentCount;
+    }
+
+    public List<Attachment> getLoadedAttachments() {
+        return attachments;
+    }
+
+    private void loadAll() {
+        try {
+            Attachment a = deserializer.readNext();
+            int count = 0;
+            while (a != null) {
+                attachments.add(a);
+                count++;
+                if (count > maxAttachmentCount) {
+                    throw new IOException("The message contains more attachments than are permitted");
+                }
+                a = deserializer.readNext();
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+    /**
+     * Check for more attachments by attempting to deserialize the next attachment.
+     *
+     * @param shouldLoadNew if <i>false</i>, the "loaded attachments" List will not be changed.
+     * @return there is more attachment or not
+     * @throws IOException
+     */
+    public boolean hasNext(boolean shouldLoadNew) throws IOException {
+        if (shouldLoadNew) {
+            Attachment a = deserializer.readNext();
+            if (a != null) {
+                attachments.add(a);
+                return true;
+            }
+            return false;
+        }
+        return deserializer.hasNext();
+    }
+
+    public boolean hasNext() throws IOException {
+        return hasNext(true);
+    }
+    public Iterator<Attachment> iterator() {
+        return new Iterator<Attachment>() {
+            int current;
+            boolean removed;
+
+            public boolean hasNext() {
+                if (attachments.size() > current) {
+                    return true;
+                }
+
+                // check if there is another attachment
+                try {
+                    Attachment a = deserializer.readNext();
+                    if (a == null) {
+                        return false;
+                    }
+                    attachments.add(a);
+                    return true;
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+
+            @Override
+            public Attachment next() {
+                Attachment a = attachments.get(current);
+                current++;
+                removed = false;
+                return a;
+            }
+
+            @Override
+            public void remove() {
+                if (removed) {
+                    throw new IllegalStateException();
+                }
+                attachments.remove(--current);
+                removed = true;
+            }
+
+        };
+    }
+
+    public int size() {
+        loadAll();
+
+        return attachments.size();
+    }
+
+    public boolean add(Attachment arg0) {
+        return attachments.add(arg0);
+    }
+
+    public boolean addAll(Collection<? extends Attachment> arg0) {
+        return attachments.addAll(arg0);
+    }
+
+    public void clear() {
+        attachments.clear();
+    }
+
+    public boolean contains(Object arg0) {
+        return attachments.contains(arg0);
+    }
+
+    public boolean containsAll(Collection<?> arg0) {
+        return attachments.containsAll(arg0);
+    }
+
+    public boolean isEmpty() {
+        if (attachments.isEmpty()) {
+            return !iterator().hasNext();
+        }
+        return attachments.isEmpty();
+    }
+
+    public boolean remove(Object arg0) {
+        return attachments.remove(arg0);
+    }
+
+    public boolean removeAll(Collection<?> arg0) {
+        return attachments.removeAll(arg0);
+    }
+
+    public boolean retainAll(Collection<?> arg0) {
+        return attachments.retainAll(arg0);
+    }
+
+    public Object[] toArray() {
+        loadAll();
+
+        return attachments.toArray();
+    }
+
+    public <T> T[] toArray(T[] arg0) {
+        loadAll();
+
+        return attachments.toArray(arg0);
+    }
+
+    public Map<String, DataHandler> createDataHandlerMap() {
+        return new LazyAttachmentMap(this);
+    }
+
+    private static class LazyAttachmentMap implements Map<String, DataHandler> {
+        LazyAttachmentCollection collection;
+
+        LazyAttachmentMap(LazyAttachmentCollection c) {
+            collection = c;
+        }
+
+        public void clear() {
+            collection.clear();
+        }
+
+        public boolean containsKey(Object key) {
+            Iterator<Attachment> it = collection.iterator();
+            while (it.hasNext()) {
+                Attachment at = it.next();
+                if (key.equals(at.getId())) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public boolean containsValue(Object value) {
+            Iterator<Attachment> it = collection.iterator();
+            while (it.hasNext()) {
+                Attachment at = it.next();
+                if (value.equals(at.getDataHandler())) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public DataHandler get(Object key) {
+            Iterator<Attachment> it = collection.iterator();
+            while (it.hasNext()) {
+                Attachment at = it.next();
+                if (key.equals(at.getId())) {
+                    return at.getDataHandler();
+                }
+            }
+            return null;
+        }
+
+        public boolean isEmpty() {
+            return collection.isEmpty();
+        }
+        public int size() {
+            return collection.size();
+        }
+
+        public DataHandler remove(Object key) {
+            Iterator<Attachment> it = collection.iterator();
+            while (it.hasNext()) {
+                Attachment at = it.next();
+                if (key.equals(at.getId())) {
+                    collection.remove(at);
+                    return at.getDataHandler();
+                }
+            }
+            return null;
+        }
+        public DataHandler put(String key, DataHandler value) {
+            Attachment at = new AttachmentImpl(key, value);
+            collection.add(at);
+            return value;
+        }
+
+        public void putAll(Map<? extends String, ? extends DataHandler> t) {
+            for (Map.Entry<? extends String, ? extends DataHandler> ent : t.entrySet()) {
+                put(ent.getKey(), ent.getValue());
+            }
+        }
+
+
+        public Set<Map.Entry<String, DataHandler>> entrySet() {
+            return new AbstractSet<Map.Entry<String, DataHandler>>() {
+                public Iterator<Map.Entry<String, DataHandler>> iterator() {
+                    return new Iterator<Map.Entry<String, DataHandler>>() {
+                        Iterator<Attachment> it = collection.iterator();
+                        public boolean hasNext() {
+                            return it.hasNext();
+                        }
+                        public Map.Entry<String, DataHandler> next() {
+                            return new Map.Entry<String, DataHandler>() {
+                                Attachment at = it.next();
+                                public String getKey() {
+                                    return at.getId();
+                                }
+                                public DataHandler getValue() {
+                                    return at.getDataHandler();
+                                }
+                                public DataHandler setValue(DataHandler value) {
+                                    if (at instanceof AttachmentImpl) {
+                                        DataHandler h = at.getDataHandler();
+                                        ((AttachmentImpl)at).setDataHandler(value);
+                                        return h;
+                                    }
+                                    throw new UnsupportedOperationException();
+                                }
+                            };
+                        }
+                        @Override
+                        public void remove() {
+                            it.remove();
+                        }
+                    };
+                }
+                public int size() {
+                    return collection.size();
+                }
+            };
+        }
+
+        public Set<String> keySet() {
+            return new AbstractSet<String>() {
+                public Iterator<String> iterator() {
+                    return new Iterator<String>() {
+                        Iterator<Attachment> it = collection.iterator();
+                        public boolean hasNext() {
+                            return it.hasNext();
+                        }
+
+                        public String next() {
+                            return it.next().getId();
+                        }
+
+                        @Override
+                        public void remove() {
+                            it.remove();
+                        }
+                    };
+                }
+
+                public int size() {
+                    return collection.size();
+                }
+            };
+        }
+
+
+        public Collection<DataHandler> values() {
+            return new AbstractCollection<DataHandler>() {
+                public Iterator<DataHandler> iterator() {
+                    return new Iterator<DataHandler>() {
+                        Iterator<Attachment> it = collection.iterator();
+                        public boolean hasNext() {
+                            return it.hasNext();
+                        }
+                        public DataHandler next() {
+                            return it.next().getDataHandler();
+                        }
+                        @Override
+                        public void remove() {
+                            it.remove();
+                        }
+                    };
+                }
+
+                public int size() {
+                    return collection.size();
+                }
+            };
+        }
+
+    }
+
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/attachment/MimeBodyPartInputStream.java b/transform/src/patch/java/org/apache/cxf/attachment/MimeBodyPartInputStream.java
new file mode 100644
index 0000000..ab80b89
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/attachment/MimeBodyPartInputStream.java
@@ -0,0 +1,275 @@
+/**
+ * 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.cxf.attachment;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+
+public class MimeBodyPartInputStream extends InputStream {
+
+    PushbackInputStream inStream;
+
+    boolean boundaryFound;
+    int pbAmount;
+    byte[] boundary;
+    byte[] boundaryBuffer;
+
+    private boolean closed;
+
+    public MimeBodyPartInputStream(PushbackInputStream inStreamParam,
+                                   byte[] boundaryParam,
+                                   int pbsize) {
+        super();
+        this.inStream = inStreamParam;
+        this.boundary = boundaryParam;
+        this.pbAmount = pbsize;
+    }
+
+    @Override
+    public int read(byte[] buf, int origOff, int origLen) throws IOException {
+        byte[] b = buf;
+        int off = origOff;
+        int len = origLen;
+        if (boundaryFound || closed) {
+            return -1;
+        }
+        if ((off < 0) || (off > b.length) || (len < 0)
+            || ((off + len) > b.length) || ((off + len) < 0)) {
+
+            throw new IndexOutOfBoundsException();
+        }
+        if (len == 0) {
+            return 0;
+        }
+        boolean bufferCreated = false;
+        if (len < boundary.length * 2) {
+            //buffer is too short to detect boundaries with it.  We'll need to create a larger buffer
+            bufferCreated = true;
+            if (boundaryBuffer == null) {
+                boundaryBuffer = new byte[boundary.length * 2];
+            }
+            b = boundaryBuffer;
+            off = 0;
+            len = boundaryBuffer.length;
+        }
+        if (len > pbAmount) {
+            len = pbAmount;  //can only pushback that much so make sure we can
+        }
+        int read = 0;
+        int idx = 0;
+        while (read >= 0 && idx < len && idx < (boundary.length * 2)) {
+            //make sure we read enough to detect the boundary
+            read = inStream.read(b, off + idx, len - idx);
+            if (read != -1) {
+                idx += read;
+            }
+        }
+        if (read == -1 && idx == 0) {
+            return -1;
+        }
+        len = idx;
+
+        int i = processBuffer(b, off, len);
+        if (bufferCreated && i > 0) {
+            // read more than we need, push it back
+            if (origLen >= i) {
+                System.arraycopy(b, 0, buf, origOff, i);
+            } else {
+                System.arraycopy(b, 0, buf, origOff, origLen);
+                inStream.unread(b, origLen, i - origLen);
+                i = origLen;
+            }
+        } else if (i == 0 && boundaryFound) {
+            return -1;
+        }
+
+        return i;
+    }
+
+    //Has Data after encountering CRLF
+    private boolean hasData(byte[] b, int initialPointer, int pointer, int off, int len)
+        throws IOException {
+        if (pointer < (off + len)) {
+            return true;
+        } else if (pointer >= 1000000000) {
+            inStream.unread(b, initialPointer, (off + len) - initialPointer);
+            return false;
+        } else {
+            int x = inStream.read();
+            if (x != -1) {
+                inStream.unread(x);
+                inStream.unread(b, initialPointer, (off + len) - initialPointer);
+                return false;
+            }
+            return true;
+        }
+    }
+
+    protected int processBuffer(byte[] buffer, int off, int len) throws IOException {
+        for (int i = off; i < (off + len); i++) {
+            boolean needUnread0d0a = false;
+            int value = buffer[i];
+            int initialI = i;
+            if (value == 13) {
+                if (!hasData(buffer, initialI, initialI + 1, off, len)) {
+                    return initialI - off;
+                }
+                value = buffer[initialI + 1];
+                if (value != 10) {
+                    continue;
+                }
+                if (!hasData(buffer, initialI, initialI + 2, off, len)) {
+                    return initialI - off;
+                }
+                value = buffer[initialI + 2];
+                if ((byte) value != boundary[0]) {
+                    i++;
+                    continue;
+                }
+                needUnread0d0a = true;
+                i += 2; //i after this points to boundary[0] element
+            } else if (value != boundary[0]) {
+                continue;
+            }
+
+            int boundaryIndex = 0;
+            while ((boundaryIndex < boundary.length) && (value == boundary[boundaryIndex])) {
+                if (!hasData(buffer, initialI, i + 1, off, len)) {
+                    return initialI - off;
+                }
+                value = buffer[++i];
+                boundaryIndex++;
+            }
+            if (boundaryIndex == boundary.length) {
+                // read the end of line character
+                if (initialI != off) {
+                    i = 1000000000;
+                }
+                if (initialI - off != 0
+                    && !hasData(buffer, initialI, i + 1, off, len)) {
+                    return initialI - off;
+                }
+                boundaryFound = true;
+                int j = i + 1;
+                if (j < len && buffer[j] == 45 && value == 45) {
+                    // Last mime boundary should have a succeeding "--"
+                    // as we are on it, read the terminating CRLF
+                    i += 2;
+                    //last mime boundary
+                }
+
+                //boundary matched (may or may not be last mime boundary)
+                int processed = initialI - off;
+                if ((len - ((i - off) + 2)) > 0) {
+                    inStream.unread(buffer, i + 2, len - (i + 2) + off);
+                }
+                return processed;
+            }
+
+            // Boundary not found. Restoring bytes skipped.
+            // write first skipped byte, push back the rest
+            if (value != -1) { //pushing back first byte of boundary
+                // Stream might have ended
+                i--;
+            }
+            if (needUnread0d0a) { //Pushing all,  returning 13
+                i = i - boundaryIndex;
+                i--; //for 10
+//                value = 13;
+            } else {
+                i = i - boundaryIndex;
+                i++;
+//                value = boundary[0];
+            }
+        }
+        return len;
+    }
+
+    public int read() throws IOException {
+        boolean needUnread0d0a = false;
+        if (boundaryFound) {
+            return -1;
+        }
+
+        // read the next value from stream
+        int value = inStream.read();
+        // A problem occurred because all the mime parts tends to have a /r/n
+        // at the end. Making it hard to transform them to correct
+        // DataSources.
+        // This logic introduced to handle it
+        if (value == 13) {
+            value = inStream.read();
+            if (value != 10) {
+                inStream.unread(value);
+                return 13;
+            }
+            value = inStream.read();
+            if ((byte) value != boundary[0]) {
+                inStream.unread(value);
+                inStream.unread(10);
+                return 13;
+            }
+            needUnread0d0a = true;
+        } else if ((byte) value != boundary[0]) {
+            return value;
+        }
+        // read value is the first byte of the boundary. Start matching the
+        // next characters to find a boundary
+        int boundaryIndex = 0;
+        while ((boundaryIndex < boundary.length) && ((byte) value == boundary[boundaryIndex])) {
+            value = inStream.read();
+            boundaryIndex++;
+        }
+        if (boundaryIndex == boundary.length) {
+            // boundary found
+            boundaryFound = true;
+            int dashNext = inStream.read();
+            // read the end of line character
+            if (dashNext == 45 && value == 45) {
+                // Last mime boundary should have a succeeding "--"
+                // as we are on it, read the terminating CRLF
+                inStream.read();
+                inStream.read();
+            }
+            return -1;
+        }
+        // Boundary not found. Restoring bytes skipped.
+        // write first skipped byte, push back the rest
+        if (value != -1) {
+            // Stream might have ended
+            inStream.unread(value);
+        }
+        if (needUnread0d0a) {
+            inStream.unread(boundary, 0, boundaryIndex);
+            inStream.unread(10);
+            value = 13;
+        } else {
+            inStream.unread(boundary, 1, boundaryIndex - 1);
+            value = boundary[0];
+        }
+        return value;
+    }
+
+    @Override
+    public void close() throws IOException {
+        this.closed = true;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/CXFBusFactory.java b/transform/src/patch/java/org/apache/cxf/bus/CXFBusFactory.java
new file mode 100644
index 0000000..fb3a833
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/CXFBusFactory.java
@@ -0,0 +1,47 @@
+/**
+ * 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.cxf.bus;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
+
+public class CXFBusFactory extends BusFactory {
+
+    public Bus createBus() {
+        return createBus(new HashMap<>());
+    }
+
+    public Bus createBus(Map<Class<?>, Object> e) {
+        return createBus(e, new HashMap<>());
+    }
+
+    public Bus createBus(Map<Class<?>, Object> e, Map<String, Object> properties) {
+        ExtensionManagerBus bus = new ExtensionManagerBus(e, properties);
+        possiblySetDefaultBus(bus);
+        initializeBus(bus);
+        bus.initialize();
+        return bus;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/blueprint/BundleDelegatingClassLoader.java b/transform/src/patch/java/org/apache/cxf/bus/blueprint/BundleDelegatingClassLoader.java
new file mode 100644
index 0000000..ff957c2
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/blueprint/BundleDelegatingClassLoader.java
@@ -0,0 +1,134 @@
+/**
+ * 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.cxf.bus.blueprint;
+
+import java.io.IOException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * A ClassLoader delegating to a given OSGi bundle.
+ */
+public class BundleDelegatingClassLoader extends ClassLoader {
+
+    private final Bundle bundle;
+    private final ClassLoader classLoader;
+
+    public BundleDelegatingClassLoader(Bundle bundle) {
+        this(bundle, null);
+    }
+
+    public BundleDelegatingClassLoader(Bundle bundle, ClassLoader classLoader) {
+        this.bundle = bundle;
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    protected Class<?> findClass(final String name) throws ClassNotFoundException {
+        try {
+            return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
+                public Class<?> run() throws ClassNotFoundException {
+                    return bundle.loadClass(name);
+                }
+            });
+        } catch (PrivilegedActionException e) {
+            Exception cause = e.getException();
+
+            if (cause instanceof ClassNotFoundException) {
+                throw (ClassNotFoundException)cause;
+            }
+            throw (RuntimeException)cause;
+        }
+    }
+
+    @Override
+    protected URL findResource(final String name) {
+        URL resource = AccessController.doPrivileged(new PrivilegedAction<URL>() {
+            public URL run() {
+                return bundle.getResource(name);
+            }
+        });
+        if (classLoader != null && resource == null) {
+            resource = classLoader.getResource(name);
+        }
+        return resource;
+    }
+
+    @Override
+    protected Enumeration<URL> findResources(final String name) throws IOException {
+        Enumeration<URL> urls;
+        try {
+            urls = AccessController.doPrivileged(new PrivilegedExceptionAction<Enumeration<URL>>() {
+                public Enumeration<URL> run() throws IOException {
+                    return bundle.getResources(name);
+                }
+
+            });
+        } catch (PrivilegedActionException e) {
+            Exception cause = e.getException();
+
+            if (cause instanceof IOException) {
+                throw (IOException)cause;
+            }
+            throw (RuntimeException)cause;
+        }
+
+        if (urls == null) {
+            urls = Collections.enumeration(new ArrayList<>());
+        }
+
+        return urls;
+    }
+
+    @Override
+    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+        Class<?> clazz;
+        try {
+            clazz = findClass(name);
+        } catch (ClassNotFoundException cnfe) {
+            if (classLoader != null) {
+                try {
+                    clazz = classLoader.loadClass(name);
+                } catch (ClassNotFoundException e) {
+                    throw new ClassNotFoundException(name + " from bundle " + bundle.getBundleId()
+                                                     + " (" + bundle.getSymbolicName() + ")", cnfe);
+                }
+            } else {
+                throw new ClassNotFoundException(name + " from bundle " + bundle.getBundleId()
+                                                 + " (" + bundle.getSymbolicName() + ")", cnfe);
+            }
+        }
+        if (resolve) {
+            resolveClass(clazz);
+        }
+        return clazz;
+    }
+
+    public Bundle getBundle() {
+        return bundle;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/blueprint/BusDefinitionParser.java b/transform/src/patch/java/org/apache/cxf/bus/blueprint/BusDefinitionParser.java
new file mode 100644
index 0000000..baf83b7
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/blueprint/BusDefinitionParser.java
@@ -0,0 +1,72 @@
+/**
+ * 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.cxf.bus.blueprint;
+
+
+import org.w3c.dom.Element;
+
+import org.apache.aries.blueprint.ParserContext;
+import org.apache.aries.blueprint.mutable.MutableBeanMetadata;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.configuration.blueprint.AbstractBPBeanDefinitionParser;
+import org.osgi.service.blueprint.reflect.Metadata;
+
+public class BusDefinitionParser
+    extends AbstractBPBeanDefinitionParser {
+
+    public BusDefinitionParser() {
+    }
+
+    public Metadata parse(Element element, ParserContext context) {
+        String bname = element.hasAttribute("bus") ? element.getAttribute("bus") : "cxf";
+        String id = element.hasAttribute("id") ? element.getAttribute("id") : null;
+        MutableBeanMetadata cxfBean = getBus(context, bname);
+        parseAttributes(element, context, cxfBean);
+        parseChildElements(element, context, cxfBean);
+        context.getComponentDefinitionRegistry().removeComponentDefinition(bname);
+        if (!StringUtils.isEmpty(id)) {
+            cxfBean.addProperty("id", createValue(context, id));
+        }
+        return cxfBean;
+    }
+    
+    @Override
+    protected void processBusAttribute(Element element, ParserContext ctx,
+                                       MutableBeanMetadata bean, String val) {
+        //nothing
+    }
+    
+    @Override
+    protected boolean hasBusProperty() {
+        return false;
+    }
+
+
+    @Override
+    protected void mapElement(ParserContext ctx, MutableBeanMetadata bean, Element el, String name) {
+        if ("inInterceptors".equals(name) || "inFaultInterceptors".equals(name)
+            || "outInterceptors".equals(name) || "outFaultInterceptors".equals(name)
+            || "features".equals(name)) {
+            bean.addProperty(name, parseListData(ctx, bean, el));
+        } else if ("properties".equals(name)) {
+            bean.addProperty(name, parseMapData(ctx, bean, el));
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/blueprint/ConfigurerImpl.java b/transform/src/patch/java/org/apache/cxf/bus/blueprint/ConfigurerImpl.java
new file mode 100644
index 0000000..37f82fe
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/blueprint/ConfigurerImpl.java
@@ -0,0 +1,180 @@
+/**
+ * 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.cxf.bus.blueprint;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.configuration.Configurable;
+import org.apache.cxf.configuration.Configurer;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.osgi.service.blueprint.container.NoSuchComponentException;
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+
+/**
+ *
+ */
+public class ConfigurerImpl implements Configurer {
+    private static final Logger LOG = LogUtils.getL7dLogger(ConfigurerImpl.class);
+    BlueprintContainer container;
+
+    private final Map<String, List<MatcherHolder>> wildCardBeanDefinitions
+        = new TreeMap<>();
+
+    static class MatcherHolder implements Comparable<MatcherHolder> {
+        Matcher matcher;
+        String wildCardId;
+        MatcherHolder(String orig, Matcher matcher) {
+            wildCardId = orig;
+            this.matcher = matcher;
+        }
+        @Override
+        public int compareTo(MatcherHolder mh) {
+            int literalCharsLen1 = this.wildCardId.replace("*", "").length();
+            int literalCharsLen2 = mh.wildCardId.replace("*", "").length();
+            // The expression with more literal characters should end up on the top of the list
+            return Integer.compare(literalCharsLen1, literalCharsLen2) * -1;
+        }
+    }
+
+    public ConfigurerImpl(BlueprintContainer con) {
+        container = con;
+        initializeWildcardMap();
+    }
+    private boolean isWildcardBeanName(String bn) {
+        return bn.indexOf('*') != -1 || bn.indexOf('?') != -1
+            || (bn.indexOf('(') != -1 && bn.indexOf(')') != -1);
+    }
+
+    private void initializeWildcardMap() {
+        for (String s : container.getComponentIds()) {
+            if (isWildcardBeanName(s)) {
+                ComponentMetadata cmd = container.getComponentMetadata(s);
+                Class<?> cls = BlueprintBeanLocator.getClassForMetaData(container, cmd);
+                if (cls != null) {
+                    final String cid = s.charAt(0) != '*' ? s
+                            : "." + s.replaceAll("\\.", "\\."); //old wildcard
+                    Matcher matcher = Pattern.compile(cid).matcher("");
+                    List<MatcherHolder> m = wildCardBeanDefinitions.get(cls.getName());
+                    if (m == null) {
+                        m = new ArrayList<>();
+                        wildCardBeanDefinitions.put(cls.getName(), m);
+                    }
+                    MatcherHolder holder = new MatcherHolder(s, matcher);
+                    m.add(holder);
+                }
+            }
+        }
+    }
+
+    public void configureBean(Object beanInstance) {
+        configureBean(null, beanInstance, true);
+    }
+
+    public void configureBean(String bn, Object beanInstance) {
+        configureBean(bn, beanInstance, true);
+    }
+    public synchronized void configureBean(String bn, Object beanInstance, boolean checkWildcards) {
+        if (null == bn) {
+            bn = getBeanName(beanInstance);
+        }
+
+        if (null == bn) {
+            return;
+        }
+        if (checkWildcards) {
+            configureWithWildCard(bn, beanInstance);
+        }
+
+        if (container instanceof ExtendedBlueprintContainer) {
+            try {
+                final ComponentMetadata cm = container.getComponentMetadata(bn);
+                if (cm instanceof BeanMetadata) {
+                    ((ExtendedBlueprintContainer)container).injectBeanInstance((BeanMetadata)cm, beanInstance);
+                }
+            } catch (NoSuchComponentException nsce) {
+            }
+        }
+    }
+
+    private void configureWithWildCard(String bn, Object beanInstance) {
+        if (!wildCardBeanDefinitions.isEmpty()) {
+            Class<?> clazz = beanInstance.getClass();
+            while (!Object.class.equals(clazz)) {
+                String className = clazz.getName();
+                List<MatcherHolder> matchers = wildCardBeanDefinitions.get(className);
+                if (matchers != null) {
+                    for (MatcherHolder m : matchers) {
+                        synchronized (m.matcher) {
+                            m.matcher.reset(bn);
+                            if (m.matcher.matches()) {
+                                configureBean(m.wildCardId, beanInstance, false);
+                                return;
+                            }
+                        }
+                    }
+                }
+                clazz = clazz.getSuperclass();
+            }
+        }
+    }
+
+    protected String getBeanName(Object beanInstance) {
+        if (beanInstance instanceof Configurable) {
+            return ((Configurable)beanInstance).getBeanName();
+        }
+        String beanName = null;
+        Method m = null;
+        try {
+            m = beanInstance.getClass().getDeclaredMethod("getBeanName", (Class[])null);
+        } catch (NoSuchMethodException ex) {
+            try {
+                m = beanInstance.getClass().getMethod("getBeanName", (Class[])null);
+            } catch (NoSuchMethodException e) {
+                //ignore
+            }
+        }
+        if (m != null) {
+            try {
+                beanName = (String)(m.invoke(beanInstance));
+            } catch (Exception ex) {
+                LogUtils.log(LOG, Level.WARNING, "ERROR_DETERMINING_BEAN_NAME_EXC", ex);
+            }
+        }
+
+        if (null == beanName) {
+            LogUtils.log(LOG, Level.FINE, "COULD_NOT_DETERMINE_BEAN_NAME_MSG",
+                         beanInstance.getClass().getName());
+        }
+
+        return beanName;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/extension/Extension.java b/transform/src/patch/java/org/apache/cxf/bus/extension/Extension.java
new file mode 100644
index 0000000..03f0dc6
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/extension/Extension.java
@@ -0,0 +1,291 @@
+/**
+ * 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.cxf.bus.extension;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.StringUtils;
+
+public class Extension {
+    protected static final Logger LOG = LogUtils.getL7dLogger(Extension.class);
+    
+    private static final String PROBLEM_CREATING_EXTENSION_CLASS = "PROBLEM_CREATING_EXTENSION_CLASS";
+
+    protected String className;
+    protected ClassLoader classloader;
+    protected volatile Class<?> clazz;
+    protected volatile Class<?> intf;
+    protected String interfaceName;
+    protected boolean deferred;
+    protected Collection<String> namespaces = new ArrayList<>();
+    protected Object[] args;
+    protected volatile Object obj;
+    protected boolean optional;
+    protected boolean notFound;
+    
+
+    public Extension() {
+    }
+
+    public Extension(Class<?> cls, Class<?> inf) {
+        clazz = cls;
+        intf = inf;
+        interfaceName = inf.getName();
+        className = cls.getName();
+        classloader = cls.getClassLoader();
+    }
+    public Extension(Class<?> cls) {
+        clazz = cls;
+        className = cls.getName();
+        classloader = cls.getClassLoader();
+    }
+    public Extension(ClassLoader loader) {
+        classloader = loader;
+    }
+
+    public Extension(Extension ext) {
+        className = ext.className;
+        interfaceName = ext.interfaceName;
+        deferred = ext.deferred;
+        namespaces = ext.namespaces;
+        obj = ext.obj;
+        clazz = ext.clazz;
+        intf = ext.intf;
+        classloader = ext.classloader;
+        args = ext.args;
+        optional = ext.optional;
+    }
+
+    public void setOptional(boolean b) {
+        optional = b;
+    }
+    public boolean isOptional() {
+        return optional;
+    }
+
+    public String getName() {
+        return StringUtils.isEmpty(interfaceName) ? className : interfaceName;
+    }
+    public Object getLoadedObject() {
+        return obj;
+    }
+
+    public Extension cloneNoObject() {
+        Extension ext = new Extension(this);
+        ext.obj = null;
+        ext.clazz = null;
+        ext.intf = null;
+        return ext;
+    }
+
+    public String toString() {
+        StringBuilder buf = new StringBuilder(128);
+        buf.append("class: ");
+        buf.append(className);
+        buf.append(", interface: ");
+        buf.append(interfaceName);
+        buf.append(", deferred: ");
+        buf.append(deferred ? "true" : "false");
+        buf.append(", namespaces: (");
+        int n = 0;
+        for (String ns : namespaces) {
+            if (n > 0) {
+                buf.append(", ");
+            }
+            buf.append(ns);
+            n++;
+        }
+        buf.append(')');
+        return buf.toString();
+    }
+
+    public String getClassname() {
+        return className;
+    }
+
+    public void setClassname(String i) {
+        clazz = null;
+        notFound = false;
+        className = i;
+    }
+
+    public String getInterfaceName() {
+        return interfaceName;
+    }
+
+    public void setInterfaceName(String i) {
+        interfaceName = i;
+        notFound = false;
+    }
+
+    public boolean isDeferred() {
+        return deferred;
+    }
+
+    public void setDeferred(boolean d) {
+        deferred = d;
+    }
+
+    public Collection<String> getNamespaces() {
+        return namespaces;
+    }
+
+    public void setArgs(Object[] a) {
+        args = a;
+    }
+
+    protected Class<?> tryClass(String name, ClassLoader cl) {
+        Throwable origEx = null;
+        if (classloader != null) {
+            try {
+                return classloader.loadClass(name);
+            } catch (Throwable nex) {
+                //ignore, fall into the stuff below
+                //save the exception though as this is likely the important one
+                origEx = nex;
+            }
+        }
+        try {
+            return cl.loadClass(name);
+        } catch (Throwable ex) {
+            try {
+                // using the extension classloader as a fallback
+                return this.getClass().getClassLoader().loadClass(name);
+            } catch (Throwable nex) {
+                notFound = true;
+                if (!optional) {
+                    throw new ExtensionException(new Message("PROBLEM_LOADING_EXTENSION_CLASS", LOG, name),
+                        origEx != null ? origEx : ex);
+                }
+            }
+        }
+        return null;
+    }
+
+    public Class<?> getClassObject(ClassLoader cl) {
+        if (notFound) {
+            return null;
+        }
+        if (clazz != null) {
+            return clazz;
+        }
+        synchronized (this) {
+            if (clazz == null) {
+                clazz = tryClass(className, cl);
+            }
+        }
+        return clazz;
+    }
+    public Object load(ClassLoader cl, Bus b) {
+        if (obj != null) {
+            return obj;
+        }
+        Class<?> cls = getClassObject(cl);
+        try {
+            if (notFound) {
+                return null;
+            }
+            try {
+                //if there is a Bus constructor, use it.
+                if (b != null && args == null) {
+                    Constructor<?> con = cls.getConstructor(Bus.class);
+                    obj = con.newInstance(b);
+                    return obj;
+                } else if (b != null && args != null) {
+                    try {
+                        obj = cls.getConstructor(Bus.class, Object[].class).newInstance(b, args);
+                    } catch (NoSuchMethodException ex) { // no bus
+                        obj = cls.getConstructor(Object[].class).newInstance(args);
+                    }
+                    return obj;
+                } else if (args != null) {
+                    Constructor<?> con = cls.getConstructor(Object[].class);
+                    obj = con.newInstance(args);
+                    return obj;
+                }
+            } catch (InvocationTargetException ex) {
+                throw new ExtensionException(new Message(PROBLEM_CREATING_EXTENSION_CLASS, LOG, cls.getName()),
+                                             ex.getCause());
+            } catch (InstantiationException | SecurityException ex) {
+                throw new ExtensionException(new Message(PROBLEM_CREATING_EXTENSION_CLASS, LOG, cls.getName()), ex);
+            } catch (NoSuchMethodException e) {
+                //ignore
+            }
+            obj = cls.getConstructor().newInstance();
+        } catch (ExtensionException ex) {
+            notFound = true;
+            if (!optional) {
+                throw ex;
+            }
+            LOG.log(Level.FINE, "Could not load optional extension " + getName(), ex);
+        } catch (InvocationTargetException ex) {
+            notFound = true;
+            if (!optional) {
+                throw new ExtensionException(new Message(PROBLEM_CREATING_EXTENSION_CLASS, LOG, cls.getName()),
+                                             ex.getCause());
+            }
+            LOG.log(Level.FINE, "Could not load optional extension " + getName(), ex);
+        } catch (NoSuchMethodException ex) {
+            notFound = true;
+            List<Object> a = new ArrayList<>();
+            if (b != null) {
+                a.add(b);
+            }
+            if (args != null) {
+                a.add(args);
+            }
+            if (!optional) {
+                throw new ExtensionException(new Message("PROBLEM_FINDING_CONSTRUCTOR", LOG,
+                                                         cls.getName(), a), ex);
+            }
+            LOG.log(Level.FINE, "Could not load optional extension " + getName(), ex);
+        } catch (Throwable e) {
+            notFound = true;
+            if (!optional) {
+                throw new ExtensionException(new Message(PROBLEM_CREATING_EXTENSION_CLASS, LOG, cls.getName()), e);
+            }
+            LOG.log(Level.FINE, "Could not load optional extension " + getName(), e);
+        }
+        return obj;
+    }
+
+    public Class<?> loadInterface(ClassLoader cl) {
+        if (intf != null || notFound) {
+            return intf;
+        }
+        synchronized (this) {
+            if (intf == null) {
+                intf = tryClass(interfaceName, cl);
+            }
+        }
+        return intf;
+    }
+
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/extension/ExtensionManagerImpl.java b/transform/src/patch/java/org/apache/cxf/bus/extension/ExtensionManagerImpl.java
new file mode 100644
index 0000000..d4ce0be
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/extension/ExtensionManagerImpl.java
@@ -0,0 +1,381 @@
+/**
+ * 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.cxf.bus.extension;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.ResourceInjector;
+import org.apache.cxf.configuration.ConfiguredBeanLocator;
+import org.apache.cxf.configuration.Configurer;
+import org.apache.cxf.resource.ObjectTypeResolver;
+import org.apache.cxf.resource.ResourceManager;
+import org.apache.cxf.resource.ResourceResolver;
+import org.apache.cxf.resource.SinglePropertyResolver;
+
+public class ExtensionManagerImpl implements ExtensionManager, ConfiguredBeanLocator {
+    public static final String EXTENSIONMANAGER_PROPERTY_NAME = "extensionManager";
+    public static final String ACTIVATION_NAMESPACES_PROPERTY_NAME = "activationNamespaces";
+    public static final String ACTIVATION_NAMESPACES_SETTER_METHOD_NAME = "setActivationNamespaces";
+    public static final String BUS_EXTENSION_RESOURCE = "META-INF/cxf/bus-extensions.txt";
+
+    private final ClassLoader loader;
+    private ResourceManager resourceManager;
+    private Map<String, Extension> all = new ConcurrentHashMap<>();
+    private List<Extension> ordered = new CopyOnWriteArrayList<>();
+    private final Map<Class<?>, Object> activated;
+    private final Bus bus;
+
+    public ExtensionManagerImpl(ClassLoader cl, Map<Class<?>, Object> initialExtensions,
+                                ResourceManager rm, Bus b) {
+        this(new String[] {BUS_EXTENSION_RESOURCE},
+                 cl, initialExtensions, rm, b);
+    }
+    public ExtensionManagerImpl(String resource,
+                                ClassLoader cl,
+                                Map<Class<?>, Object> initialExtensions,
+                                ResourceManager rm,
+                                Bus b) {
+        this(new String[] {resource}, cl, initialExtensions, rm, b);
+    }
+    public ExtensionManagerImpl(String[] resources,
+                                ClassLoader cl,
+                                Map<Class<?>, Object> initialExtensions,
+                                ResourceManager rm,
+                                Bus b) {
+
+        loader = cl;
+        bus = b;
+        activated = initialExtensions;
+        resourceManager = rm;
+
+        ResourceResolver extensionManagerResolver =
+            new SinglePropertyResolver(EXTENSIONMANAGER_PROPERTY_NAME, this);
+        resourceManager.addResourceResolver(extensionManagerResolver);
+        resourceManager.addResourceResolver(new ObjectTypeResolver(this));
+
+        load(resources);
+        for (Map.Entry<String, Extension> ext : ExtensionRegistry.getRegisteredExtensions().entrySet()) {
+            if (!all.containsKey(ext.getKey())) {
+                all.put(ext.getKey(), ext.getValue());
+                ordered.add(ext.getValue());
+            }
+        }
+    }
+
+    final void load(String[] resources) {
+        if (resources == null) {
+            return;
+        }
+        try {
+            for (String resource : resources) {
+                load(resource);
+            }
+        } catch (IOException ex) {
+            throw new ExtensionException(ex);
+        }
+    }
+    public void add(Extension ex) {
+        all.put(ex.getName(), ex);
+        ordered.add(ex);
+    }
+
+    public void initialize() {
+        for (Extension e : ordered) {
+            if (!e.isDeferred() && e.getLoadedObject() == null) {
+                loadAndRegister(e);
+            }
+        }
+    }
+
+    public void removeBeansOfNames(List<String> names) {
+        for (String s : names) {
+            Extension ex = all.remove(s);
+            if (ex != null) {
+                ordered.remove(ex);
+            }
+        }
+    }
+    public void activateAll() {
+        for (Extension e : ordered) {
+            if (e.getLoadedObject() == null) {
+                loadAndRegister(e);
+            }
+        }
+    }
+    public <T> void activateAllByType(Class<T> type) {
+        for (Extension e : ordered) {
+            if (e.getLoadedObject() == null) {
+                Class<?> cls = e.getClassObject(loader);
+                if (cls != null && type.isAssignableFrom(cls)) {
+                    synchronized (e) {
+                        loadAndRegister(e);
+                    }
+                }
+            }
+        }
+    }
+
+    public boolean hasBeanOfName(String name) {
+        return all.containsKey(name);
+    }
+
+    final void load(String resource) throws IOException {
+        if (loader != getClass().getClassLoader()) {
+            load(resource, getClass().getClassLoader());
+        }
+        load(resource, loader);
+    }
+    final synchronized void load(String resource, ClassLoader l) throws IOException {
+
+        Enumeration<URL> urls = l.getResources(resource);
+
+        while (urls.hasMoreElements()) {
+            final URL url = urls.nextElement();
+            try (InputStream is = AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>() {
+                    public InputStream run() throws Exception {
+                        return url.openStream();
+                    }
+                })) {
+                List<Extension> exts = new TextExtensionFragmentParser(loader).getExtensions(is);
+                for (Extension e : exts) {
+                    if (loader != l) {
+                        e.classloader = l;
+                    }
+                    if (!all.containsKey(e.getName())) {
+                        all.put(e.getName(), e);
+                        ordered.add(e);
+                    }
+                }
+            } catch (PrivilegedActionException pae) {
+                throw (IOException)pae.getException();
+            }
+        }
+    }
+
+    final void loadAndRegister(Extension e) {
+        Class<?> cls;
+        if (null != e.getInterfaceName() && !"".equals(e.getInterfaceName())) {
+            cls = e.loadInterface(loader);
+        }  else {
+            cls = e.getClassObject(loader);
+        }
+        if (null != activated && null != cls && null != activated.get(cls)) {
+            return;
+        }
+
+        synchronized (e) {
+            Object obj = e.load(loader, bus);
+            if (obj == null) {
+                return;
+            }
+
+            if (null != activated) {
+                Configurer configurer = (Configurer)(activated.get(Configurer.class));
+                if (null != configurer) {
+                    configurer.configureBean(obj);
+                }
+            }
+
+            // let the object know for which namespaces it has been activated
+            ResourceResolver namespacesResolver = null;
+            if (null != e.getNamespaces()) {
+                namespacesResolver = new SinglePropertyResolver(ACTIVATION_NAMESPACES_PROPERTY_NAME,
+                                                                e.getNamespaces());
+                resourceManager.addResourceResolver(namespacesResolver);
+            }
+
+            // Since we need to support spring2.5 by removing @Resource("activationNamespaces")
+            // Now we call the setActivationNamespaces method directly here
+            if (e.getNamespaces() != null && !e.getNamespaces().isEmpty()) {
+                invokeSetterActivationNSMethod(obj, e.getNamespaces());
+            }
+
+            ResourceInjector injector = new ResourceInjector(resourceManager);
+
+            try {
+                injector.inject(obj);
+                injector.construct(obj);
+            } finally {
+                if (null != namespacesResolver) {
+                    resourceManager.removeResourceResolver(namespacesResolver);
+                }
+            }
+
+            if (null != activated) {
+                if (cls == null) {
+                    cls = obj.getClass();
+                }
+                activated.put(cls, obj);
+            }
+        }
+    }
+
+    public <T> T getExtension(String name, Class<T> type) {
+        if (name == null) {
+            return null;
+        }
+        Extension e = all.get(name);
+        if (e != null) {
+            Class<?> cls = e.getClassObject(loader);
+            if (cls != null && type.isAssignableFrom(cls)) {
+                synchronized (e) {
+                    if (e.getLoadedObject() == null) {
+                        loadAndRegister(e);
+                    }
+                    return type.cast(e.getLoadedObject());
+                }
+            }
+        }
+        return null;
+    }
+
+    private void invokeSetterActivationNSMethod(Object target, Object value) {
+        Class<?> clazz = target.getClass();
+        String methodName = ACTIVATION_NAMESPACES_SETTER_METHOD_NAME;
+        while (clazz != Object.class) {
+            Method[] methods = clazz.getMethods();
+            for (int i = 0; i < methods.length; i++) {
+                Method method = methods[i];
+                Class<?>[] params = method.getParameterTypes();
+                if (method.getName().equals(methodName) && params.length == 1) {
+                    Class<?> paramType = params[0];
+                    if (paramType.isInstance(value)) {
+                        try {
+                            method.invoke(target, new Object[] {value});
+                        } catch (Exception e) {
+                            // do nothing here
+                        }
+                        return;
+                    }
+                }
+            }
+            clazz = clazz.getSuperclass();
+        }
+    }
+    public List<String> getBeanNamesOfType(Class<?> type) {
+        List<String> ret = new LinkedList<>();
+        for (Extension ex : ordered) {
+            Class<?> cls = ex.getClassObject(loader);
+            if (cls != null && type.isAssignableFrom(cls)) {
+                synchronized (ex) {
+                    ret.add(ex.getName());
+                }
+            }
+        }
+        return ret;
+    }
+    public <T> T getBeanOfType(String name, Class<T> type) {
+        if (name == null) {
+            return null;
+        }
+        Extension ex = all.get(name);
+        if (ex != null) {
+            if (ex.getLoadedObject() == null) {
+                loadAndRegister(ex);
+            }
+            return type.cast(ex.getLoadedObject());
+        }
+        return null;
+    }
+    public <T> Collection<? extends T> getBeansOfType(Class<T> type) {
+        List<T> ret = new LinkedList<>();
+        Extension ext = all.get(type.getName());
+        if (ext != null) {
+            Class<?> cls = ext.getClassObject(loader);
+            if (cls != null && type.isAssignableFrom(cls)) {
+                synchronized (ext) {
+                    if (ext.getLoadedObject() == null) {
+                        loadAndRegister(ext);
+                    }
+                    if (ext.getLoadedObject() != null) {
+                        ret.add(type.cast(ext.getLoadedObject()));
+                    }
+                }
+            }
+        }
+        for (Extension ex : ordered) {
+            if (ex != ext) {
+                Class<?> cls = ex.getClassObject(loader);
+                if (cls != null && type.isAssignableFrom(cls)) {
+                    synchronized (ex) {
+                        if (ex.getLoadedObject() == null) {
+                            loadAndRegister(ex);
+                        }
+                        if (ex.getLoadedObject() != null) {
+                            ret.add(type.cast(ex.getLoadedObject()));
+                        }
+                    }
+                }
+            }
+        }
+        return ret;
+    }
+    public <T> boolean loadBeansOfType(Class<T> type, BeanLoaderListener<T> listener) {
+        boolean loaded = false;
+        for (Extension ex : ordered) {
+            Class<?> cls = ex.getClassObject(loader);
+            if (cls != null
+                && type.isAssignableFrom(cls)) {
+                synchronized (ex) {
+                    if (listener.loadBean(ex.getName(), cls.asSubclass(type))) {
+                        if (ex.getLoadedObject() == null) {
+                            loadAndRegister(ex);
+                        }
+                        if (listener.beanLoaded(ex.getName(), type.cast(ex.getLoadedObject()))) {
+                            return true;
+                        }
+                        loaded = true;
+                    }
+                }
+            }
+        }
+        return loaded;
+    }
+    public boolean hasConfiguredPropertyValue(String beanName, String propertyName, String value) {
+        if (beanName == null) {
+            return false;
+        }
+        Extension ex = all.get(beanName);
+        return ex != null && ex.getNamespaces() != null
+            && ex.getNamespaces().contains(value);
+    }
+    public void destroyBeans() {
+        for (Extension ex : ordered) {
+            if (ex.getLoadedObject() != null) {
+                ResourceInjector injector = new ResourceInjector(resourceManager);
+                injector.destroy(ex.getLoadedObject());
+            }
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/managers/ServiceContractResolverRegistryImpl.java b/transform/src/patch/java/org/apache/cxf/bus/managers/ServiceContractResolverRegistryImpl.java
new file mode 100644
index 0000000..a0f7af0
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/managers/ServiceContractResolverRegistryImpl.java
@@ -0,0 +1,113 @@
+/**
+ * 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.cxf.bus.managers;
+
+import java.net.URI;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.endpoint.ServiceContractResolver;
+import org.apache.cxf.endpoint.ServiceContractResolverRegistry;
+
+/**
+ * A simple contract resolver registry. It maintains a list of contract resolvers in an
+ * <code>ArrayList</code>.
+ */
+@NoJSR250Annotations(unlessNull = "bus")
+public class ServiceContractResolverRegistryImpl implements ServiceContractResolverRegistry {
+
+    private List<ServiceContractResolver> resolvers
+        = new CopyOnWriteArrayList<>();
+
+    public ServiceContractResolverRegistryImpl() {
+
+    }
+    public ServiceContractResolverRegistryImpl(Bus b) {
+        setBus(b);
+    }
+
+
+    /**
+     * Sets the bus with which the registry is associated.
+     *
+     * @param bus
+     */
+    public final void setBus(Bus bus) {
+        if (bus != null) {
+            bus.setExtension(this, ServiceContractResolverRegistry.class);
+        }
+    }
+
+    /**
+     * Calls each of the registered <code>ServiceContractResolver</code> instances
+     * to resolve the location of the service's contract. It returns the location
+     * from the first resolver that matches the QName to a location.
+     *
+     * @param qname QName to be resolved into a contract location
+     * @return URI representing the location of the contract
+    */
+    public URI getContractLocation(QName qname) {
+        for (ServiceContractResolver resolver : resolvers) {
+            URI contractLocation = resolver.getContractLocation(qname);
+            if (null != contractLocation) {
+                return contractLocation;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Tests if a resolver is alreadey registered with this registry.
+     *
+     * @param resolver the contract resolver for which to searche
+     * @return <code>true</code> if the resolver is registered
+     */
+    public boolean isRegistered(ServiceContractResolver resolver) {
+        return resolvers.contains(resolver);
+    }
+
+    /**
+     * Registers a contract resolver with this registry.
+     *
+     * @param resolver the contract resolver to register
+     */
+    public synchronized void register(ServiceContractResolver resolver) {
+        resolvers.add(resolver);
+    }
+
+    /**
+     * Removes a contract resolver from this registry.
+     *
+     * @param resolver the contract resolver to remove
+     */
+    public synchronized void unregister(ServiceContractResolver resolver) {
+        resolvers.remove(resolver);
+    }
+
+
+    protected List<ServiceContractResolver> getResolvers() {
+        return resolvers;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/osgi/CXFActivator.java b/transform/src/patch/java/org/apache/cxf/bus/osgi/CXFActivator.java
new file mode 100644
index 0000000..6504276
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/osgi/CXFActivator.java
@@ -0,0 +1,134 @@
+/**
+ * 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.cxf.bus.osgi;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cxf.bus.blueprint.BlueprintNameSpaceHandlerFactory;
+import org.apache.cxf.bus.blueprint.NamespaceHandlerRegisterer;
+import org.apache.cxf.bus.extension.Extension;
+import org.apache.cxf.bus.extension.ExtensionRegistry;
+import org.apache.cxf.common.util.CollectionUtils;
+import org.apache.cxf.internal.CXFAPINamespaceHandler;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * Is called in OSGi on start and stop of the cxf bundle.
+ * Manages
+ * - CXFBundleListener
+ * - Attaching ManagedWorkqueues to config admin service
+ * - OsgiBusListener
+ * - Blueprint namespaces
+ */
+public class CXFActivator implements BundleActivator {
+
+    private List<Extension> extensions;
+    private ManagedWorkQueueList workQueues;
+    private ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> configAdminTracker;
+    private CXFExtensionBundleListener cxfBundleListener;
+    private ServiceRegistration<ManagedServiceFactory> workQueueServiceRegistration;
+
+
+
+    /** {@inheritDoc}*/
+    public void start(BundleContext context) throws Exception {
+        workQueues = new ManagedWorkQueueList();
+        cxfBundleListener = new CXFExtensionBundleListener(context.getBundle().getBundleId());
+        context.addBundleListener(cxfBundleListener);
+        cxfBundleListener.registerExistingBundles(context);
+
+        configAdminTracker = new ServiceTracker<>(context, ConfigurationAdmin.class, null);
+        configAdminTracker.open();
+        workQueues.setConfigAdminTracker(configAdminTracker);
+        workQueueServiceRegistration = registerManagedServiceFactory(context,
+                                                                     ManagedServiceFactory.class,
+                                                                     workQueues,
+                                                                     ManagedWorkQueueList.FACTORY_PID);
+
+        extensions = new ArrayList<>();
+        extensions.add(createOsgiBusListenerExtension(context));
+        extensions.add(createManagedWorkQueueListExtension(workQueues));
+        ExtensionRegistry.addExtensions(extensions);
+
+        BlueprintNameSpaceHandlerFactory factory = new BlueprintNameSpaceHandlerFactory() {
+
+            @Override
+            public Object createNamespaceHandler() {
+                return new CXFAPINamespaceHandler();
+            }
+        };
+        NamespaceHandlerRegisterer.register(context, factory,
+                                            "http://cxf.apache.org/blueprint/core",
+                                            "http://cxf.apache.org/configuration/beans",
+                                            "http://cxf.apache.org/configuration/parameterized-types",
+                                            "http://cxf.apache.org/configuration/security",
+                                            "http://schemas.xmlsoap.org/wsdl/",
+                                            "http://www.w3.org/2005/08/addressing",
+                                            "http://schemas.xmlsoap.org/ws/2004/08/addressing");
+
+    }
+
+    private <T> ServiceRegistration<T> registerManagedServiceFactory(BundleContext context,
+                                                                     Class<T> serviceClass,
+                                                                     T service,
+                                                                     String servicePid) {
+        return context.registerService(serviceClass, service, 
+                                       CollectionUtils.singletonDictionary(Constants.SERVICE_PID, servicePid));
+    }
+
+    private Extension createOsgiBusListenerExtension(BundleContext context) {
+        Extension busListener = new Extension(OSGIBusListener.class);
+        busListener.setArgs(new Object[] {context});
+        return busListener;
+    }
+
+    private static Extension createManagedWorkQueueListExtension(final ManagedWorkQueueList workQueues) {
+        return new Extension(ManagedWorkQueueList.class) {
+            
+            @Override
+            public Object getLoadedObject() {
+                return workQueues;
+            }
+
+            @Override
+            public Extension cloneNoObject() {
+                return this;
+            }
+        };
+    }
+
+    /** {@inheritDoc}*/
+    public void stop(BundleContext context) throws Exception {
+        context.removeBundleListener(cxfBundleListener);
+        cxfBundleListener.shutdown();
+        workQueues.shutDown();
+        workQueueServiceRegistration.unregister();
+        configAdminTracker.close();
+        ExtensionRegistry.removeExtensions(extensions);
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/osgi/CXFExtensionBundleListener.java b/transform/src/patch/java/org/apache/cxf/bus/osgi/CXFExtensionBundleListener.java
new file mode 100644
index 0000000..ee9bb15
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/osgi/CXFExtensionBundleListener.java
@@ -0,0 +1,181 @@
+/**
+ * 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.cxf.bus.osgi;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.bus.extension.Extension;
+import org.apache.cxf.bus.extension.ExtensionException;
+import org.apache.cxf.bus.extension.ExtensionRegistry;
+import org.apache.cxf.bus.extension.TextExtensionFragmentParser;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.SynchronousBundleListener;
+
+public class CXFExtensionBundleListener implements SynchronousBundleListener {
+    private static final Logger LOG = LogUtils.getL7dLogger(CXFActivator.class);
+    private long id;
+    private ConcurrentMap<Long, List<OSGiExtension>> extensions
+        = new ConcurrentHashMap<>(16, 0.75f, 4);
+
+    public CXFExtensionBundleListener(long bundleId) {
+        this.id = bundleId;
+    }
+
+    public void registerExistingBundles(BundleContext context) {
+        for (Bundle bundle : context.getBundles()) {
+            if ((bundle.getState() == Bundle.RESOLVED
+                || bundle.getState() == Bundle.STARTING
+                || bundle.getState() == Bundle.ACTIVE
+                || bundle.getState() == Bundle.STOPPING)
+                && bundle.getBundleId() != context.getBundle().getBundleId()) {
+                register(bundle);
+            }
+        }
+    }
+
+    /** {@inheritDoc}*/
+    public void bundleChanged(BundleEvent event) {
+        if (event.getType() == BundleEvent.RESOLVED && id != event.getBundle().getBundleId()) {
+            register(event.getBundle());
+        } else if (event.getType() == BundleEvent.UNRESOLVED || event.getType() == BundleEvent.UNINSTALLED) {
+            unregister(event.getBundle().getBundleId());
+        }
+    }
+
+    protected void register(final Bundle bundle) {
+        Enumeration<?> e = bundle.findEntries("META-INF/cxf/", "bus-extensions.txt", false);
+        while (e != null && e.hasMoreElements()) {
+            List<Extension> orig = new TextExtensionFragmentParser(null).getExtensions((URL)e.nextElement());
+            addExtensions(bundle, orig);
+        }
+    }
+
+    private boolean addExtensions(final Bundle bundle, List<Extension> orig) {
+        if (orig.isEmpty()) {
+            return false;
+        }
+
+        List<String> names = new ArrayList<>(orig.size());
+        for (Extension ext : orig) {
+            names.add(ext.getName());
+        }
+        LOG.info("Adding the extensions from bundle " + bundle.getSymbolicName()
+                 + " (" + bundle.getBundleId() + ") " + names);
+        List<OSGiExtension> list = extensions.get(bundle.getBundleId());
+        if (list == null) {
+            list = new CopyOnWriteArrayList<>();
+            List<OSGiExtension> preList = extensions.putIfAbsent(bundle.getBundleId(), list);
+            if (preList != null) {
+                list = preList;
+            }
+        }
+        for (Extension ext : orig) {
+            list.add(new OSGiExtension(ext, bundle));
+        }
+        ExtensionRegistry.addExtensions(list);
+        return !list.isEmpty();
+    }
+
+    protected void unregister(final long bundleId) {
+        List<OSGiExtension> list = extensions.remove(bundleId);
+        if (list != null) {
+            LOG.info("Removing the extensions for bundle " + bundleId);
+            ExtensionRegistry.removeExtensions(list);
+        }
+    }
+
+    public void shutdown() {
+        while (!extensions.isEmpty()) {
+            unregister(extensions.keySet().iterator().next());
+        }
+    }
+
+    public class OSGiExtension extends Extension {
+        final Bundle bundle;
+        Object serviceObject;
+        public OSGiExtension(Extension e, Bundle b) {
+            super(e);
+            bundle = b;
+        }
+
+        public void setServiceObject(Object o) {
+            serviceObject = o;
+            obj = o;
+        }
+        
+        @Override
+        public Object load(ClassLoader cl, Bus b) {
+            if (interfaceName == null && bundle.getBundleContext() != null) {
+                ServiceReference<?> ref = bundle.getBundleContext().getServiceReference(className);
+                if (ref != null && ref.getBundle().getBundleId() == bundle.getBundleId()) {
+                    Object o = bundle.getBundleContext().getService(ref);
+                    serviceObject = o;
+                    obj = o;
+                    return obj;
+                }
+            }
+            return super.load(cl, b);
+        }
+        
+        @Override
+        protected Class<?> tryClass(String name, ClassLoader cl) {
+            Class<?> c = null;
+            Throwable origExc = null;
+            try {
+                c = bundle.loadClass(className);
+            } catch (Throwable e) {
+                origExc = e;
+            }
+            if (c == null) {
+                try {
+                    return super.tryClass(name, cl);
+                } catch (ExtensionException ee) {
+                    if (origExc != null) {
+                        throw new ExtensionException(new Message("PROBLEM_LOADING_EXTENSION_CLASS",
+                                                                 Extension.LOG, name),
+                                                     origExc);
+                    }
+                    throw ee;
+                }
+            }
+            return c;
+        }
+
+        @Override
+        public Extension cloneNoObject() {
+            OSGiExtension ext = new OSGiExtension(this, bundle);
+            ext.obj = serviceObject;
+            return ext;
+        }
+
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/osgi/OSGIBusListener.java b/transform/src/patch/java/org/apache/cxf/bus/osgi/OSGIBusListener.java
new file mode 100644
index 0000000..aad270d
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/osgi/OSGIBusListener.java
@@ -0,0 +1,224 @@
+/**
+ * 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.cxf.bus.osgi;
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.bus.extension.ExtensionManagerImpl;
+import org.apache.cxf.buslifecycle.BusCreationListener;
+import org.apache.cxf.buslifecycle.BusLifeCycleListener;
+import org.apache.cxf.buslifecycle.BusLifeCycleManager;
+import org.apache.cxf.common.util.CollectionUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.configuration.ConfiguredBeanLocator;
+import org.apache.cxf.endpoint.ClientLifeCycleListener;
+import org.apache.cxf.endpoint.ClientLifeCycleManager;
+import org.apache.cxf.endpoint.ServerLifeCycleListener;
+import org.apache.cxf.endpoint.ServerLifeCycleManager;
+import org.apache.cxf.feature.Feature;
+import org.apache.cxf.workqueue.WorkQueueManager;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.Version;
+
+public class OSGIBusListener implements BusLifeCycleListener {
+    public static final String CONTEXT_SYMBOLIC_NAME_PROPERTY = "cxf.context.symbolicname";
+    public static final String CONTEXT_VERSION_PROPERTY = "cxf.context.version";
+    public static final String CONTEXT_NAME_PROPERTY = "cxf.bus.id";
+
+    private static final String SERVICE_PROPERTY_PRIVATE = "org.apache.cxf.bus.private.extension";
+    private static final String SERVICE_PROPERTY_RESTRICTED = "org.apache.cxf.bus.restricted.extension";
+    private static final String BUS_EXTENSION_BUNDLES_EXCLUDES = "bus.extension.bundles.excludes";
+    Bus bus;
+    ServiceRegistration<?> service;
+    BundleContext defaultContext;
+    private Pattern extensionBundlesExcludesPattern;
+
+    public OSGIBusListener(Bus b) {
+        this(b, null);
+    }
+    public OSGIBusListener(Bus b, Object[] args) {
+        bus = b;
+        if (args != null && args.length > 0
+            && args[0] instanceof BundleContext) {
+            defaultContext = (BundleContext)args[0];
+        }
+        String extExcludes = (String)bus.getProperty(BUS_EXTENSION_BUNDLES_EXCLUDES);
+        if (!StringUtils.isEmpty(extExcludes)) {
+            try {
+                extensionBundlesExcludesPattern = Pattern.compile(extExcludes);
+            } catch (IllegalArgumentException e) {
+                // ignore
+            }
+        }
+        BusLifeCycleManager manager = bus.getExtension(BusLifeCycleManager.class);
+        manager.registerLifeCycleListener(this);
+        registerConfiguredBeanLocator();
+        registerClientLifeCycleListeners();
+        registerServerLifecycleListeners();
+        registerBusFeatures();
+        sendBusCreatedToBusCreationListeners();
+
+    }
+    private void registerConfiguredBeanLocator() {
+        final ConfiguredBeanLocator cbl = bus.getExtension(ConfiguredBeanLocator.class);
+        if (cbl instanceof ExtensionManagerImpl) {
+            // wire in the OSGi things
+            bus.setExtension(new OSGiBeanLocator(cbl, defaultContext),
+                             ConfiguredBeanLocator.class);
+        }
+    }
+
+    public void initComplete() {
+        ManagedWorkQueueList wqList = bus.getExtension(ManagedWorkQueueList.class);
+        if (wqList != null) {
+            WorkQueueManager manager = bus.getExtension(WorkQueueManager.class);
+            wqList.addAllToWorkQueueManager(manager);
+        }
+        registerBusAsService();
+    }
+
+
+    public void preShutdown() {
+    }
+
+    public void postShutdown() {
+        if (service != null) {
+            service.unregister();
+            service = null;
+        }
+    }
+
+    private static ServiceReference<?>[] getServiceReferences(BundleContext context, Class<?> serviceClass) {
+        ServiceReference<?>[] refs = null;
+        try {
+            refs = context.getServiceReferences(serviceClass.getName(), null);
+        } catch (InvalidSyntaxException e) {
+            // ignore
+        }
+        if (refs == null) {
+            refs = new ServiceReference<?>[]{};
+        }
+        return refs;
+    }
+
+    private void sendBusCreatedToBusCreationListeners() {
+        ServiceReference<?>[] refs = getServiceReferences(defaultContext, BusCreationListener.class);
+        for (ServiceReference<?> ref : refs) {
+            if (!isPrivate(ref) && !isExcluded(ref)) {
+                BusCreationListener listener = (BusCreationListener)defaultContext.getService(ref);
+                listener.busCreated(bus);
+            }
+        }
+    }
+
+    private void registerServerLifecycleListeners() {
+        ServiceReference<?>[] refs = getServiceReferences(defaultContext, ServerLifeCycleListener.class);
+        ServerLifeCycleManager clcm = bus.getExtension(ServerLifeCycleManager.class);
+        for (ServiceReference<?> ref : refs) {
+            if (!isPrivate(ref) && !isExcluded(ref)) {
+                ServerLifeCycleListener listener = (ServerLifeCycleListener)defaultContext.getService(ref);
+                clcm.registerListener(listener);
+            }
+        }
+    }
+    private void registerClientLifeCycleListeners() {
+        ServiceReference<?>[] refs = getServiceReferences(defaultContext, ClientLifeCycleListener.class);
+        ClientLifeCycleManager clcm = bus.getExtension(ClientLifeCycleManager.class);
+        for (ServiceReference<?> ref : refs) {
+            if (!isPrivate(ref) && !isExcluded(ref)) {
+                ClientLifeCycleListener listener = (ClientLifeCycleListener)defaultContext.getService(ref);
+                clcm.registerListener(listener);
+            }
+        }
+    }
+
+    private void registerBusFeatures() {
+        ServiceReference<?>[] refs = getServiceReferences(defaultContext, Feature.class);
+        for (ServiceReference<?> ref : refs) {
+            if (!isPrivate(ref) && !isExcluded(ref)) {
+                Feature feature = (Feature)defaultContext.getService(ref);
+                bus.getFeatures().add(feature);
+            }
+        }
+    }
+
+    private boolean isPrivate(ServiceReference<?> ref) {
+        Object o = ref.getProperty(SERVICE_PROPERTY_PRIVATE);
+        
+        if (o == null) {
+            return false;
+        }
+        
+        Boolean pvt = Boolean.FALSE;
+        if (o instanceof String) {
+            pvt = Boolean.parseBoolean((String)o);
+        } else if (o instanceof Boolean) {
+            pvt = (Boolean)o;
+        }
+        return pvt.booleanValue();
+    }
+
+    private boolean isExcluded(ServiceReference<?> ref) {
+        String o = (String)ref.getProperty(SERVICE_PROPERTY_RESTRICTED);
+        if (!StringUtils.isEmpty(o)) {
+            // if the service's restricted-regex is set, the service is excluded when the app not matching that regex
+            BundleContext app = bus.getExtension(BundleContext.class);
+            try {
+                if (app != null && !app.getBundle().getSymbolicName().matches(o)) {
+                    return true;
+                }
+            } catch (IllegalArgumentException e) {
+                // ignore
+            }
+        }
+        // if the excludes-regex is set, the service is excluded when matching that regex.
+        return extensionBundlesExcludesPattern != null
+            && extensionBundlesExcludesPattern.matcher(ref.getBundle().getSymbolicName()).matches();
+    }
+
+    private Version getBundleVersion(Bundle bundle) {
+        Dictionary<?, ?> headers = bundle.getHeaders();
+        String version = (String) headers.get(Constants.BUNDLE_VERSION);
+        return (version != null) ? Version.parseVersion(version) : Version.emptyVersion;
+    }
+
+
+
+    private void registerBusAsService() {
+        BundleContext context = bus.getExtension(BundleContext.class);
+        if (context != null) {
+            Map<String, Object> props = new HashMap<>();
+            props.put(CONTEXT_SYMBOLIC_NAME_PROPERTY, context.getBundle().getSymbolicName());
+            props.put(CONTEXT_VERSION_PROPERTY, getBundleVersion(context.getBundle()));
+            props.put(CONTEXT_NAME_PROPERTY, bus.getId());
+
+            service = context.registerService(Bus.class.getName(), bus, CollectionUtils.toDictionary(props));
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/transform/src/patch/java/org/apache/cxf/bus/resource/ResourceManagerImpl.java b/transform/src/patch/java/org/apache/cxf/bus/resource/ResourceManagerImpl.java
new file mode 100644
index 0000000..99c6ee9
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/resource/ResourceManagerImpl.java
@@ -0,0 +1,85 @@
+/**
+ * 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.cxf.bus.resource;
+
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.configuration.ConfiguredBeanLocator;
+import org.apache.cxf.extension.BusExtension;
+import org.apache.cxf.resource.DefaultResourceManager;
+import org.apache.cxf.resource.ObjectTypeResolver;
+import org.apache.cxf.resource.ResourceManager;
+import org.apache.cxf.resource.ResourceResolver;
+
+@NoJSR250Annotations(unlessNull = "bus")
+public class ResourceManagerImpl extends DefaultResourceManager implements BusExtension {
+
+    private Bus bus;
+
+    public ResourceManagerImpl() {
+    }
+
+    public ResourceManagerImpl(Bus b) {
+        super();
+        setBus(b);
+    }
+    
+    @Override
+    protected void onFirstResolve() {
+        super.onFirstResolve();
+        if (bus != null) {
+            ConfiguredBeanLocator locator = bus.getExtension(ConfiguredBeanLocator.class);
+            if (locator != null) {
+                this.addResourceResolvers(locator.getBeansOfType(ResourceResolver.class));
+            }
+        }
+    }
+
+    /**
+     * Set the list of resolvers for this resource manager.
+     * @param resolvers
+     */
+    public final void setResolvers(List<? extends ResourceResolver> resolvers) {
+        registeredResolvers.clear();
+        registeredResolvers.addAll(resolvers);
+    }
+
+    @Resource
+    public final void setBus(Bus b) {
+        if (bus != b) {
+            bus = b;
+            firstCalled = false;
+            super.addResourceResolver(new ObjectTypeResolver(bus));
+            if (null != bus) {
+                bus.setExtension(this, ResourceManager.class);
+            }
+        }
+    }
+
+    public Class<?> getRegistrationType() {
+        return ResourceManager.class;
+    }
+
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/spring/BusDefinitionParser.java b/transform/src/patch/java/org/apache/cxf/bus/spring/BusDefinitionParser.java
new file mode 100644
index 0000000..9d508b6
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/spring/BusDefinitionParser.java
@@ -0,0 +1,310 @@
+/**
+ * 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.cxf.bus.spring;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
+import org.apache.cxf.configuration.spring.BusWiringType;
+import org.apache.cxf.feature.Feature;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.AbstractBasicInterceptorProvider;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.message.Message;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+public class BusDefinitionParser extends AbstractBeanDefinitionParser {
+    private static AtomicInteger counter = new AtomicInteger(0);
+
+    public BusDefinitionParser() {
+        super();
+        setBeanClass(BusConfig.class);
+    }
+
+    @Override
+    protected void doParse(Element element, ParserContext ctx, BeanDefinitionBuilder bean) {
+        String bus = element.getAttribute("bus");
+        if (StringUtils.isEmpty(bus)) {
+            bus = element.getAttribute("name");
+            if (StringUtils.isEmpty(bus)) {
+                element.setAttribute("bus", bus);
+            }
+        }
+        element.removeAttribute("name");
+        if (StringUtils.isEmpty(bus)) {
+            bus = "cxf";
+        }
+        String id = element.getAttribute("id");
+        if (!StringUtils.isEmpty(id)) {
+            bean.addPropertyValue("id", id);
+        }
+
+        super.doParse(element, ctx, bean);
+
+        if (ctx.getRegistry().containsBeanDefinition(bus)) {
+            BeanDefinition def = ctx.getRegistry().getBeanDefinition(bus);
+            copyProps(bean, def);
+            bean.addConstructorArgValue(bus);
+        } else if (!"cxf".equals(bus)) {
+            bean.getRawBeanDefinition().setBeanClass(SpringBus.class);
+            bean.setDestroyMethodName("shutdown");
+            try {
+                element.setUserData("ID", bus, null);
+                bean.getRawBeanDefinition().getPropertyValues().removePropertyValue("bus");
+            } catch (Throwable t) {
+                //likely not DOM level 3, ignore
+            }
+        } else {
+            addBusWiringAttribute(bean, BusWiringType.PROPERTY, bus, ctx);
+            bean.getRawBeanDefinition().setAttribute(WIRE_BUS_CREATE,
+                                                     resolveId(element, null, ctx));
+            bean.addConstructorArgValue(bus);
+        }
+    }
+    
+    @Override
+    protected boolean processBusAttribute(Element element, ParserContext ctx,
+                                          BeanDefinitionBuilder bean,
+                                          String val) {
+        return false;
+    }
+    
+    private void copyProps(BeanDefinitionBuilder src, BeanDefinition def) {
+        for (PropertyValue v : src.getBeanDefinition().getPropertyValues().getPropertyValues()) {
+            if (!"bus".equals(v.getName())) {
+                def.getPropertyValues().addPropertyValue(v.getName(), v.getValue());
+            }
+            src.getBeanDefinition().getPropertyValues().removePropertyValue(v);
+        }
+
+    }
+
+    @Override
+    protected void mapElement(ParserContext ctx,
+                              BeanDefinitionBuilder bean,
+                              Element e,
+                              String name) {
+        if ("inInterceptors".equals(name) || "inFaultInterceptors".equals(name)
+            || "outInterceptors".equals(name) || "outFaultInterceptors".equals(name)
+            || "features".equals(name)) {
+            List<?> list = ctx.getDelegate().parseListElement(e, bean.getBeanDefinition());
+            bean.addPropertyValue(name, list);
+        } else if ("properties".equals(name)) {
+            Map<?, ?> map = ctx.getDelegate().parseMapElement(e, bean.getBeanDefinition());
+            bean.addPropertyValue("properties", map);
+        }
+    }
+    @Override
+    protected String resolveId(Element element, AbstractBeanDefinition definition,
+                               ParserContext ctx) {
+        String bus = null;
+        try {
+            bus = (String)element.getUserData("ID");
+        } catch (Throwable t) {
+            //ignore
+        }
+        if (bus == null) {
+            bus = element.getAttribute("bus");
+            if (StringUtils.isEmpty(bus)) {
+                bus = element.getAttribute("name");
+            }
+            if (StringUtils.isEmpty(bus)) {
+                bus = Bus.DEFAULT_BUS_ID + ".config" + counter.getAndIncrement();
+            } else {
+                bus = bus + ".config";
+            }
+            try {
+                element.setUserData("ID", bus, null);
+            } catch (Throwable t) {
+                //maybe no DOM level 3, ignore, but, may have issues with the counter
+            }
+        }
+        return bus;
+    }
+
+    @NoJSR250Annotations
+    public static class BusConfig extends AbstractBasicInterceptorProvider
+        implements ApplicationContextAware {
+
+        Bus bus;
+        String busName;
+        String id;
+        Collection<Feature> features;
+        Map<String, Object> properties;
+
+        public BusConfig(String busName) {
+            this.busName = busName;
+        }
+
+        public void setBus(Bus bb) {
+            if (bus == bb) {
+                return;
+            }
+            if (properties != null) {
+                bb.setProperties(properties);
+                properties = null;
+            }
+            if (!getInInterceptors().isEmpty()) {
+                bb.getInInterceptors().addAll(getInInterceptors());
+            }
+            if (!getOutInterceptors().isEmpty()) {
+                bb.getOutInterceptors().addAll(getOutInterceptors());
+            }
+            if (!getInFaultInterceptors().isEmpty()) {
+                bb.getInFaultInterceptors().addAll(getInFaultInterceptors());
+            }
+            if (!getOutFaultInterceptors().isEmpty()) {
+                bb.getOutFaultInterceptors().addAll(getOutFaultInterceptors());
+            }
+            if (!StringUtils.isEmpty(id)) {
+                bb.setId(id);
+            }
+            if (features != null) {
+                bb.setFeatures(features);
+                features = null;
+            }
+            bus = bb;
+        }
+
+        public void setApplicationContext(ApplicationContext applicationContext) {
+            if (bus != null) {
+                return;
+            }
+        }
+
+        @Override
+        public List<Interceptor<? extends Message>> getOutFaultInterceptors() {
+            if (bus != null) {
+                return bus.getOutFaultInterceptors();
+            }
+            return super.getOutFaultInterceptors();
+        }
+
+        @Override
+        public List<Interceptor<? extends Message>> getInFaultInterceptors() {
+            if (bus != null) {
+                return bus.getInFaultInterceptors();
+            }
+            return super.getInFaultInterceptors();
+        }
+
+        @Override
+        public List<Interceptor<? extends Message>> getInInterceptors() {
+            if (bus != null) {
+                return bus.getInInterceptors();
+            }
+            return super.getInInterceptors();
+        }
+
+        @Override
+        public List<Interceptor<? extends Message>> getOutInterceptors() {
+            if (bus != null) {
+                return bus.getOutInterceptors();
+            }
+            return super.getOutInterceptors();
+        }
+
+        @Override
+        public void setInInterceptors(List<Interceptor<? extends Message>> interceptors) {
+            if (bus != null) {
+                bus.getInInterceptors().addAll(interceptors);
+            } else {
+                super.setInInterceptors(interceptors);
+            }
+        }
+
+        @Override
+        public void setInFaultInterceptors(List<Interceptor<? extends Message>> interceptors) {
+            if (bus != null) {
+                bus.getInFaultInterceptors().addAll(interceptors);
+            } else {
+                super.setInFaultInterceptors(interceptors);
+            }
+        }
+
+        @Override
+        public void setOutInterceptors(List<Interceptor<? extends Message>> interceptors) {
+            if (bus != null) {
+                bus.getOutInterceptors().addAll(interceptors);
+            } else {
+                super.setOutInterceptors(interceptors);
+            }
+        }
+
+        @Override
+        public void setOutFaultInterceptors(List<Interceptor<? extends Message>> interceptors) {
+            if (bus != null) {
+                bus.getOutFaultInterceptors().addAll(interceptors);
+            } else {
+                super.setOutFaultInterceptors(interceptors);
+            }
+        }
+
+        public Collection<Feature> getFeatures() {
+            if (bus != null) {
+                return bus.getFeatures();
+            }
+            return features;
+        }
+
+        public void setFeatures(Collection<? extends Feature> features) {
+            if (bus != null) {
+                bus.setFeatures(features);
+            } else {
+                this.features = CastUtils.cast(features);
+            }
+
+        }
+
+        public Map<String, Object> getProperties() {
+            if (bus != null) {
+                return bus.getProperties();
+            }
+            return properties;
+        }
+        public void setProperties(Map<String, Object> s) {
+            if (bus != null) {
+                bus.setProperties(s);
+            } else {
+                this.properties = s;
+            }
+        }
+
+        public void setId(String s) {
+            id = s;
+        }
+
+
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/spring/BusEntityResolver.java b/transform/src/patch/java/org/apache/cxf/bus/spring/BusEntityResolver.java
new file mode 100644
index 0000000..1e95e28
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/spring/BusEntityResolver.java
@@ -0,0 +1,94 @@
+/**
+ * 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.cxf.bus.spring;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.springframework.beans.factory.xml.DelegatingEntityResolver;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PropertiesLoaderUtils;
+import org.springframework.util.CollectionUtils;
+
+/**
+ *
+ */
+public class BusEntityResolver extends DelegatingEntityResolver  {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(BusEntityResolver.class);
+
+    private EntityResolver dtdResolver;
+    private EntityResolver schemaResolver;
+    private Map<String, String> schemaMappings;
+    private ClassLoader classLoader;
+
+    public BusEntityResolver(ClassLoader loader, EntityResolver dr, EntityResolver sr) {
+        super(dr, sr);
+        classLoader = loader;
+        dtdResolver = dr;
+        schemaResolver = sr;
+
+        try {
+            Properties mappings = PropertiesLoaderUtils.loadAllProperties("META-INF/spring.schemas",
+                                                                          classLoader);
+            schemaMappings = new ConcurrentHashMap<>(mappings.size());
+            CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
+        } catch (IOException e) {
+            //ignore
+        }
+    }
+
+    @Override
+    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
+        InputSource source = super.resolveEntity(publicId, systemId);
+        if (null == source && null != systemId) {
+            // try the schema and dtd resolver in turn, ignoring the suffix in publicId
+            LOG.log(Level.FINE, "Attempting to resolve systemId {0}", systemId);
+            source = schemaResolver.resolveEntity(publicId, systemId);
+            if (null == source) {
+                source = dtdResolver.resolveEntity(publicId, systemId);
+            }
+        }
+        
+        if (null == source) {
+            return null;
+        }
+        
+        String resourceLocation = schemaMappings.get(systemId);
+        if (resourceLocation != null && publicId == null) {
+            Resource resource = new ClassPathResource(resourceLocation, classLoader);
+            if (resource.exists()) {
+                source.setPublicId(systemId);
+                source.setSystemId(resource.getURL().toString());
+            }
+        }
+        return source;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/spring/BusExtensionPostProcessor.java b/transform/src/patch/java/org/apache/cxf/bus/spring/BusExtensionPostProcessor.java
new file mode 100644
index 0000000..9389be6
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/spring/BusExtensionPostProcessor.java
@@ -0,0 +1,71 @@
+/**
+ * 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.cxf.bus.spring;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.extension.BusExtension;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.Ordered;
+
+@NoJSR250Annotations
+public class BusExtensionPostProcessor implements BeanPostProcessor, ApplicationContextAware, Ordered {
+
+    private Bus bus;
+    private ApplicationContext context;
+
+    public void setApplicationContext(ApplicationContext ctx) {
+        context = ctx;
+    }
+
+    public int getOrder() {
+        return 1001;
+    }
+
+
+    @Override
+    public Object postProcessAfterInitialization(Object bean, String beanId) {
+        return bean;
+    }
+
+    @Override
+    public Object postProcessBeforeInitialization(Object bean, String beanId) {
+        if (bean instanceof BusExtension && null != getBus()) {
+            Class<? extends Object> cls = ((BusExtension)bean).getRegistrationType();
+            registerExt(bean, cls);
+        } else if (bean instanceof Bus && Bus.DEFAULT_BUS_ID.equals(beanId)) {
+            bus = (Bus)bean;
+        }
+        return bean;
+    }
+    private <T> void registerExt(Object bean, Class<T> cls) {
+        getBus().setExtension(cls.cast(bean), cls);
+    }
+
+    private Bus getBus() {
+        if (bus == null) {
+            bus = (Bus)context.getBean(Bus.DEFAULT_BUS_ID);
+        }
+        return bus;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/spring/Jsr250BeanPostProcessor.java b/transform/src/patch/java/org/apache/cxf/bus/spring/Jsr250BeanPostProcessor.java
new file mode 100644
index 0000000..1fb0746
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/spring/Jsr250BeanPostProcessor.java
@@ -0,0 +1,164 @@
+/**
+ * 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.cxf.bus.spring;
+
+
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.ResourceInjector;
+import org.apache.cxf.resource.ResourceManager;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.Ordered;
+
+public class Jsr250BeanPostProcessor
+    implements DestructionAwareBeanPostProcessor, Ordered, ApplicationContextAware {
+
+    private ResourceManager resourceManager;
+    private ApplicationContext context;
+
+    private boolean isProcessing = true;
+    //private int count;
+    //private int count2;
+
+    Jsr250BeanPostProcessor() {
+    }
+
+    public void setApplicationContext(ApplicationContext applicationContext) {
+        context = applicationContext;
+        try {
+            Class<?> cls = Class
+                .forName("org.springframework.context.annotation.CommonAnnotationBeanPostProcessor");
+            isProcessing = context.getBeanNamesForType(cls, true, false).length == 0;
+        } catch (ClassNotFoundException e) {
+            isProcessing = true;
+        }
+    }
+
+    public int getOrder() {
+        return 1010;
+    }
+
+    private boolean injectable(Object bean, String beanId) {
+        return !"cxf".equals(beanId) && ResourceInjector.processable(bean.getClass(), bean);
+    }
+    private ResourceManager getResourceManager(Object bean) {
+        if (resourceManager == null) {
+            boolean temp = isProcessing;
+            isProcessing = false;
+            if (bean instanceof ResourceManager) {
+                resourceManager = (ResourceManager)bean;
+                resourceManager.addResourceResolver(new BusApplicationContextResourceResolver(context));
+            } else if (bean instanceof Bus) {
+                Bus b = (Bus)bean;
+                ResourceManager m = b.getExtension(ResourceManager.class);
+                if (m != null) {
+                    resourceManager = m;
+                    if (!(b instanceof SpringBus)) {
+                        resourceManager
+                            .addResourceResolver(new BusApplicationContextResourceResolver(context));
+                    }
+                }
+            } else {
+                ResourceManager m = null;
+                Bus b = null;
+                try {
+                    m = (ResourceManager)context.getBean(ResourceManager.class.getName());
+                } catch (NoSuchBeanDefinitionException t) {
+                    //ignore - no resource manager
+                }
+                if (m == null) {
+                    b = (Bus)context.getBean("cxf");
+                    m = b.getExtension(ResourceManager.class);
+                }
+                if (m != null) {
+                    resourceManager = m;
+                    if (!(b instanceof SpringBus)) {
+                        resourceManager
+                            .addResourceResolver(new BusApplicationContextResourceResolver(context));
+                    }
+                }
+            }
+            isProcessing = temp;
+        }
+        return resourceManager;
+    }
+    
+    @Override
+    public Object postProcessAfterInitialization(Object bean, String beanId) {
+        if (!isProcessing) {
+            if (resourceManager == null && bean instanceof ResourceManager) {
+                resourceManager = (ResourceManager)bean;
+                resourceManager.addResourceResolver(new BusApplicationContextResourceResolver(context));
+            }
+            return bean;
+        }
+        if (bean != null
+            && injectable(bean, beanId)) {
+            new ResourceInjector(getResourceManager(bean)).construct(bean);
+        }
+        return bean;
+    }
+
+    @Override
+    public Object postProcessBeforeInitialization(Object bean, String beanId) {
+        if (!isProcessing) {
+            return bean;
+        }
+        if (bean instanceof Bus) {
+            getResourceManager(bean);
+        }
+        /*
+        if (bean.getClass().getName().contains("Corb")) {
+            Thread.dumpStack();
+        }
+        */
+
+        if (bean != null
+            && injectable(bean, beanId)) {
+            new ResourceInjector(getResourceManager(bean)).inject(bean);
+            /*
+            System.out.println("p :" + (++count) + ": " + bean.getClass().getName() + " " + beanId);
+        } else if (bean != null) {
+            System.out.println("np: " + (++count2)
+                               + ": " + bean.getClass().getName() + " " + beanId);
+                               */
+        }
+        return bean;
+    }
+
+    public void postProcessBeforeDestruction(Object bean, String beanId) {
+        if (!isProcessing) {
+            return;
+        }
+        if (bean != null
+            && injectable(bean, beanId)) {
+            new ResourceInjector(getResourceManager(bean)).destroy(bean);
+        }
+    }
+
+    @Override
+    public boolean requiresDestruction(Object bean) {
+        return isProcessing;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/spring/NamespaceHandler.java b/transform/src/patch/java/org/apache/cxf/bus/spring/NamespaceHandler.java
new file mode 100644
index 0000000..9211ea8
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/spring/NamespaceHandler.java
@@ -0,0 +1,57 @@
+/**
+ * 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.cxf.bus.spring;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.configuration.spring.SimpleBeanDefinitionParser;
+import org.apache.cxf.feature.FastInfosetFeature;
+import org.apache.cxf.workqueue.AutomaticWorkQueueImpl;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+import org.springframework.beans.factory.xml.ParserContext;
+
+public class NamespaceHandler extends NamespaceHandlerSupport {
+    @SuppressWarnings("deprecation")
+    public void init() {
+        registerBeanDefinitionParser("bus",
+                                     new BusDefinitionParser());
+        registerBeanDefinitionParser("logging",
+                                     new SimpleBeanDefinitionParser(org.apache.cxf.feature.LoggingFeature.class));
+        registerBeanDefinitionParser("fastinfoset",
+                                     new SimpleBeanDefinitionParser(FastInfosetFeature.class));
+
+        registerBeanDefinitionParser("workqueue",
+                                     new SimpleBeanDefinitionParser(AutomaticWorkQueueImpl.class) {
+
+                @Override
+                protected void processNameAttribute(Element element,
+                                                ParserContext ctx,
+                                                BeanDefinitionBuilder bean,
+                                                String val) {
+                    bean.addPropertyValue("name", val);
+                    element.removeAttribute("name");
+                    if (!element.hasAttribute("id")) {
+                        element.setAttribute("id", "cxf.workqueue." + val);
+                    }
+
+                }
+            });
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/bus/spring/SpringBus.java b/transform/src/patch/java/org/apache/cxf/bus/spring/SpringBus.java
new file mode 100644
index 0000000..6616c8e
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/bus/spring/SpringBus.java
@@ -0,0 +1,142 @@
+/**
+ * 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.cxf.bus.spring;
+
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
+import org.apache.cxf.configuration.ConfiguredBeanLocator;
+import org.apache.cxf.configuration.Configurer;
+import org.apache.cxf.configuration.spring.ConfigurerImpl;
+import org.apache.cxf.resource.ResourceManager;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.context.support.AbstractApplicationContext;
+
+/**
+ *
+ */
+public class SpringBus extends ExtensionManagerBus
+    implements ApplicationContextAware {
+
+    AbstractApplicationContext ctx;
+    boolean closeContext;
+
+    public SpringBus() {
+    }
+
+    public void setBusConfig(BusDefinitionParser.BusConfig bc) {
+        bc.setBus(this);
+    }
+
+    /** {@inheritDoc}*/
+    public void setApplicationContext(ApplicationContext applicationContext) {
+        ctx = (AbstractApplicationContext)applicationContext;
+        @SuppressWarnings("rawtypes")
+        ApplicationListener listener = new ApplicationListener() {
+            public void onApplicationEvent(ApplicationEvent event) {
+                SpringBus.this.onApplicationEvent(event);
+            }
+        };
+        ctx.addApplicationListener(listener);
+        ApplicationContext ac = applicationContext.getParent();
+        while (ac != null) {
+            if (ac instanceof AbstractApplicationContext) {
+                ((AbstractApplicationContext)ac).addApplicationListener(listener);
+            }
+            ac = ac.getParent();
+        }
+
+        // set the classLoader extension with the application context classLoader
+        setExtension(applicationContext.getClassLoader(), ClassLoader.class);
+
+        setExtension(new ConfigurerImpl(applicationContext), Configurer.class);
+
+        ResourceManager m = getExtension(ResourceManager.class);
+        m.addResourceResolver(new BusApplicationContextResourceResolver(applicationContext));
+
+        setExtension(applicationContext, ApplicationContext.class);
+        ConfiguredBeanLocator loc = getExtension(ConfiguredBeanLocator.class);
+        if (!(loc instanceof SpringBeanLocator)) {
+            setExtension(new SpringBeanLocator(applicationContext, this), ConfiguredBeanLocator.class);
+        }
+        if (getState() != BusState.RUNNING) {
+            initialize();
+        }
+    }
+
+    public void onApplicationEvent(ApplicationEvent event) {
+        if (ctx == null) {
+            return;
+        }
+        boolean doIt = false;
+        ApplicationContext ac = ctx;
+        while (ac != null) {
+            if (event.getSource() == ac) {
+                doIt = true;
+                break;
+            }
+            ac = ac.getParent();
+        }
+        if (doIt) {
+            if (event instanceof ContextRefreshedEvent) {
+                if (getState() != BusState.RUNNING) {
+                    initialize();
+                }
+            } else if (event instanceof ContextClosedEvent && getState() == BusState.RUNNING) {
+                // The bus could be create by using SpringBusFactory.createBus("/cxf.xml");
+                // Just to make sure the shutdown is called rightly
+                shutdown();
+            }
+        }
+    }
+
+    @Override
+    public void destroyBeans() {
+        if (closeContext) {
+            ctx.close();
+        }
+        super.destroyBeans();
+    }
+
+    @Override
+    public String getId() {
+        if (id == null) {
+            try {
+                Class<?> clsbc = Class.forName("org.osgi.framework.BundleContext");
+                Class<?> clsb = Class.forName("org.osgi.framework.Bundle");
+                Object o = getExtension(clsbc);
+                Object o2 = clsbc.getMethod("getBundle").invoke(o);
+                String s = (String)clsb.getMethod("getSymbolicName").invoke(o2);
+                id = s + '-' + DEFAULT_BUS_ID + Integer.toString(this.hashCode());
+            } catch (Throwable t) {
+                id = super.getId();
+            }
+        }
+        return id;
+    }
+
+    public void setCloseContext(boolean b) {
+        closeContext = b;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/catalog/CatalogXmlSchemaURIResolver.java b/transform/src/patch/java/org/apache/cxf/catalog/CatalogXmlSchemaURIResolver.java
new file mode 100644
index 0000000..15a3ce2
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/catalog/CatalogXmlSchemaURIResolver.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.cxf.catalog;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.xml.sax.InputSource;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.resource.ExtendedURIResolver;
+import org.apache.cxf.transport.TransportURIResolver;
+import org.apache.ws.commons.schema.XmlSchemaException;
+import org.apache.ws.commons.schema.resolver.URIResolver;
+
+/**
+ * Resolves URIs using Apache Commons Resolver API.
+ */
+public class CatalogXmlSchemaURIResolver implements URIResolver {
+
+    private ExtendedURIResolver resolver;
+    private Bus bus;
+    private Map<String, String> resolved = new HashMap<>();
+
+    public CatalogXmlSchemaURIResolver(Bus bus) {
+        this.resolver = new TransportURIResolver(bus);
+        this.bus = bus;
+    }
+
+    public Map<String, String> getResolvedMap() {
+        return resolved;
+    }
+
+    public InputSource resolveEntity(String targetNamespace, String schemaLocation, String baseUri) {
+        final String resolvedSchemaLocation;
+        OASISCatalogManager catalogResolver = OASISCatalogManager.getCatalogManager(bus);
+        try {
+            resolvedSchemaLocation = new OASISCatalogManagerHelper().resolve(catalogResolver,
+                                          schemaLocation, baseUri);
+        } catch (Exception e) {
+            throw new RuntimeException("Catalog resolution failed", e);
+        }
+
+        final InputSource in;
+        if (resolvedSchemaLocation == null) {
+            in = this.resolver.resolve(schemaLocation, baseUri);
+        } else {
+            resolved.put(schemaLocation, resolvedSchemaLocation);
+            in = this.resolver.resolve(resolvedSchemaLocation, baseUri);
+        }
+
+        // If we return null, a NPE is raised in SchemaBuilder.
+        // If we return new InputSource(), a XmlSchemaException is raised
+        // but without any nice error message. So let's just throw a nice error here.
+        if (in == null) {
+            throw new XmlSchemaException("Unable to locate imported document "
+                                         + "at '" + schemaLocation + "'"
+                                         + (baseUri == null
+                                            ? "."
+                                            : ", relative to '" + baseUri + "'."));
+        } else if (in.getByteStream() != null
+            && !(in.getByteStream() instanceof ByteArrayInputStream)) {
+            //workaround bug in XmlSchema - XmlSchema is not closing the InputStreams
+            //that are returned for imports.  Thus, with a lot of services starting up
+            //or a lot of schemas imported or similar, it's easy to run out of
+            //file handles.  We'll just load the file into a byte[] and return that.
+            try {
+                InputStream ins = IOUtils.loadIntoBAIS(in.getByteStream());
+                in.setByteStream(ins);
+            } catch (IOException e) {
+                throw new XmlSchemaException("Unable to load imported document "
+                                             + "at '" + schemaLocation + "'"
+                                             + (baseUri == null
+                                                ? "."
+                                                : ", relative to '" + baseUri + "'."),
+                                                e);
+            }
+        }
+
+        return in;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/i18n/Exception.java b/transform/src/patch/java/org/apache/cxf/common/i18n/Exception.java
new file mode 100644
index 0000000..fcb38ad
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/i18n/Exception.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.cxf.common.i18n;
+
+
+
+public class Exception extends java.lang.Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    private final Message message;
+
+    public Exception(Message msg) {
+        message = msg;
+    }
+
+    public Exception(Message msg, Throwable t) {
+        super(t);
+        message = msg;
+    }
+
+    public Exception(Throwable cause) {
+        super(cause);
+        message = null;
+    }
+
+    public String getCode() {
+        if (null != message) {
+            return message.getCode();
+        }
+        return null;
+    }
+
+    @Override
+    public String getMessage() {
+        if (null != message) {
+            return message.toString();
+        }
+        return null;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/i18n/Message.java b/transform/src/patch/java/org/apache/cxf/common/i18n/Message.java
new file mode 100644
index 0000000..d1a65c8
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/i18n/Message.java
@@ -0,0 +1,91 @@
+/**
+ * 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.cxf.common.i18n;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.logging.Logger;
+
+public class Message implements Serializable {
+    private static final long serialVersionUID = 42L;
+
+    transient String code;
+    transient Object[] parameters;
+    transient ResourceBundle bundle;
+
+    /**
+     * Constructor.
+     *
+     * @param key the message catalog (resource bundle) key
+     * @param logger a logger with an associated resource bundle
+     * @param params the message substitution parameters
+     */
+    public Message(String key, Logger logger, Object...params) {
+        this(key, logger.getResourceBundle(), params);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param key the message catalog (resource bundle) key
+     * @param catalog the resource bundle
+     * @param params the message substitution parameters
+     */
+    public Message(String key, ResourceBundle catalog, Object...params) {
+        code = key;
+        bundle = catalog;
+        parameters = params;
+    }
+
+    public String toString() {
+        final String fmt;
+        try {
+            if (null == bundle) {
+                return code;
+            }
+            fmt = bundle.getString(code);
+        } catch (MissingResourceException ex) {
+            return code;
+        }
+        return MessageFormat.format(fmt, parameters);
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public Object[] getParameters() {
+        return parameters;
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out)
+        throws IOException {
+        out.writeUTF(toString());
+    }
+    private void readObject(java.io.ObjectInputStream in)
+        throws IOException, ClassNotFoundException {
+        code = in.readUTF();
+        bundle = null;
+        parameters = null;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/i18n/UncheckedException.java b/transform/src/patch/java/org/apache/cxf/common/i18n/UncheckedException.java
new file mode 100644
index 0000000..ea15fd7
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/i18n/UncheckedException.java
@@ -0,0 +1,84 @@
+/**
+ * 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.cxf.common.i18n;
+
+import java.util.ResourceBundle;
+import java.util.logging.Logger;
+
+
+
+public class UncheckedException extends java.lang.RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    protected final Message message;
+
+    public UncheckedException(Message msg) {
+        message = msg;
+    }
+
+    public UncheckedException(Message msg, Throwable t) {
+        super(t);
+        message = msg;
+    }
+
+    public UncheckedException(Throwable cause) {
+        super(cause);
+        message = null;
+    }
+
+    public UncheckedException(Logger log, String msg, Object ... params) {
+        message = new org.apache.cxf.common.i18n.Message(msg,
+                                                         log,
+                                                         params);
+    }
+    public UncheckedException(ResourceBundle bundle, String msg, Object ... params) {
+        message = new org.apache.cxf.common.i18n.Message(msg,
+                                                         bundle,
+                                                         params);
+    }
+    public UncheckedException(Logger log, String msg, Throwable t, Object ... params) {
+        super(t);
+        message = new org.apache.cxf.common.i18n.Message(msg,
+                                                         log,
+                                                         params);
+    }
+    public UncheckedException(ResourceBundle bundle, String msg, Throwable t, Object ... params) {
+        super(t);
+        message = new org.apache.cxf.common.i18n.Message(msg,
+                                                         bundle,
+                                                         params);
+    }
+
+    public String getCode() {
+        if (null != message) {
+            return message.getCode();
+        }
+        return null;
+    }
+
+    @Override
+    public String getMessage() {
+        if (null != message) {
+            return message.toString();
+        }
+        return null;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/injection/ResourceInjector.java b/transform/src/patch/java/org/apache/cxf/common/injection/ResourceInjector.java
new file mode 100644
index 0000000..9c420ce
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/injection/ResourceInjector.java
@@ -0,0 +1,446 @@
+/**
+ * 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.cxf.common.injection;
+
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.annotation.Resource;
+import javax.annotation.Resources;
+
+
+import org.apache.cxf.common.annotation.AbstractAnnotationVisitor;
+import org.apache.cxf.common.annotation.AnnotationProcessor;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ClassHelper;
+import org.apache.cxf.common.util.ReflectionUtil;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.resource.ResourceManager;
+import org.apache.cxf.resource.ResourceResolver;
+
+
+/**
+ * injects references specified using @Resource annotation
+ *
+ */
+public class ResourceInjector extends AbstractAnnotationVisitor {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(ResourceInjector.class);
+    private static final List<Class<? extends Annotation>> ANNOTATIONS = new ArrayList<>();
+
+    static {
+        ANNOTATIONS.add(Resource.class);
+        ANNOTATIONS.add(Resources.class);
+    }
+
+
+    private final ResourceManager resourceManager;
+    private final List<ResourceResolver> resourceResolvers;
+
+    public ResourceInjector(ResourceManager resMgr) {
+        this(resMgr, resMgr == null ? null : resMgr.getResourceResolvers());
+    }
+
+    public ResourceInjector(ResourceManager resMgr, List<ResourceResolver> resolvers) {
+        super(ANNOTATIONS);
+        resourceManager = resMgr;
+        resourceResolvers = resolvers;
+    }
+
+    private static Field getField(Class<?> cls, String name) {
+        if (cls == null) {
+            return null;
+        }
+        try {
+            Field f = ReflectionUtil.getDeclaredField(cls, name);
+            if (f == null) {
+                f = getField(cls.getSuperclass(), name);
+            }
+            return f;
+        } catch (Exception ex) {
+            return getField(cls.getSuperclass(), name);
+        }
+    }
+
+    public static boolean processable(Class<?> cls, Object o) {
+        if (cls.getName().startsWith("java.")
+            || cls.getName().startsWith("javax.")) {
+            return false;
+        }
+        NoJSR250Annotations njsr = cls.getAnnotation(NoJSR250Annotations.class);
+        if (njsr != null) {
+            for (String s : njsr.unlessNull()) {
+                try {
+                    Field f = getField(cls, s);
+                    ReflectionUtil.setAccessible(f);
+                    if (f.get(o) == null) {
+                        return true;
+                    }
+                } catch (Exception ex) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        return true;
+    }
+
+    public void inject(Object o) {
+        inject(o, o.getClass());
+    }
+
+    public void inject(Object o, Class<?> claz) {
+        if (processable(claz, o)) {
+            AnnotationProcessor processor = new AnnotationProcessor(o);
+            processor.accept(this, claz);
+        }
+    }
+
+    public void construct(Object o) {
+        setTarget(o);
+        if (processable(targetClass, o)) {
+            invokePostConstruct();
+        }
+    }
+    public void construct(Object o, Class<?> cls) {
+        setTarget(o, cls);
+        if (processable(targetClass, o)) {
+            invokePostConstruct();
+        }
+    }
+
+
+    public void destroy(Object o) {
+        setTarget(o);
+        if (processable(targetClass, o)) {
+            invokePreDestroy();
+        }
+    }
+
+
+    // Implementation of org.apache.cxf.common.annotation.AnnotationVisitor
+
+    @Override
+    public final void visitClass(final Class<?> clz, final Annotation annotation) { //NOPMD
+
+        assert annotation instanceof Resource || annotation instanceof Resources : annotation;
+
+        if (annotation instanceof Resource) {
+            injectResourceClassLevel((Resource)annotation);
+        } else if (annotation instanceof Resources) {
+            Resources resources = (Resources)annotation;
+            for (Resource resource : resources.value()) {
+                injectResourceClassLevel(resource);
+            }
+        }
+
+    }
+
+    private void injectResourceClassLevel(Resource res) {
+        if (res.name() == null || "".equals(res.name())) {
+            LOG.log(Level.INFO, "RESOURCE_NAME_NOT_SPECIFIED", target.getClass().getName());
+            return;
+        }
+
+        Object resource;
+        // first find a setter that matches this resource
+        Method setter = findSetterForResource(res);
+        if (setter != null) {
+            Class<?> type = getResourceType(res, setter);
+            resource = resolveResource(res.name(), type);
+            if (resource == null) {
+                LOG.log(Level.INFO, "RESOURCE_RESOLVE_FAILED");
+                return;
+            }
+
+            invokeSetter(setter, resource);
+            return;
+        }
+
+        Field field = findFieldForResource(res);
+        if (field != null) {
+            Class<?> type = getResourceType(res, field);
+            resource = resolveResource(res.name(), type);
+            if (resource == null) {
+                LOG.log(Level.INFO, "RESOURCE_RESOLVE_FAILED");
+                return;
+            }
+            injectField(field, resource);
+            return;
+        }
+        LOG.log(Level.SEVERE, "NO_SETTER_OR_FIELD_FOR_RESOURCE", getTarget().getClass().getName());
+    }
+
+    public final void visitField(final Field field, final Annotation annotation) {
+
+        assert annotation instanceof Resource : annotation;
+
+        Resource res = (Resource)annotation;
+
+        String name = getFieldNameForResource(res, field);
+        Class<?> type = getResourceType(res, field);
+
+        Object resource = resolveResource(name, type);
+        if (resource == null
+            && "".equals(res.name())) {
+            resource = resolveResource(null, type);
+        }
+        if (resource != null) {
+            injectField(field, resource);
+        } else {
+            LOG.log(Level.INFO, "RESOURCE_RESOLVE_FAILED", name);
+        }
+    }
+
+    public final void visitMethod(final Method method, final Annotation annotation) {
+
+        assert annotation instanceof Resource : annotation;
+
+        Resource res = (Resource)annotation;
+
+        String resourceName = getResourceName(res, method);
+        Class<?> clz = getResourceType(res, method);
+
+        Object resource = resolveResource(resourceName, clz);
+        if (resource == null
+            && "".equals(res.name())) {
+            resource = resolveResource(null, clz);
+        }
+        if (resource != null) {
+            invokeSetter(method, resource);
+        } else {
+            LOG.log(Level.FINE, "RESOURCE_RESOLVE_FAILED", new Object[] {resourceName, clz});
+        }
+    }
+
+    private Field findFieldForResource(Resource res) {
+        assert target != null;
+        assert res.name() != null;
+
+        for (Field field : target.getClass().getFields()) {
+            if (field.getName().equals(res.name())) {
+                return field;
+            }
+        }
+
+        for (Field field : target.getClass().getDeclaredFields()) {
+            if (field.getName().equals(res.name())) {
+                return field;
+            }
+        }
+        return null;
+    }
+
+
+    private Method findSetterForResource(Resource res) {
+        assert target != null;
+
+        String setterName = resourceNameToSetter(res.name());
+        Method setterMethod = null;
+
+        for (Method method : getTarget().getClass().getMethods()) {
+            if (setterName.equals(method.getName())) {
+                setterMethod = method;
+                break;
+            }
+        }
+
+        if (setterMethod != null && setterMethod.getParameterTypes().length != 1) {
+            LOG.log(Level.WARNING, "SETTER_INJECTION_WITH_INCORRECT_TYPE", setterMethod);
+        }
+        return setterMethod;
+    }
+
+    private static String resourceNameToSetter(String resName) {
+        return "set" + StringUtils.capitalize(resName);
+    }
+
+    private void invokeSetter(Method method, Object resource) {
+        try {
+            ReflectionUtil.setAccessible(method);
+            if (method.getDeclaringClass().isAssignableFrom(getTarget().getClass())) {
+                method.invoke(getTarget(), resource);
+            } else { // deal with the proxy setter method
+                Method targetMethod = getTarget().getClass().getMethod(method.getName(),
+                                                                       method.getParameterTypes());
+                targetMethod.invoke(getTarget(), resource);
+            }
+        } catch (IllegalAccessException e) {
+            LOG.log(Level.SEVERE, "INJECTION_SETTER_NOT_VISIBLE", method);
+        } catch (InvocationTargetException | SecurityException e) {
+            LogUtils.log(LOG, Level.SEVERE, "INJECTION_SETTER_RAISED_EXCEPTION", e, method);
+        } catch (NoSuchMethodException e) {
+            LOG.log(Level.SEVERE, "INJECTION_SETTER_METHOD_NOT_FOUND", new Object[] {method.getName()});
+        }
+    }
+
+    private String getResourceName(Resource res, Method method) {
+        assert method != null;
+        assert res != null;
+        assert method.getName().startsWith("set") : method;
+
+        if (res.name() == null || res.name().isEmpty()) {
+            String name = method.getName().substring(3);
+            name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
+            return method.getDeclaringClass().getCanonicalName() + '/' + name;
+        }
+        return res.name();
+    }
+
+
+
+    private void injectField(Field field, Object resource) {
+        assert field != null;
+        assert resource != null;
+
+        boolean accessible = field.isAccessible();
+        try {
+            if (field.getType().isAssignableFrom(resource.getClass())) {
+                ReflectionUtil.setAccessible(field);
+                field.set(ClassHelper.getRealObject(getTarget()), resource);
+            }
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+            LOG.severe("FAILED_TO_INJECT_FIELD");
+        } finally {
+            ReflectionUtil.setAccessible(field, accessible);
+        }
+    }
+
+
+    public void invokePostConstruct() {
+
+        boolean accessible = false;
+        for (Method method : getPostConstructMethods()) {
+            PostConstruct pc = method.getAnnotation(PostConstruct.class);
+            if (pc != null) {
+                try {
+                    ReflectionUtil.setAccessible(method);
+                    method.invoke(target);
+                } catch (IllegalAccessException e) {
+                    LOG.log(Level.WARNING, "INJECTION_COMPLETE_NOT_VISIBLE", method);
+                } catch (InvocationTargetException e) {
+                    LOG.log(Level.WARNING, "INJECTION_COMPLETE_THREW_EXCEPTION", e);
+                } finally {
+                    ReflectionUtil.setAccessible(method, accessible);
+                }
+            }
+        }
+    }
+
+    public void invokePreDestroy() {
+
+        boolean accessible = false;
+        for (Method method : getPreDestroyMethods()) {
+            PreDestroy pd = method.getAnnotation(PreDestroy.class);
+            if (pd != null) {
+                try {
+                    ReflectionUtil.setAccessible(method);
+                    method.invoke(target);
+                } catch (IllegalAccessException e) {
+                    LOG.log(Level.WARNING, "PRE_DESTROY_NOT_VISIBLE", method);
+                } catch (InvocationTargetException e) {
+                    LOG.log(Level.WARNING, "PRE_DESTROY_THREW_EXCEPTION", e);
+                } finally {
+                    ReflectionUtil.setAccessible(method, accessible);
+                }
+            }
+        }
+    }
+
+
+    private Collection<Method> getPostConstructMethods() {
+        return getAnnotatedMethods(PostConstruct.class);
+    }
+
+    private Collection<Method> getPreDestroyMethods() {
+        return getAnnotatedMethods(PreDestroy.class);
+    }
+
+    private Collection<Method> getAnnotatedMethods(Class<? extends Annotation> acls) {
+
+        Collection<Method> methods = new LinkedList<>();
+        addAnnotatedMethods(acls, getTarget().getClass().getMethods(), methods);
+        addAnnotatedMethods(acls, ReflectionUtil.getDeclaredMethods(getTarget().getClass()), methods);
+        if (getTargetClass() != getTarget().getClass()) {
+            addAnnotatedMethods(acls, getTargetClass().getMethods(), methods);
+            addAnnotatedMethods(acls, ReflectionUtil.getDeclaredMethods(getTargetClass()), methods);
+        }
+        return methods;
+    }
+
+    private void addAnnotatedMethods(Class<? extends Annotation> acls, Method[] methods,
+        Collection<Method> annotatedMethods) {
+        for (Method method : methods) {
+            if (method.getAnnotation(acls) != null
+                && !annotatedMethods.contains(method)) {
+                annotatedMethods.add(method);
+            }
+        }
+    }
+
+
+    /**
+     * making this protected to keep pmd happy
+     */
+    protected Class<?> getResourceType(Resource res, Field field) {
+        assert res != null;
+        Class<?> type = res.type();
+        if (res.type() == null || Object.class == res.type()) {
+            type = field.getType();
+        }
+        return type;
+    }
+
+
+    private Class<?> getResourceType(Resource res, Method method) {
+        return res.type() != null && !Object.class.equals(res.type())
+            ? res.type()
+            : method.getParameterTypes()[0];
+    }
+
+
+    private String getFieldNameForResource(Resource res, Field field) {
+        assert res != null;
+        if (res.name() == null || "".equals(res.name())) {
+            return field.getDeclaringClass().getCanonicalName() + "/" + field.getName();
+        }
+        return res.name();
+    }
+
+    private Object resolveResource(String resourceName, Class<?> type) {
+        if (resourceManager == null) {
+            return null;
+        }
+        return resourceManager.resolveResource(resourceName, type, resourceResolvers);
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/jaxb/JAXBUtils.java b/transform/src/patch/java/org/apache/cxf/common/jaxb/JAXBUtils.java
new file mode 100644
index 0000000..f018e2a
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/jaxb/JAXBUtils.java
@@ -0,0 +1,1180 @@
+/**
+ * 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.cxf.common.jaxb;
+
+
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.charset.StandardCharsets;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.PropertyException;
+import javax.xml.bind.SchemaOutputResolver;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.attachment.AttachmentMarshaller;
+import javax.xml.bind.attachment.AttachmentUnmarshaller;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.spi.ClassLoaderService;
+import org.apache.cxf.common.util.CachedClass;
+import org.apache.cxf.common.util.PackageUtils;
+import org.apache.cxf.common.util.ProxyHelper;
+import org.apache.cxf.common.util.ReflectionInvokationHandler;
+import org.apache.cxf.common.util.ReflectionInvokationHandler.WrapReturn;
+import org.apache.cxf.common.util.ReflectionUtil;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.common.util.SystemPropertyAction;
+import org.apache.cxf.common.xmlschema.SchemaCollection;
+import org.apache.cxf.helpers.JavaUtils;
+
+public final class JAXBUtils {
+    public static final String JAXB_URI = "http://java.sun.com/xml/ns/jaxb";
+
+    private static final Logger LOG = LogUtils.getL7dLogger(JAXBUtils.class);
+
+    public enum IdentifierType {
+        CLASS,
+        INTERFACE,
+        GETTER,
+        SETTER,
+        VARIABLE,
+        CONSTANT
+    };
+
+    private static final char[] XML_NAME_PUNCTUATION_CHARS = new char[] {
+        /* hyphen                       */ '\u002D',
+        /* period                       */ '\u002E',
+        /* colon                        */'\u003A',
+        /* dot                          */ '\u00B7',
+        /* greek ano teleia             */ '\u0387',
+        /* arabic end of ayah           */ '\u06DD',
+        /* arabic start of rub el hizb  */'\u06DE',
+        /* underscore                   */ '\u005F',
+    };
+
+    private static final String XML_NAME_PUNCTUATION_STRING = new String(XML_NAME_PUNCTUATION_CHARS);
+
+    private static final Map<String, String> BUILTIN_DATATYPES_MAP;
+    private static final Map<String, Class<?>> HOLDER_TYPES_MAP;
+    private static ClassLoader jaxbXjcLoader;
+    private static volatile Optional<Object> jaxbMinimumEscapeHandler;
+    private static volatile Optional<Object> jaxbNoEscapeHandler;
+    
+    static {
+        BUILTIN_DATATYPES_MAP = new HashMap<>();
+        BUILTIN_DATATYPES_MAP.put("string", "java.lang.String");
+        BUILTIN_DATATYPES_MAP.put("integer", "java.math.BigInteger");
+        BUILTIN_DATATYPES_MAP.put("int", "int");
+        BUILTIN_DATATYPES_MAP.put("long", "long");
+        BUILTIN_DATATYPES_MAP.put("short", "short");
+        BUILTIN_DATATYPES_MAP.put("decimal", "java.math.BigDecimal");
+        BUILTIN_DATATYPES_MAP.put("float", "float");
+        BUILTIN_DATATYPES_MAP.put("double", "double");
+        BUILTIN_DATATYPES_MAP.put("boolean", "boolean");
+        BUILTIN_DATATYPES_MAP.put("byte", "byte");
+        BUILTIN_DATATYPES_MAP.put("QName", "javax.xml.namespace.QName");
+        BUILTIN_DATATYPES_MAP.put("dateTime", "javax.xml.datatype.XMLGregorianCalendar");
+        BUILTIN_DATATYPES_MAP.put("base64Binary", "byte[]");
+        BUILTIN_DATATYPES_MAP.put("hexBinary", "byte[]");
+        BUILTIN_DATATYPES_MAP.put("unsignedInt", "long");
+        BUILTIN_DATATYPES_MAP.put("unsignedShort", "short");
+        BUILTIN_DATATYPES_MAP.put("unsignedByte", "byte");
+        BUILTIN_DATATYPES_MAP.put("time", "javax.xml.datatype.XMLGregorianCalendar");
+        BUILTIN_DATATYPES_MAP.put("date", "javax.xml.datatype.XMLGregorianCalendar");
+        BUILTIN_DATATYPES_MAP.put("gYear", "javax.xml.datatype.XMLGregorianCalendar");
+        BUILTIN_DATATYPES_MAP.put("gYearMonth", "javax.xml.datatype.XMLGregorianCalendar");
+        BUILTIN_DATATYPES_MAP.put("gMonth", "javax.xml.datatype.XMLGregorianCalendar");
+        BUILTIN_DATATYPES_MAP.put("gMonthDay", "javax.xml.datatype.XMLGregorianCalendar");
+        BUILTIN_DATATYPES_MAP.put("gDay", "javax.xml.datatype.XMLGregorianCalendar");
+        BUILTIN_DATATYPES_MAP.put("duration", "javax.xml.datatype.Duration");
+        BUILTIN_DATATYPES_MAP.put("NOTATION", "javax.xml.namespace.QName");
+
+        HOLDER_TYPES_MAP = new HashMap<>();
+        HOLDER_TYPES_MAP.put("int", java.lang.Integer.class);
+        HOLDER_TYPES_MAP.put("long", java.lang.Long.class);
+        HOLDER_TYPES_MAP.put("short", java.lang.Short.class);
+        HOLDER_TYPES_MAP.put("float", java.lang.Float.class);
+        HOLDER_TYPES_MAP.put("double", java.lang.Double.class);
+        HOLDER_TYPES_MAP.put("boolean", java.lang.Boolean.class);
+        HOLDER_TYPES_MAP.put("byte", java.lang.Byte.class);
+    }
+
+
+    /**
+     * prevents instantiation
+     *
+     */
+    private JAXBUtils() {
+    }
+
+    public static void closeUnmarshaller(Unmarshaller u) {
+        if (u instanceof Closeable) {
+            //need to do this to clear the ThreadLocal cache
+            //see https://java.net/jira/browse/JAXB-1000
+
+            try {
+                ((Closeable)u).close();
+            } catch (IOException e) {
+                //ignore
+            }
+        }
+    }
+    public static Object unmarshall(JAXBContext c, Element e) throws JAXBException {
+        Unmarshaller u = c.createUnmarshaller();
+        try {
+            u.setEventHandler(null);
+            return u.unmarshal(e);
+        } finally {
+            closeUnmarshaller(u);
+        }
+    }
+    public static <T> JAXBElement<T> unmarshall(JAXBContext c, Element e, Class<T> cls) throws JAXBException {
+        Unmarshaller u = c.createUnmarshaller();
+        try {
+            u.setEventHandler(null);
+            return u.unmarshal(e, cls);
+        } finally {
+            closeUnmarshaller(u);
+        }
+    }
+    public static Object unmarshall(JAXBContext c, Source s) throws JAXBException {
+        Unmarshaller u = c.createUnmarshaller();
+        try {
+            u.setEventHandler(null);
+            return u.unmarshal(s);
+        } finally {
+            closeUnmarshaller(u);
+        }
+    }
+    public static <T> JAXBElement<T> unmarshall(JAXBContext c,
+                                                XMLStreamReader reader,
+                                                Class<T> cls) throws JAXBException {
+        Unmarshaller u = c.createUnmarshaller();
+        try {
+            u.setEventHandler(null);
+            return u.unmarshal(reader, cls);
+        } finally {
+            closeUnmarshaller(u);
+        }
+    }
+    public static Object unmarshall(JAXBContext c,
+                                    XMLStreamReader reader) throws JAXBException {
+        Unmarshaller u = c.createUnmarshaller();
+        try {
+            u.setEventHandler(null);
+            return u.unmarshal(reader);
+        } finally {
+            closeUnmarshaller(u);
+        }
+    }
+
+    public static String builtInTypeToJavaType(String type) {
+        return BUILTIN_DATATYPES_MAP.get(type);
+    }
+
+    public static Class<?> holderClass(String type) {
+        return HOLDER_TYPES_MAP.get(type);
+    }
+
+    /**
+     * Checks if the specified word is a Java keyword (as defined in JavaUtils).
+     *
+     * @param word the word to check.
+     * @return true if the word is a keyword.
+     * @see org.apache.cxf.helpers.JavaUtils
+     */
+    protected static boolean isJavaKeyword(String word) {
+        return JavaUtils.isJavaKeyword(word);
+    }
+
+    /**
+     * Generates a Java package name from a URI according to the
+     * algorithm outlined in JAXB 2.0.
+     *
+     * @param namespaceURI the namespace URI.
+     * @return the package name.
+     */
+    public static String namespaceURIToPackage(String namespaceURI) {
+        try {
+            return nameSpaceURIToPackage(new URI(namespaceURI));
+        } catch (URISyntaxException ex) {
+            return null;
+        }
+    }
+
+    /**
+     * Generates a Java package name from a URI according to the
+     * algorithm outlined in Appendix D of JAXB (2.0+).
+     *
+     * @param uri the namespace URI.
+     * @return the package name.
+     */
+    public static String nameSpaceURIToPackage(URI uri) {
+
+        StringBuilder packageName = new StringBuilder();
+        String authority = uri.getAuthority();
+        String scheme = uri.getScheme();
+        if (authority == null && "urn".equals(scheme)) {
+            authority = uri.getSchemeSpecificPart();
+        }
+
+        if (null != authority && !"".equals(authority)) {
+            if ("urn".equals(scheme)) {
+                packageName.append(authority);
+                /* JAXB 2.2 D.5.1, Rule #5 */
+                for (int i = 0; i < packageName.length(); i++) {
+                    if (packageName.charAt(i) == '-') {
+                        packageName.setCharAt(i, '.');
+                    }
+                }
+                authority = packageName.toString();
+                packageName.setLength(0);
+
+                StringTokenizer st = new StringTokenizer(authority, ":");
+                while (st.hasMoreTokens()) {
+                    String token = st.nextToken();
+                    if (packageName.length() > 0) {
+                        packageName.insert(0, '.');
+                        packageName.insert(0, normalizePackageNamePart(token));
+                    } else {
+                        packageName.insert(0, token);
+                    }
+                }
+                authority = packageName.toString();
+                packageName.setLength(0);
+
+            }
+
+            StringTokenizer st = new StringTokenizer(authority, ".");
+            if (st.hasMoreTokens()) {
+                while (st.hasMoreTokens()) {
+                    String token = st.nextToken();
+                    if (packageName.length() == 0) {
+                        if ("www".equals(token)) {
+                            continue;
+                        }
+                    } else {
+                        packageName.insert(0, '.');
+                    }
+                    packageName.insert(0, normalizePackageNamePart(token));
+                }
+            }
+
+            if (!("http".equalsIgnoreCase(scheme) || "urn".equalsIgnoreCase(scheme))) {
+                packageName.insert(0, '.');
+                packageName.insert(0, normalizePackageNamePart(scheme));
+            }
+
+        }
+
+        String path = uri.getPath();
+        if (path == null) {
+            path = "";
+        }
+        /* JAXB 2.2 D.5.1 Rule 2 - remove trailing .??, .???, or .html only. */
+        int index = path.lastIndexOf('.');
+        if (index < 0) {
+            index = path.length();
+        } else {
+            String ending = path.substring(index + 1);
+            if (ending.length() < 2 || (ending.length() > 3
+                && !"html".equalsIgnoreCase(ending))) {
+                index = path.length();
+            }
+        }
+        StringTokenizer st = new StringTokenizer(path.substring(0, index), "/");
+        while (st.hasMoreTokens()) {
+            String token = st.nextToken();
+            if (packageName.length() > 0) {
+                packageName.append('.');
+            }
+            packageName.append(normalizePackageNamePart(token));
+        }
+        return packageName.toString();
+    }
+
+    private static String normalizePackageNamePart(String name) {
+        StringBuilder sname = new StringBuilder(name.toLowerCase());
+
+        for (int i = 0; i < sname.length(); i++) {
+            sname.setCharAt(i, Character.toLowerCase(sname.charAt(i)));
+        }
+
+        for (int i = 0; i < sname.length(); i++) {
+            if (!Character.isJavaIdentifierPart(sname.charAt(i))) {
+                sname.setCharAt(i, '_');
+            }
+        }
+
+        if (isJavaKeyword(sname.toString())) {
+            sname.insert(0, '_');
+        }
+
+        if (!Character.isJavaIdentifierStart(sname.charAt(0))) {
+            sname.insert(0, '_');
+        }
+
+        return sname.toString();
+    }
+
+
+    /**
+     * Converts an XML name to a Java identifier according to the mapping
+     * algorithm outlined in the JAXB specification
+     *
+     * @param name the XML name
+     * @return the Java identifier
+     */
+    public static String nameToIdentifier(String name, IdentifierType type) {
+
+        if (null == name || name.length() == 0) {
+            return name;
+        }
+
+        // algorithm will not change an XML name that is already a legal and
+        // conventional (!) Java class, method, or constant identifier
+
+        StringBuilder buf = new StringBuilder(name);
+        boolean hasUnderscore = false;
+        boolean legalIdentifier = Character.isJavaIdentifierStart(buf.charAt(0));
+
+        for (int i = 1; i < name.length() && legalIdentifier; i++) {
+            legalIdentifier &= Character.isJavaIdentifierPart(buf.charAt(i));
+            hasUnderscore |= '_' == buf.charAt(i);
+        }
+
+        boolean conventionalIdentifier = isConventionalIdentifier(buf, type);
+        if (legalIdentifier && conventionalIdentifier) {
+            if (JAXBUtils.isJavaKeyword(name) && type == IdentifierType.VARIABLE) {
+                name = normalizePackageNamePart(name);
+            }
+            if (!hasUnderscore || IdentifierType.CLASS != type) {
+                return name;
+            }
+        }
+
+        // split into words
+
+        List<String> words = new ArrayList<>();
+
+        StringTokenizer st = new StringTokenizer(name, XML_NAME_PUNCTUATION_STRING);
+        while (st.hasMoreTokens()) {
+            words.add(st.nextToken());
+        }
+
+        for (int i = 0; i < words.size(); i++) {
+            splitWord(words, i);
+        }
+
+        return makeConventionalIdentifier(words, type);
+    }
+
+    private static void splitWord(List<String> words, int listIndex) {
+        String word = words.get(listIndex);
+        if (word.length() <= 1) {
+            return;
+        }
+        int index = listIndex + 1;
+        StringBuilder sword = new StringBuilder(word);
+        int first = 0;
+        char firstChar = sword.charAt(first);
+        if (Character.isLowerCase(firstChar)) {
+            sword.setCharAt(first, Character.toUpperCase(firstChar));
+        }
+        int i = 1;
+
+        while (i < sword.length()) {
+            if (Character.isDigit(firstChar)) {
+                while (i < sword.length() && Character.isDigit(sword.charAt(i))) {
+                    i++;
+                }
+            } else if (isCasedLetter(firstChar)) {
+                boolean previousIsLower = Character.isLowerCase(firstChar);
+                while (i < sword.length() && isCasedLetter(sword.charAt(i))) {
+                    if (Character.isUpperCase(sword.charAt(i)) && previousIsLower) {
+                        break;
+                    }
+                    previousIsLower = Character.isLowerCase(sword.charAt(i));
+                    i++;
+                }
+            } else {
+                // first must be a mark or an uncased letter
+                while (i < sword.length() && (isMark(sword.charAt(i)) || !isCasedLetter(sword.charAt(i)))) {
+                    i++;
+                }
+            }
+
+            // characters from first to i are all either
+            // * digits
+            // * upper or lower case letters, with only the first one an upper
+            // * uncased letters or marks
+
+
+            String newWord = sword.substring(first, i);
+            words.add(index, newWord);
+            index++;
+            if (i >= sword.length()) {
+                break;
+            }
+            first = i;
+            firstChar = sword.charAt(first);
+        }
+
+        if (index > (listIndex + 1)) {
+            words.remove(listIndex);
+        }
+    }
+
+    private static boolean isMark(char c) {
+        return Character.isJavaIdentifierPart(c) && !Character.isLetter(c) && !Character.isDigit(c);
+    }
+
+    private static boolean isCasedLetter(char c) {
+        return Character.isUpperCase(c) || Character.isLowerCase(c);
+    }
+
+    private static boolean isConventionalIdentifier(StringBuilder buf, IdentifierType type) {
+        if (null == buf || buf.length() == 0) {
+            return false;
+        }
+        final boolean result;
+        if (IdentifierType.CONSTANT == type) {
+            for (int i = 0; i < buf.length(); i++) {
+                if (Character.isLowerCase(buf.charAt(i))) {
+                    return false;
+                }
+            }
+            result = true;
+        } else if (IdentifierType.VARIABLE == type) {
+            result = Character.isLowerCase(buf.charAt(0));
+        } else {
+            int pos = 3;
+            if (IdentifierType.GETTER == type
+                && !(buf.length() >= pos
+                    && "get".equals(buf.subSequence(0, 3)))) {
+                return false;
+            } else if (IdentifierType.SETTER == type
+                && !(buf.length() >= pos && "set".equals(buf.subSequence(0, 3)))) {
+                return false;
+            } else {
+                pos = 0;
+            }
+            result = Character.isUpperCase(buf.charAt(pos));
+        }
+        return result;
+    }
+
+    private static String makeConventionalIdentifier(List<String> words, IdentifierType type) {
+        StringBuilder buf = new StringBuilder();
+        boolean firstWord = true;
+        if (IdentifierType.GETTER == type) {
+            buf.append("get");
+        } else if (IdentifierType.SETTER == type) {
+            buf.append("set");
+        }
+        for (String w : words) {
+            int l = buf.length();
+            if (l > 0 && IdentifierType.CONSTANT == type) {
+                buf.append('_');
+                l++;
+            }
+            buf.append(w);
+            if (IdentifierType.CONSTANT == type) {
+                for (int i = l; i < buf.length(); i++) {
+                    if (Character.isLowerCase(buf.charAt(i))) {
+                        buf.setCharAt(i, Character.toUpperCase(buf.charAt(i)));
+                    }
+                }
+            } else if (IdentifierType.VARIABLE == type) {
+                if (firstWord && Character.isUpperCase(buf.charAt(l))) {
+                    buf.setCharAt(l, Character.toLowerCase(buf.charAt(l)));
+                }
+            } else {
+                if (firstWord && Character.isLowerCase(buf.charAt(l))) {
+                    buf.setCharAt(l, Character.toUpperCase(buf.charAt(l)));
+                }
+            }
+            firstWord = false;
+        }
+        return buf.toString();
+    }
+
+    public static Class<?> getValidClass(Class<?> cls) {
+        if (cls.isEnum() || cls.isArray()) {
+            return cls;
+        }
+
+        if (cls == Object.class || cls == String.class || cls.isPrimitive() || cls.isAnnotation()
+            || "javax.xml.ws.Holder".equals(cls.getName())) {
+            return null;
+        } else if (cls.isInterface()
+            || "javax.xml.ws.wsaddressing.W3CEndpointReference".equals(cls.getName())) {
+            return cls;
+        }
+
+        Constructor<?> cons = ReflectionUtil.getDeclaredConstructor(cls);
+        if (cons == null) {
+            cons = ReflectionUtil.getConstructor(cls);
+            if (cons == null) {
+                return null;
+            }
+        }
+        return cls;
+    }
+
+    private static synchronized ClassLoader getXJCClassLoader() {
+        if (jaxbXjcLoader == null) {
+            try {
+                Class.forName("com.sun.tools.internal.xjc.api.XJC");
+                jaxbXjcLoader = ClassLoader.getSystemClassLoader();
+            } catch (Exception t2) {
+                //couldn't find either, probably cause tools.jar isn't on
+                //the classpath.   Let's see if we can find the tools jar
+                String s = SystemPropertyAction.getProperty("java.home");
+                if (!StringUtils.isEmpty(s)) {
+                    File home = new File(s);
+                    File jar = new File(home, "lib/tools.jar");
+                    if (!jar.exists()) {
+                        jar = new File(home, "../lib/tools.jar");
+                    }
+                    if (jar.exists()) {
+                        try {
+                            jaxbXjcLoader = new URLClassLoader(new URL[] {jar.toURI().toURL()});
+                            Class.forName("com.sun.tools.internal.xjc.api.XJC", false, jaxbXjcLoader);
+                        } catch (Exception e) {
+                            jaxbXjcLoader = null;
+                        }
+                    }
+                }
+            }
+        }
+        return jaxbXjcLoader;
+    }
+
+    public static Object setNamespaceMapper(Bus bus, final Map<String, String> nspref,
+                                            Marshaller marshaller) throws PropertyException {
+        ClassLoaderService classLoaderService = bus.getExtension(ClassLoaderService.class);
+        Object mapper = classLoaderService.createNamespaceWrapperInstance(marshaller.getClass(), nspref);
+        if (mapper != null) {
+            if (marshaller.getClass().getName().contains(".internal.")) {
+                marshaller.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper",
+                                       mapper);
+            } else if (marshaller.getClass().getName().contains("com.sun")) {
+                marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper",
+                                       mapper);
+            } else if (marshaller.getClass().getName().contains("eclipse")) {
+                marshaller.setProperty("eclipselink.namespace-prefix-mapper",
+                                       mapper);
+            }
+        }
+        return mapper;
+    }
+    public static BridgeWrapper createBridge(Set<Class<?>> ctxClasses,
+                                      QName qname,
+                                      Class<?> refcls,
+                                      Annotation[] anns) throws JAXBException {
+        try {
+            Class<?> cls;
+            Class<?> refClass;
+            String pkg = "com.sun.xml.bind.";
+            try {
+                cls = Class.forName("com.sun.xml.bind.api.JAXBRIContext");
+                refClass = Class.forName(pkg + "api.TypeReference");
+            } catch (ClassNotFoundException e) {
+                cls = Class.forName("com.sun.xml.internal.bind.api.JAXBRIContext", true, getXJCClassLoader());
+                pkg = "com.sun.xml.internal.bind.";
+                refClass = Class.forName(pkg + "api.TypeReference", true, getXJCClassLoader());
+            }
+            Object ref = refClass.getConstructor(QName.class,
+                                                 Type.class,
+                                                 anns.getClass()).newInstance(qname, refcls, anns);
+            List<Object> typeRefs = new ArrayList<>();
+            typeRefs.add(ref);
+            List<Class<?>> clses = new ArrayList<>(ctxClasses);
+            clses.add(refClass.getField("type").get(ref).getClass());
+            if (!refcls.isInterface()) {
+                clses.add(refcls);
+            }
+
+            Object ctx = null;
+            for (Method m : cls.getDeclaredMethods()) {
+                if ("newInstance".equals(m.getName())
+                    && m.getParameterTypes().length == 6) {
+                    ctx = m.invoke(null, clses.toArray(new Class<?>[0]),
+                                         typeRefs, null, null, true, null);
+
+                }
+            }
+
+            if (ctx == null) {
+                throw new JAXBException("No ctx found");
+            }
+
+            Object bridge = ctx.getClass().getMethod("createBridge", refClass).invoke(ctx, ref);
+            return ReflectionInvokationHandler.createProxyWrapper(bridge,
+                                                                  BridgeWrapper.class);
+        } catch (Exception ex) {
+            throw new JAXBException(ex);
+        }
+    }
+    public interface BridgeWrapper {
+
+        Object unmarshal(XMLStreamReader source, AttachmentUnmarshaller am) throws JAXBException;
+
+        Object unmarshal(InputStream source) throws JAXBException;
+
+        Object unmarshal(Node source, AttachmentUnmarshaller am) throws JAXBException;
+
+        void marshal(Object elValue, XMLStreamWriter source, AttachmentMarshaller m) throws JAXBException;
+
+        void marshal(Object elValue, StreamResult s1) throws JAXBException;
+
+        void marshal(Object elValue, Node source, AttachmentMarshaller am) throws JAXBException;
+    }
+
+
+    public static SchemaCompiler createSchemaCompiler() throws JAXBException {
+        try {
+            Class<?> cls;
+            Object sc;
+            try {
+                cls = Class.forName("com.sun.tools.xjc.api.XJC");
+                sc = cls.getMethod("createSchemaCompiler").invoke(null);
+            } catch (Throwable e) {
+                cls = Class.forName("com.sun.tools.internal.xjc.api.XJC", true, getXJCClassLoader());
+                sc = cls.getMethod("createSchemaCompiler").invoke(null);
+            }
+
+            return ReflectionInvokationHandler.createProxyWrapper(sc,
+                                                                  SchemaCompiler.class);
+        } catch (Exception ex) {
+            throw new JAXBException(ex);
+        }
+    }
+
+    public static SchemaCompiler createSchemaCompilerWithDefaultAllocator(Set<String> allocatorSet) {
+
+        try {
+            SchemaCompiler compiler = JAXBUtils.createSchemaCompiler();
+            Object allocator = ReflectionInvokationHandler
+                .createProxyWrapper(new DefaultClassNameAllocator(allocatorSet),
+                                JAXBUtils.getParamClass(compiler, "setClassNameAllocator"));
+
+            compiler.setClassNameAllocator(allocator);
+            return compiler;
+        } catch (JAXBException e1) {
+            throw new IllegalStateException("Unable to create schema compiler", e1);
+        }
+
+    }
+
+    public static void logGeneratedClassNames(Logger logger, JCodeModel codeModel) {
+        if (!logger.isLoggable(Level.FINE)) {
+            return;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        boolean first = true;
+        for (Iterator<JPackage> itr = codeModel.packages(); itr.hasNext();) {
+            JPackage package1 = itr.next();
+
+            for (Iterator<JDefinedClass> citr = package1.classes(); citr.hasNext();) {
+                if (!first) {
+                    sb.append(", ");
+                } else {
+                    first = false;
+                }
+                sb.append(citr.next().fullName());
+            }
+        }
+
+        logger.log(Level.FINE, "Created classes: " + sb.toString());
+    }
+
+    public static List<String> getGeneratedClassNames(JCodeModel codeModel) {
+        List<String> classes = new ArrayList<>();
+        for (Iterator<JPackage> itr = codeModel.packages(); itr.hasNext();) {
+            JPackage package1 = itr.next();
+
+            for (Iterator<JDefinedClass> citr = package1.classes(); citr.hasNext();) {
+                classes.add(citr.next().fullName());
+            }
+        }
+        return classes;
+    }
+    public static Object createFileCodeWriter(File f) throws JAXBException {
+        return createFileCodeWriter(f, StandardCharsets.UTF_8.name());
+    }
+    public static Object createFileCodeWriter(File f, String encoding) throws JAXBException {
+        try {
+            Class<?> cls;
+            try {
+                cls = Class.forName("com.sun.codemodel.writer.FileCodeWriter");
+            } catch (ClassNotFoundException e) {
+                cls = Class.forName("com.sun.codemodel.internal.writer.FileCodeWriter",
+                                    true, getXJCClassLoader());
+            }
+            if (encoding != null) {
+                try {
+                    return cls.getConstructor(File.class, String.class)
+                              .newInstance(f, encoding);
+                } catch (Exception ex) {
+                    // try a single argument constructor
+                }
+            }
+            return cls.getConstructor(File.class).newInstance(f);
+        } catch (Exception ex) {
+            throw new JAXBException(ex);
+        }
+    }
+
+    public static Class<?> getParamClass(SchemaCompiler sc, String method) {
+        Object o = ((ReflectionInvokationHandler)Proxy.getInvocationHandler(sc)).getTarget();
+        for (Method m : o.getClass().getMethods()) {
+            if (m.getName().equals(method) && m.getParameterTypes().length == 1) {
+                return m.getParameterTypes()[0];
+            }
+        }
+        return null;
+    }
+
+
+    public static List<DOMResult> generateJaxbSchemas(
+        JAXBContext context, final Map<String, DOMResult> builtIns) throws IOException {
+        final List<DOMResult> results = new ArrayList<>();
+
+        context.generateSchema(new SchemaOutputResolver() {
+            @Override
+            public Result createOutput(String ns, String file) throws IOException {
+                DOMResult result = new DOMResult();
+
+                if (builtIns.containsKey(ns)) {
+                    DOMResult dr = builtIns.get(ns);
+                    result.setSystemId(dr.getSystemId());
+                    results.add(dr);
+                    return result;
+                }
+                result.setSystemId(file);
+                results.add(result);
+                return result;
+            }
+        });
+        return results;
+    }
+
+    public static String getPackageNamespace(Class<?> cls) {
+        Package p = cls.getPackage();
+        if (p != null) {
+            javax.xml.bind.annotation.XmlSchema schemaAnn =
+                p.getAnnotation(javax.xml.bind.annotation.XmlSchema.class);
+            if (schemaAnn != null) {
+                return schemaAnn.namespace();
+            }
+        }
+        return null;
+    }
+
+    public static void scanPackages(Set<Class<?>> classes,
+                                    Map<Package, CachedClass> objectFactoryCache) {
+        scanPackages(classes, null, objectFactoryCache);
+    }
+    public static void scanPackages(Set<Class<?>> classes,
+                                    Class<?>[] extraClass,
+                                    Map<Package, CachedClass> objectFactoryCache) {
+
+        // add user extra class into jaxb context
+        if (extraClass != null && extraClass.length > 0) {
+            for (Class<?> clz : extraClass) {
+                classes.add(clz);
+            }
+        }
+
+        // try and read any jaxb.index files that are with the other classes.
+        // This should
+        // allow loading of extra classes (such as subclasses for inheritance
+        // reasons)
+        // that are in the same package. Also check for ObjectFactory classes
+        Map<String, InputStream> packages = new HashMap<>();
+        Map<String, ClassLoader> packageLoaders = new HashMap<>();
+        Set<Class<?>> objectFactories = new HashSet<>();
+        for (Class<?> jcls : classes) {
+            String pkgName = PackageUtils.getPackageName(jcls);
+            if (!packages.containsKey(pkgName)) {
+                Package pkg = jcls.getPackage();
+
+                packages.put(pkgName, jcls.getResourceAsStream("jaxb.index"));
+                packageLoaders.put(pkgName, getClassLoader(jcls));
+                String objectFactoryClassName = pkgName + "." + "ObjectFactory";
+                Class<?> ofactory = null;
+                CachedClass cachedFactory = null;
+                if (pkg != null && objectFactoryCache != null) {
+                    synchronized (objectFactoryCache) {
+                        cachedFactory = objectFactoryCache.get(pkg);
+                    }
+                }
+                if (cachedFactory != null) {
+                    ofactory = cachedFactory.getCachedClass();
+                }
+                if (ofactory == null) {
+                    try {
+                        ofactory = Class.forName(objectFactoryClassName, false, getClassLoader(jcls));
+                        objectFactories.add(ofactory);
+                        addToObjectFactoryCache(pkg, ofactory, objectFactoryCache);
+                    } catch (ClassNotFoundException e) {
+                        addToObjectFactoryCache(pkg, null, objectFactoryCache);
+                    }
+                } else {
+                    objectFactories.add(ofactory);
+                }
+            }
+        }
+        for (Map.Entry<String, InputStream> entry : packages.entrySet()) {
+            if (entry.getValue() != null) {
+                try (BufferedReader reader = new BufferedReader(
+                        new InputStreamReader(entry.getValue(), StandardCharsets.UTF_8))) {
+                    String pkg = entry.getKey();
+                    ClassLoader loader = packageLoaders.get(pkg);
+                    if (!StringUtils.isEmpty(pkg)) {
+                        pkg += ".";
+                    }
+
+                    String line = reader.readLine();
+                    while (line != null) {
+                        line = line.trim();
+                        if (line.indexOf('#') != -1) {
+                            line = line.substring(0, line.indexOf('#'));
+                        }
+                        if (!StringUtils.isEmpty(line)) {
+                            try {
+                                Class<?> ncls = Class.forName(pkg + line, false, loader);
+                                classes.add(ncls);
+                            } catch (Exception e) {
+                                // ignore
+                            }
+                        }
+                        line = reader.readLine();
+                    }
+                } catch (IOException e) {
+                    // ignore
+                } finally {
+                    try {
+                        entry.getValue().close();
+                    } catch (IOException e) {
+                        // ignore
+                    }
+                }
+            }
+        }
+        classes.addAll(objectFactories);
+    }
+
+    private static ClassLoader getClassLoader(final Class<?> clazz) {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                @Override
+                public ClassLoader run() {
+                    return clazz.getClassLoader();
+                }
+            });
+        }
+        return clazz.getClassLoader();
+    }
+       
+    private static void addToObjectFactoryCache(Package objectFactoryPkg, 
+                                         Class<?> ofactory,
+                                         Map<Package, CachedClass> objectFactoryCache) {
+        if (objectFactoryPkg == null || objectFactoryCache == null) {
+            return;
+        }
+        synchronized (objectFactoryCache) {
+            objectFactoryCache.put(objectFactoryPkg,
+                                     new CachedClass(ofactory));
+        }
+    }
+
+    public static class DefaultClassNameAllocator {
+        private final Set<String> typesClassNames;
+
+        public DefaultClassNameAllocator() {
+            this(new HashSet<>());
+        }
+
+        public DefaultClassNameAllocator(Set<String> set) {
+            typesClassNames = set;
+        }
+
+        public String assignClassName(String packageName, String className) {
+            String fullClassName = className;
+            String fullPckClass = packageName + "." + fullClassName;
+            int cnt = 0;
+            while (typesClassNames.contains(fullPckClass)) {
+                cnt++;
+                fullClassName = className + cnt;
+                fullPckClass = packageName + "." + fullClassName;
+            }
+            typesClassNames.add(fullPckClass);
+            return fullClassName;
+        }
+
+    }
+
+    public interface SchemaCompiler {
+        void setEntityResolver(EntityResolver entityResolver);
+
+        void setErrorListener(Object elForRun);
+
+        void setClassNameAllocator(Object allocator);
+
+        @WrapReturn(S2JJAXBModel.class)
+        S2JJAXBModel bind();
+
+        void parseSchema(InputSource source);
+
+        void parseSchema(String key, Element el);
+        void parseSchema(String key, XMLStreamReader el);
+
+        @WrapReturn(Options.class)
+        Options getOptions();
+    }
+    public interface S2JJAXBModel {
+
+        @WrapReturn(JCodeModel.class)
+        JCodeModel generateCode(Object object, Object elForRun);
+
+        @WrapReturn(Mapping.class)
+        Mapping get(QName qn);
+
+        @WrapReturn(TypeAndAnnotation.class)
+        TypeAndAnnotation getJavaType(QName typeQName);
+    }
+    public interface Mapping {
+        @WrapReturn(TypeAndAnnotation.class)
+        TypeAndAnnotation getType();
+    }
+    public interface TypeAndAnnotation {
+        @WrapReturn(JType.class)
+        JType getTypeClass();
+    }
+    public interface JType {
+        boolean isArray();
+
+        @WrapReturn(JType.class)
+        JType elementType();
+
+        boolean isPrimitive();
+
+        String binaryName();
+
+        String fullName();
+
+        String name();
+
+        @WrapReturn(value = JType.class, iterator = true)
+        Iterator<JType> classes();
+    }
+    public interface Options {
+
+        void addGrammar(InputSource is);
+
+        void addBindFile(InputSource is);
+
+        void parseArguments(String[] args);
+
+        String getBuildID();
+    }
+    public interface JCodeModel {
+
+        void build(Object writer) throws IOException;
+
+        @WrapReturn(value = JPackage.class, iterator = true)
+        Iterator<JPackage> packages();
+    }
+    public interface JPackage {
+
+        String name();
+
+        @WrapReturn(value = JDefinedClass.class, iterator = true)
+        Iterator<JDefinedClass> classes();
+    }
+    public interface JDefinedClass {
+        String name();
+
+        String fullName();
+    }
+
+    public static boolean isJAXB22() {
+        Target t = XmlElement.class.getAnnotation(Target.class);
+        //JAXB 2.2 allows XmlElement on params.
+        for (ElementType et : t.value()) {
+            if (et == ElementType.PARAMETER) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static JAXBContextProxy createJAXBContextProxy(final JAXBContext ctx) {
+        return createJAXBContextProxy(ctx, null, null);
+    }
+    public static JAXBContextProxy createJAXBContextProxy(final JAXBContext ctx,
+                                                          final SchemaCollection collection,
+                                                          final String defaultNs) {
+        if (ctx.getClass().getName().contains("com.sun.")
+            || collection == null) {
+            return ReflectionInvokationHandler.createProxyWrapper(ctx, JAXBContextProxy.class);
+        }
+        return new SchemaCollectionContextProxy(ctx, collection, defaultNs);
+    }
+    public static JAXBBeanInfo getBeanInfo(JAXBContextProxy context, Class<?> cls) {
+        Object o = context.getBeanInfo(cls);
+        if (o == null) {
+            return null;
+        }
+        if (o instanceof JAXBBeanInfo) {
+            return (JAXBBeanInfo)o;
+        }
+        return ReflectionInvokationHandler.createProxyWrapper(o, JAXBBeanInfo.class);
+    }
+
+    private static String getPostfix(Class<?> cls) {
+        String className = cls.getName();
+        if (className.contains("com.sun.xml.internal")
+            || className.contains("eclipse")) {
+            //eclipse moxy accepts sun package CharacterEscapeHandler 
+            return ".internal";
+        } else if (className.contains("com.sun.xml.bind")
+            || className.startsWith("com.ibm.xml")) {
+            return "";
+        }
+        return null;
+    }
+
+    public static void setMinimumEscapeHandler(Marshaller marshaller) {
+        if (jaxbMinimumEscapeHandler == null) {
+            jaxbMinimumEscapeHandler = Optional.ofNullable(createMininumEscapeHandler(marshaller.getClass()));
+        }
+        jaxbMinimumEscapeHandler.ifPresent(p -> setEscapeHandler(marshaller, p));
+    }
+
+    public static void setNoEscapeHandler(final Marshaller marshaller) {
+        if (jaxbNoEscapeHandler == null) {
+            jaxbNoEscapeHandler = Optional.ofNullable(createNoEscapeHandler(marshaller.getClass()));
+        }
+        jaxbNoEscapeHandler.ifPresent(p -> setEscapeHandler(marshaller, p));
+    }
+    
+    public static void setEscapeHandler(Marshaller marshaller, Object escapeHandler) {
+        try {
+            String postFix = getPostfix(marshaller.getClass());
+            if (postFix != null && escapeHandler != null) {
+                marshaller.setProperty("com.sun.xml" + postFix + ".bind.characterEscapeHandler", escapeHandler);
+            }
+        } catch (PropertyException e) {
+            LOG.log(Level.INFO, "Failed to set MinumEscapeHandler to jaxb marshaller", e);
+        }
+    }
+    
+    public static Object createMininumEscapeHandler(Class<?> cls) {
+        return createEscapeHandler(cls, "MinimumEscapeHandler");
+    }
+    
+    public static Object createNoEscapeHandler(Class<?> cls) {
+        return createEscapeHandler(cls, "NoEscapeHandler");
+    }
+    
+    private static Object createEscapeHandler(Class<?> cls, String simpleClassName) {
+        try {
+            String postFix = getPostfix(cls);
+            if (postFix == null) {
+                LOG.log(Level.WARNING, "Failed to create" + simpleClassName + " for unknown jaxb class:"
+                    + cls);
+                return null;
+            }
+            Class<?> handlerClass = ClassLoaderUtils.loadClass("com.sun.xml" + postFix
+                                                                   + ".bind.marshaller." + simpleClassName,
+                                                               cls);
+            Class<?> handlerInterface = ClassLoaderUtils
+                .loadClass("com.sun.xml" + postFix + ".bind.marshaller.CharacterEscapeHandler",
+                           cls);
+            Object targetHandler = ReflectionUtil.getDeclaredField(handlerClass, "theInstance").get(null);
+            return ProxyHelper.getProxy(cls.getClassLoader(),
+                                        new Class[] {handlerInterface},
+                                        new EscapeHandlerInvocationHandler(targetHandler));
+        } catch (Exception e) {
+            if ("NoEscapeHandler".equals(simpleClassName)) {
+                //this class doesn't exist in JAXB 2.2 so expected
+                LOG.log(Level.FINER, "Failed to create " + simpleClassName);
+            } else {
+                LOG.log(Level.INFO, "Failed to create " + simpleClassName);
+            }
+        }
+        return null;
+    }
+    
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/logging/AbstractDelegatingLogger.java b/transform/src/patch/java/org/apache/cxf/common/logging/AbstractDelegatingLogger.java
new file mode 100644
index 0000000..dd3cbd5
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/logging/AbstractDelegatingLogger.java
@@ -0,0 +1,457 @@
+/**
+ * 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.cxf.common.logging;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.logging.Filter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+/**
+ * java.util.logging.Logger implementation delegating to another framework.
+ * All methods can be used except:
+ *   setLevel
+ *   addHandler / getHandlers
+ *   setParent / getParent
+ *   setUseParentHandlers / getUseParentHandlers
+ */
+public abstract class AbstractDelegatingLogger extends Logger {
+
+    protected AbstractDelegatingLogger(String name, String resourceBundleName) {
+        super(name, resourceBundleName);
+    }
+
+    @Override
+    public void log(LogRecord record) {
+        if (isLoggable(record.getLevel())) {
+            doLog(record);
+        }
+    }
+
+    @Override
+    public void log(Level level, String msg) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void log(Level level, String msg, Object param1) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            Object[] params = {param1 };
+            lr.setParameters(params);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void log(Level level, String msg, Object[] params) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            lr.setParameters(params);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void log(Level level, String msg, Throwable thrown) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            lr.setThrown(thrown);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void logp(Level level, String sourceClass, String sourceMethod, String msg) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            lr.setSourceClassName(sourceClass);
+            lr.setSourceMethodName(sourceMethod);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void logp(Level level, String sourceClass, String sourceMethod, String msg, Object param1) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            lr.setSourceClassName(sourceClass);
+            lr.setSourceMethodName(sourceMethod);
+            Object[] params = {param1 };
+            lr.setParameters(params);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void logp(Level level, String sourceClass, String sourceMethod, String msg, Object[] params) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            lr.setSourceClassName(sourceClass);
+            lr.setSourceMethodName(sourceMethod);
+            lr.setParameters(params);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void logp(Level level, String sourceClass, String sourceMethod, String msg, Throwable thrown) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            lr.setSourceClassName(sourceClass);
+            lr.setSourceMethodName(sourceMethod);
+            lr.setThrown(thrown);
+            doLog(lr);
+        }
+    }
+
+  
+    @Override
+    @Deprecated
+    public void logrb(Level level, String sourceClass, String sourceMethod, String bundleName, String msg) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            lr.setSourceClassName(sourceClass);
+            lr.setSourceMethodName(sourceMethod);
+            doLog(lr, bundleName);
+        }
+    }
+
+   
+    @Override
+    @Deprecated
+    public void logrb(Level level, String sourceClass, String sourceMethod,
+                      String bundleName, String msg, Object param1) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            lr.setSourceClassName(sourceClass);
+            lr.setSourceMethodName(sourceMethod);
+            Object[] params = {param1 };
+            lr.setParameters(params);
+            doLog(lr, bundleName);
+        }
+    }
+
+  
+    @Override
+    @Deprecated
+    public void logrb(Level level, String sourceClass, String sourceMethod,
+                      String bundleName, String msg, Object[] params) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            lr.setSourceClassName(sourceClass);
+            lr.setSourceMethodName(sourceMethod);
+            lr.setParameters(params);
+            doLog(lr, bundleName);
+        }
+    }
+
+    @Override
+    @Deprecated
+    public void logrb(Level level, String sourceClass, String sourceMethod,
+                      String bundleName, String msg, Throwable thrown) {
+        if (isLoggable(level)) {
+            LogRecord lr = new LogRecord(level, msg);
+            lr.setSourceClassName(sourceClass);
+            lr.setSourceMethodName(sourceMethod);
+            lr.setThrown(thrown);
+            doLog(lr, bundleName);
+        }
+    }
+
+    @Override
+    public void entering(String sourceClass, String sourceMethod) {
+        if (isLoggable(Level.FINER)) {
+            logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
+        }
+    }
+
+    @Override
+    public void entering(String sourceClass, String sourceMethod, Object param1) {
+        if (isLoggable(Level.FINER)) {
+            Object[] params = {param1 };
+            logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", params);
+        }
+    }
+
+    @Override
+    public void entering(String sourceClass, String sourceMethod, Object[] params) {
+        if (isLoggable(Level.FINER)) {
+            String msg = "ENTRY";
+            if (params == null) {
+                logp(Level.FINER, sourceClass, sourceMethod, msg);
+                return;
+            }
+            StringBuilder builder = new StringBuilder(msg);
+            for (int i = 0; i < params.length; i++) {
+                builder.append(" {");
+                builder.append(Integer.toString(i));
+                builder.append('}');
+            }
+            logp(Level.FINER, sourceClass, sourceMethod, builder.toString(), params);
+        }
+    }
+
+    @Override
+    public void exiting(String sourceClass, String sourceMethod) {
+        if (isLoggable(Level.FINER)) {
+            logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
+        }
+    }
+
+    @Override
+    public void exiting(String sourceClass, String sourceMethod, Object result) {
+        if (isLoggable(Level.FINER)) {
+            Object[] params = {result };
+            logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", params);
+        }
+    }
+
+    @Override
+    public void throwing(String sourceClass, String sourceMethod, Throwable thrown) {
+        if (isLoggable(Level.FINER)) {
+            LogRecord lr = new LogRecord(Level.FINER, "THROW");
+            lr.setSourceClassName(sourceClass);
+            lr.setSourceMethodName(sourceMethod);
+            lr.setThrown(thrown);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void severe(String msg) {
+        if (isLoggable(Level.SEVERE)) {
+            LogRecord lr = new LogRecord(Level.SEVERE, msg);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void warning(String msg) {
+        if (isLoggable(Level.WARNING)) {
+            LogRecord lr = new LogRecord(Level.WARNING, msg);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void info(String msg) {
+        if (isLoggable(Level.INFO)) {
+            LogRecord lr = new LogRecord(Level.INFO, msg);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void config(String msg) {
+        if (isLoggable(Level.CONFIG)) {
+            LogRecord lr = new LogRecord(Level.CONFIG, msg);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void fine(String msg) {
+        if (isLoggable(Level.FINE)) {
+            LogRecord lr = new LogRecord(Level.FINE, msg);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void finer(String msg) {
+        if (isLoggable(Level.FINER)) {
+            LogRecord lr = new LogRecord(Level.FINER, msg);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void finest(String msg) {
+        if (isLoggable(Level.FINEST)) {
+            LogRecord lr = new LogRecord(Level.FINEST, msg);
+            doLog(lr);
+        }
+    }
+
+    @Override
+    public void setLevel(Level newLevel) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public abstract Level getLevel();
+
+    @Override
+    public boolean isLoggable(Level level) {
+        Level l = getLevel();
+        return level.intValue() >= l.intValue() && l != Level.OFF;
+    }
+
+    protected boolean supportsHandlers() {
+        return false;
+    }
+
+    @Override
+    public synchronized void addHandler(Handler handler) {
+        if (supportsHandlers()) {
+            super.addHandler(handler);
+            return;
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public synchronized void removeHandler(Handler handler) {
+        if (supportsHandlers()) {
+            super.removeHandler(handler);
+            return;
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public synchronized Handler[] getHandlers() {
+        if (supportsHandlers()) {
+            return super.getHandlers();
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public synchronized void setUseParentHandlers(boolean useParentHandlers) {
+        if (supportsHandlers()) {
+            super.setUseParentHandlers(useParentHandlers);
+            return;
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public synchronized boolean getUseParentHandlers() {
+        if (supportsHandlers()) {
+            return super.getUseParentHandlers();
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Logger getParent() {
+        return null;
+    }
+
+    @Override
+    public void setParent(Logger parent) {
+        throw new UnsupportedOperationException();
+    }
+
+    protected void doLog(LogRecord lr) {
+        lr.setLoggerName(getName());
+        String rbname = getResourceBundleName();
+        if (rbname != null) {
+            lr.setResourceBundleName(rbname);
+            lr.setResourceBundle(getResourceBundle());
+        }
+        internalLog(lr);
+    }
+
+    protected void doLog(LogRecord lr, String rbname) {
+        lr.setLoggerName(getName());
+        if (rbname != null) {
+            lr.setResourceBundleName(rbname);
+            lr.setResourceBundle(loadResourceBundle(rbname));
+        }
+        internalLog(lr);
+    }
+
+    protected void internalLog(LogRecord record) {
+        Filter filter = getFilter();
+        if (filter != null && !filter.isLoggable(record)) {
+            return;
+        }
+        String msg = formatMessage(record);
+        internalLogFormatted(msg, record);
+    }
+
+    protected abstract void internalLogFormatted(String msg, LogRecord record);
+
+    protected String formatMessage(LogRecord record) {
+        String format = record.getMessage();
+        ResourceBundle catalog = record.getResourceBundle();
+        if (catalog != null) {
+            try {
+                format = catalog.getString(record.getMessage());
+            } catch (MissingResourceException ex) {
+                format = record.getMessage();
+            }
+        }
+        try {
+            Object[] parameters = record.getParameters();
+            if (parameters == null || parameters.length == 0) {
+                return format;
+            }
+            if (format.indexOf("{0") >= 0 || format.indexOf("{1") >= 0
+                        || format.indexOf("{2") >= 0 || format.indexOf("{3") >= 0) {
+                return java.text.MessageFormat.format(format, parameters);
+            }
+            return format;
+        } catch (Exception ex) {
+            return format;
+        }
+    }
+
+    /**
+     * Load the specified resource bundle
+     *
+     * @param resourceBundleName
+     *            the name of the resource bundle to load, cannot be null
+     * @return the loaded resource bundle.
+     * @throws java.util.MissingResourceException
+     *             If the specified resource bundle can not be loaded.
+     */
+    static ResourceBundle loadResourceBundle(String resourceBundleName) {
+        // try context class loader to load the resource
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if (null != cl) {
+            try {
+                return ResourceBundle.getBundle(resourceBundleName, Locale.getDefault(), cl);
+            } catch (MissingResourceException e) {
+                // Failed to load using context classloader, ignore
+            }
+        }
+        // try system class loader to load the resource
+        cl = ClassLoader.getSystemClassLoader();
+        if (null != cl) {
+            try {
+                return ResourceBundle.getBundle(resourceBundleName, Locale.getDefault(), cl);
+            } catch (MissingResourceException e) {
+                // Failed to load using system classloader, ignore
+            }
+        }
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/transform/src/patch/java/org/apache/cxf/common/logging/LogUtils.java b/transform/src/patch/java/org/apache/cxf/common/logging/LogUtils.java
new file mode 100644
index 0000000..09727e6
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/logging/LogUtils.java
@@ -0,0 +1,485 @@
+/**
+ * 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.cxf.common.logging;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.i18n.BundleUtils;
+import org.apache.cxf.common.util.StringUtils;
+
+
+/**
+ * A container for static utility methods related to logging.
+ * By default, CXF logs to java.util.logging. An application can change this. To log to another system, the
+ * application must provide an object that extends {@link AbstractDelegatingLogger}, and advertise that class
+ * via one of the following mechanisms:
+ * <ul>
+ * <li>Create a file, in the classpath, named META-INF/cxf/org.apache.cxf.Logger.
+ * This file should contain the fully-qualified name
+ * of the class, with no comments, on a single line.</li>
+ * <li>Call {@link #setLoggerClass(Class)} with a Class<?> reference to the logger class.</li>
+ * </ul>
+ * CXF provides {@link Slf4jLogger} to use slf4j instead of java.util.logging.
+ */
+public final class LogUtils {
+    private static final String KEY = "org.apache.cxf.Logger";
+
+    private static final Object[] NO_PARAMETERS = new Object[0];
+
+
+    private static Class<?> loggerClass;
+
+    /**
+     * Prevents instantiation.
+     */
+    private LogUtils() {
+    }
+
+    static {
+        JDKBugHacks.doHacks();
+
+        try {
+
+            String cname = null;
+            try {
+                cname = AccessController.doPrivileged(new PrivilegedAction<String>() {
+                    public String run() {
+                        return System.getProperty(KEY);
+                    }
+                });
+            } catch (Throwable t) {
+                //ignore - likely security exception or similar that won't allow
+                //access to the system properties.   We'll continue with other methods
+            }
+            if (StringUtils.isEmpty(cname)) {
+                InputStream ins = Thread.currentThread().getContextClassLoader()
+                    .getResourceAsStream("META-INF/cxf/" + KEY);
+                if (ins == null) {
+                    ins = ClassLoader.getSystemResourceAsStream("META-INF/cxf/" + KEY);
+                }
+                if (ins != null) {
+                    try (BufferedReader din = new BufferedReader(new InputStreamReader(ins))) {
+                        cname = din.readLine();
+                    }
+                }
+            }
+            if (StringUtils.isEmpty(cname)) {
+                try {
+                    // This Class.forName likely will barf in OSGi, but it's OK
+                    // as we'll just use j.u.l and pax-logging will pick it up fine
+                    // If we don't call this and there isn't a slf4j impl avail,
+                    // you get warnings printed to stderr about NOPLoggers and such
+                    Class.forName("org.slf4j.impl.StaticLoggerBinder");
+                    Class<?> cls = Class.forName("org.slf4j.LoggerFactory");
+                    Class<?> fcls = cls.getMethod("getILoggerFactory").invoke(null).getClass();
+                    String clsName = fcls.getName();
+                    if (clsName.contains("NOPLogger")) {
+                        //no real slf4j implementation, use j.u.l
+                        cname = null;
+                    } else if (clsName.contains("JDK14")
+                        || clsName.contains("pax.logging")) {
+                        //both of these we can use the appropriate j.u.l API's
+                        //directly and have it work properly
+                        cname = null;
+                    } else {
+                        // Either we cannot really detect where it's logging
+                        // or we don't want to use a custom logger, so we'll
+                        // go ahead and use the Slf4jLogger directly
+                        cname = "org.apache.cxf.common.logging.Slf4jLogger";
+                    }
+                } catch (Throwable t) {
+                    //ignore - Slf4j not available
+                }
+            }
+            if (!StringUtils.isEmpty(cname)) {
+                try {
+                    loggerClass = Class.forName(cname.trim(), true,
+                                                Thread.currentThread().getContextClassLoader());
+                } catch (Throwable ex) {
+                    loggerClass = Class.forName(cname.trim());
+                }
+                getLogger(LogUtils.class).fine("Using " + loggerClass.getName() + " for logging.");
+            }
+        } catch (Throwable ex) {
+            //ignore - if we get here, some issue prevented the logger class from being loaded.
+            //maybe a ClassNotFound or NoClassDefFound or similar.   Just use j.u.l
+            loggerClass = null;
+        }
+    }
+
+
+    /**
+     * Specify a logger class that inherits from {@link AbstractDelegatingLogger}.
+     * Enable users to use their own logger implementation.
+     */
+    public static void setLoggerClass(Class<? extends AbstractDelegatingLogger> cls) {
+        loggerClass = cls;
+    }
+
+
+    /**
+     * Get a Logger with the associated default resource bundle for the class.
+     *
+     * @param cls the Class to contain the Logger
+     * @return an appropriate Logger
+     */
+    public static Logger getLogger(Class<?> cls) {
+        return createLogger(cls, null, cls.getName());
+    }
+
+    /**
+     * Get a Logger with an associated resource bundle.
+     *
+     * @param cls the Class to contain the Logger
+     * @param resourcename the resource name
+     * @return an appropriate Logger
+     */
+    public static Logger getLogger(Class<?> cls, String resourcename) {
+        return createLogger(cls, resourcename, cls.getName());
+    }
+
+    /**
+     * Get a Logger with an associated resource bundle.
+     *
+     * @param cls the Class to contain the Logger (to find resources)
+     * @param resourcename the resource name
+     * @param loggerName the full name for the logger
+     * @return an appropriate Logger
+     */
+    public static Logger getLogger(Class<?> cls,
+                                     String resourcename,
+                                     String loggerName) {
+        return createLogger(cls, resourcename, loggerName);
+    }
+
+    /**
+     * Get a Logger with the associated default resource bundle for the class.
+     *
+     * @param cls the Class to contain the Logger
+     * @return an appropriate Logger
+     */
+    public static Logger getL7dLogger(Class<?> cls) {
+        return createLogger(cls, null, cls.getName());
+    }
+
+    /**
+     * Get a Logger with an associated resource bundle.
+     *
+     * @param cls the Class to contain the Logger
+     * @param resourcename the resource name
+     * @return an appropriate Logger
+     */
+    public static Logger getL7dLogger(Class<?> cls, String resourcename) {
+        return createLogger(cls, resourcename, cls.getName());
+    }
+
+    /**
+     * Get a Logger with an associated resource bundle.
+     *
+     * @param cls the Class to contain the Logger (to find resources)
+     * @param resourcename the resource name
+     * @param loggerName the full name for the logger
+     * @return an appropriate Logger
+     */
+    public static Logger getL7dLogger(Class<?> cls,
+                                      String resourcename,
+                                      String loggerName) {
+        return createLogger(cls, resourcename, loggerName);
+    }
+
+    /**
+     * Create a logger
+     */
+    protected static Logger createLogger(Class<?> cls,
+                                         String name,
+                                         String loggerName) {
+        ClassLoader orig = getContextClassLoader();
+        ClassLoader n = getClassLoader(cls);
+        if (n != null) {
+            setContextClassLoader(n);
+        }
+        String bundleName = name;
+        try {
+            ResourceBundle b = null;
+            if (bundleName == null) {
+                //grab the bundle prior to the call to Logger.getLogger(...) so the
+                //ResourceBundle can be loaded outside the big sync block that getLogger really is
+                bundleName = BundleUtils.getBundleName(cls);
+                try {
+                    b = BundleUtils.getBundle(cls);
+                } catch (MissingResourceException rex) {
+                    //ignore
+                }
+            } else {
+                bundleName = BundleUtils.getBundleName(cls, bundleName);
+                try {
+                    b = BundleUtils.getBundle(cls, bundleName);
+                } catch (MissingResourceException rex) {
+                    //ignore
+                }
+            }
+            if (b != null) {
+                b.getLocale();
+            }
+
+            if (loggerClass != null) {
+                try {
+                    Constructor<?> cns = loggerClass.getConstructor(String.class, String.class);
+                    if (name == null) {
+                        try {
+                            return (Logger) cns.newInstance(loggerName, bundleName);
+                        } catch (InvocationTargetException ite) {
+                            if (ite.getTargetException() instanceof MissingResourceException) {
+                                return (Logger) cns.newInstance(loggerName, null);
+                            }
+                            throw ite;
+                        }
+                    }
+                    try {
+                        return (Logger) cns.newInstance(loggerName, bundleName);
+                    } catch (InvocationTargetException ite) {
+                        if (ite.getTargetException() instanceof MissingResourceException) {
+                            throw (MissingResourceException)ite.getTargetException();
+                        }
+                        throw ite;
+                    }
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+
+            Logger logger;
+            try {
+                logger = Logger.getLogger(loggerName, bundleName); //NOPMD
+            } catch (IllegalArgumentException | MissingResourceException ex) {
+                //likely a mismatch on the bundle name, just return the default
+                logger = Logger.getLogger(loggerName); //NOPMD
+            }
+            
+            return logger;
+        } finally {
+            if (n != orig) {
+                setContextClassLoader(orig);
+            }
+        }
+    }
+
+    private static void setContextClassLoader(final ClassLoader classLoader) {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                public Object run() {
+                    Thread.currentThread().setContextClassLoader(classLoader);
+                    return null;
+                }
+            });
+        } else {
+            Thread.currentThread().setContextClassLoader(classLoader);
+        }
+    }
+
+    private static ClassLoader getContextClassLoader() {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return Thread.currentThread().getContextClassLoader();
+                }
+            });
+        }
+        return Thread.currentThread().getContextClassLoader();
+    }
+
+    private static ClassLoader getClassLoader(final Class<?> clazz) {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return clazz.getClassLoader();
+                }
+            });
+        }
+        return clazz.getClassLoader();
+    }
+
+    /**
+     * Allows both parameter substitution and a typed Throwable to be logged.
+     *
+     * @param logger the Logger the log to
+     * @param level the severity level
+     * @param message the log message
+     * @param throwable the Throwable to log
+     * @param parameter the parameter to substitute into message
+     */
+    public static void log(Logger logger,
+                           Level level,
+                           String message,
+                           Throwable throwable,
+                           Object parameter) {
+        if (logger.isLoggable(level)) {
+            final String formattedMessage =
+                MessageFormat.format(localize(logger, message), parameter);
+            doLog(logger, level, formattedMessage, throwable);
+        }
+    }
+
+    /**
+     * Allows both parameter substitution and a typed Throwable to be logged.
+     *
+     * @param logger the Logger the log to
+     * @param level the severity level
+     * @param message the log message
+     * @param throwable the Throwable to log
+     * @param parameters the parameters to substitute into message
+     */
+    public static void log(Logger logger,
+                           Level level,
+                           String message,
+                           Throwable throwable,
+                           Object... parameters) {
+        if (logger.isLoggable(level)) {
+            final String formattedMessage =
+                MessageFormat.format(localize(logger, message), parameters);
+            doLog(logger, level, formattedMessage, throwable);
+        }
+    }
+
+    /**
+     * Checks log level and logs
+     *
+     * @param logger the Logger the log to
+     * @param level the severity level
+     * @param message the log message
+     */
+    public static void log(Logger logger,
+                           Level level,
+                           String message) {
+        log(logger, level, message, NO_PARAMETERS);
+    }
+
+    /**
+     * Checks log level and logs
+     *
+     * @param logger the Logger the log to
+     * @param level the severity level
+     * @param message the log message
+     * @param throwable the Throwable to log
+     */
+    public static void log(Logger logger,
+                           Level level,
+                           String message,
+                           Throwable throwable) {
+        log(logger, level, message, throwable, NO_PARAMETERS);
+    }
+
+    /**
+     * Checks log level and logs
+     *
+     * @param logger the Logger the log to
+     * @param level the severity level
+     * @param message the log message
+     * @param parameter the parameter to substitute into message
+     */
+    public static void log(Logger logger,
+                           Level level,
+                           String message,
+                           Object parameter) {
+        log(logger, level, message, new Object[] {parameter});
+    }
+
+    /**
+     * Checks log level and logs
+     *
+     * @param logger the Logger the log to
+     * @param level the severity level
+     * @param message the log message
+     * @param parameters the parameters to substitute into message
+     */
+    public static void log(Logger logger,
+                           Level level,
+                           String message,
+                           Object[] parameters) {
+        if (logger.isLoggable(level)) {
+            String msg = localize(logger, message);
+            try {
+                msg = MessageFormat.format(msg, parameters);
+            } catch (IllegalArgumentException ex) {
+                //ignore, log as is
+            }
+            doLog(logger, level, msg, null);
+        }
+    }
+
+    private static void doLog(Logger log, Level level, String msg, Throwable t) {
+        LogRecord record = new LogRecord(level, msg);
+
+        record.setLoggerName(log.getName());
+        record.setResourceBundleName(log.getResourceBundleName());
+        record.setResourceBundle(log.getResourceBundle());
+
+        if (t != null) {
+            record.setThrown(t);
+        }
+
+        //try to get the right class name/method name - just trace
+        //back the stack till we get out of this class
+        StackTraceElement[] stack = (new Throwable()).getStackTrace();
+        String cname = LogUtils.class.getName();
+        for (int x = 0; x < stack.length; x++) {
+            StackTraceElement frame = stack[x];
+            if (!frame.getClassName().equals(cname)) {
+                record.setSourceClassName(frame.getClassName());
+                record.setSourceMethodName(frame.getMethodName());
+                break;
+            }
+        }
+        log.log(record);
+    }
+
+    /**
+     * Retrieve localized message retrieved from a logger's resource
+     * bundle.
+     *
+     * @param logger the Logger
+     * @param message the message to be localized
+     */
+    private static String localize(Logger logger, String message) {
+        ResourceBundle bundle = logger.getResourceBundle();
+        try {
+            return bundle != null ? bundle.getString(message) : message;
+        } catch (MissingResourceException ex) {
+            //string not in the bundle
+            return message;
+        }
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/logging/RegexLoggingFilter.java b/transform/src/patch/java/org/apache/cxf/common/logging/RegexLoggingFilter.java
new file mode 100644
index 0000000..83178b9
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/logging/RegexLoggingFilter.java
@@ -0,0 +1,117 @@
+/**
+ * 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.cxf.common.logging;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class RegexLoggingFilter {
+
+    public static final String DEFAULT_REPLACEMENT = "*****";
+
+    private static class ReplaceRegEx {
+        private final Pattern pattern;
+        private final int group;
+        private final String replacement;
+
+        ReplaceRegEx(String pattern, int group, String replacement) {
+            this.pattern = Pattern.compile(pattern);
+            this.group = group;
+            this.replacement = replacement;
+        }
+
+        public CharSequence filter(CharSequence command) {
+            Matcher m = pattern.matcher(command);
+            int offset = 0;
+            while (m.find()) {
+                int origLen = command.length();
+                command = new StringBuilder(command)
+                    .replace(m.start(group) + offset, m.end(group) + offset, replacement).toString();
+                offset += command.length() - origLen;
+            }
+            return command;
+        }
+    }
+
+    private String regPattern;
+    private int regGroup = 1;
+    private String regReplacement = DEFAULT_REPLACEMENT;
+
+    private List<ReplaceRegEx> regexs = new ArrayList<>();
+
+    public CharSequence filter(CharSequence command) {
+        if (regPattern != null) {
+            command = new ReplaceRegEx(regPattern, regGroup, regReplacement).filter(command);
+        }
+        for (ReplaceRegEx regex : regexs) {
+            command = regex.filter(command);
+        }
+        return command;
+    }
+
+    public void addRegEx(String pattern) {
+        addRegEx(pattern, 1);
+    }
+
+    public void addRegEx(String pattern, int group) {
+        addRegEx(pattern, group, DEFAULT_REPLACEMENT);
+    }
+
+    public void addRegEx(String pattern, int group, String replacement) {
+        regexs.add(new ReplaceRegEx(pattern, group, replacement));
+    }
+
+    public void addCommandOption(String option, String... commands) {
+        StringBuilder pattern = new StringBuilder("(");
+        for (String command : commands) {
+            if (pattern.length() > 1) {
+                pattern.append('|');
+            }
+            pattern.append(Pattern.quote(command));
+        }
+        pattern.append(") +.*?").append(Pattern.quote(option)).append(" +([^ ]+)");
+        regexs.add(new ReplaceRegEx(pattern.toString(), 2, DEFAULT_REPLACEMENT));
+    }
+
+    public String getPattern() {
+        return regPattern;
+    }
+
+    public void setPattern(String pattern) {
+        this.regPattern = pattern;
+    }
+
+    public String getReplacement() {
+        return regReplacement;
+    }
+
+    public void setReplacement(String replacement) {
+        this.regReplacement = replacement;
+    }
+
+    public int getGroup() {
+        return regGroup;
+    }
+
+    public void setGroup(int group) {
+        this.regGroup = group;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/spi/ClassGeneratorClassLoader.java b/transform/src/patch/java/org/apache/cxf/common/spi/ClassGeneratorClassLoader.java
new file mode 100644
index 0000000..5906c7a
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/spi/ClassGeneratorClassLoader.java
@@ -0,0 +1,153 @@
+/**
+ * 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.cxf.common.spi;
+
+import java.lang.ref.WeakReference;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.common.util.WeakIdentityHashMap;
+
+/** Class loader used to store and retrieve class generated during runtime to avoid class generation each time.
+ *  inherited class use asmHelper to generate bytes and use @see #loadClass(String, Class&lt;?&gt;, byte[])
+ *  or @see #loadClass(String, ClassLoader, byte[]) to store generated class.Class can be generated during buildtime.
+ *  equivalent class is @see org.apache.cxf.common.spi.GeneratedClassClassLoader
+ * @author olivier dufour
+ */
+public class ClassGeneratorClassLoader {
+    protected static final Map<Class<?>, WeakReference<TypeHelperClassLoader>> CLASS_MAP
+            = new WeakIdentityHashMap<>();
+    protected static final Map<ClassLoader, WeakReference<TypeHelperClassLoader>> LOADER_MAP
+            = new WeakIdentityHashMap<>();
+    protected final Bus bus;
+
+    public ClassGeneratorClassLoader(final Bus bus) {
+        this.bus = bus == null ? BusFactory.getDefaultBus() : bus;
+    }
+
+    protected Class<?> loadClass(String className, Class<?> cls, byte[] bytes) {
+        GeneratedClassClassLoaderCapture capture = bus.getExtension(GeneratedClassClassLoaderCapture.class);
+        if (capture != null) {
+            capture.capture(className, bytes);
+        }
+        TypeHelperClassLoader loader = getOrCreateLoader(cls);
+        synchronized (loader) {
+            Class<?> clz = loader.lookupDefinedClass(className);
+            if (clz == null) {
+                return loader.defineClass(className, bytes);
+            }
+            return clz;
+        }
+    }
+    protected Class<?> loadClass(String className, ClassLoader l, byte[] bytes) {
+        GeneratedClassClassLoaderCapture capture = bus.getExtension(GeneratedClassClassLoaderCapture.class);
+        if (capture != null) {
+            capture.capture(className, bytes);
+        }
+        TypeHelperClassLoader loader = getOrCreateLoader(l);
+        synchronized (loader) {
+            Class<?> clz = loader.lookupDefinedClass(className);
+            if (clz == null) {
+                return loader.defineClass(className, bytes);
+            }
+            return clz;
+        }
+    }
+    protected Class<?> findClass(String className, Class<?> cls) {
+        return getOrCreateLoader(cls).lookupDefinedClass(className);
+    }
+
+    protected Class<?> findClass(String className, ClassLoader classLoader) {
+        return getOrCreateLoader(classLoader).lookupDefinedClass(className);
+    }
+    
+    private static synchronized TypeHelperClassLoader getOrCreateLoader(Class<?> cls) {
+        WeakReference<TypeHelperClassLoader> ref = CLASS_MAP.get(cls);
+        TypeHelperClassLoader ret;
+        if (ref == null || ref.get() == null) {
+            ret = new TypeHelperClassLoader(cls.getClassLoader());
+            CLASS_MAP.put(cls, new WeakReference<>(ret));
+        } else {
+            ret = ref.get();
+        }
+        return ret;
+    }
+    
+    private static synchronized TypeHelperClassLoader getOrCreateLoader(ClassLoader l) {
+        WeakReference<TypeHelperClassLoader> ref = LOADER_MAP.get(l);
+        TypeHelperClassLoader ret;
+        if (ref == null || ref.get() == null) {
+            ret = new TypeHelperClassLoader(l);
+            LOADER_MAP.put(l, new WeakReference<>(ret));
+        } else {
+            ret = ref.get();
+        }
+        return ret;
+    }
+
+    public static class TypeHelperClassLoader extends ClassLoader {
+        private final ConcurrentHashMap<String, Class<?>> defined = new ConcurrentHashMap<>();
+
+        TypeHelperClassLoader(ClassLoader parent) {
+            super(parent);
+        }
+        
+        public Class<?> lookupDefinedClass(String name) {
+            return defined.get(StringUtils.slashesToPeriod(name));
+        }
+
+        @Override
+        protected Class<?> findClass(String name) throws ClassNotFoundException {
+            if (name.endsWith("package-info")) {
+                return getParent().loadClass(name);
+            }
+            return super.findClass(name);
+        }
+
+        public Class<?> defineClass(String name, byte[] bytes) {
+            Class<?> ret = defined.get(StringUtils.slashesToPeriod(name));
+            if (ret != null) {
+                return ret;
+            }
+            if (name.endsWith("package-info")) {
+                String s = name.substring(0, name.length() - 13);
+                Package p = super.getPackage(s);
+                if (p == null) {
+                    definePackage(StringUtils.slashesToPeriod(s),
+                            null,
+                            null,
+                            null,
+                            null,
+                            null,
+                            null,
+                            null);
+                }
+            }
+
+            ret = defined.computeIfAbsent(StringUtils.slashesToPeriod(name),
+                key -> TypeHelperClassLoader.super.defineClass(key, bytes, 0, bytes.length));
+
+            return ret;
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/spi/NamespaceClassGenerator.java b/transform/src/patch/java/org/apache/cxf/common/spi/NamespaceClassGenerator.java
new file mode 100644
index 0000000..48c755b
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/spi/NamespaceClassGenerator.java
@@ -0,0 +1,450 @@
+/**
+ * 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.cxf.common.spi;
+
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+
+public class NamespaceClassGenerator extends ClassGeneratorClassLoader implements NamespaceClassCreator {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(ClassGeneratorClassLoader.class);
+    private final ASMHelper helper;
+
+    public NamespaceClassGenerator(Bus bus) {
+        super(bus);
+        helper = bus.getExtension(ASMHelper.class);
+    }
+
+    @Override
+    public synchronized Class<?> createNamespaceWrapperClass(Class<?> mcls, Map<String, String> map) {
+        String postFix = "";
+
+        if (mcls.getName().contains("eclipse")) {
+            return createEclipseNamespaceMapper();
+        } else if (mcls.getName().contains(".internal")) {
+            postFix = "Internal";
+        } else if (mcls.getName().contains("com.sun")) {
+            postFix = "RI";
+        }
+
+        String className = "org.apache.cxf.jaxb.NamespaceMapper";
+        className += postFix;
+        Class<?> cls = findClass(className, NamespaceClassCreator.class);
+        Throwable t = null;
+        if (cls == null) {
+            try {
+                byte[] bts = createNamespaceWrapperInternal(postFix);
+                className = "org.apache.cxf.jaxb.NamespaceMapper" + postFix;
+                return loadClass(className, NamespaceClassCreator.class, bts);
+            } catch (RuntimeException ex) {
+                // continue
+                t = ex;
+            }
+        }
+        if (cls == null
+                && (!mcls.getName().contains(".internal.") && mcls.getName().contains("com.sun"))) {
+            try {
+                cls = ClassLoaderUtils.loadClass("org.apache.cxf.common.jaxb.NamespaceMapper",
+                        NamespaceClassCreator.class);
+            } catch (Throwable ex2) {
+                // ignore
+                t = ex2;
+            }
+        }
+        LOG.log(Level.INFO, "Could not create a NamespaceMapper compatible with Marshaller class " + mcls.getName(), t);
+        return cls;
+    }
+
+    private Class<?> createEclipseNamespaceMapper() {
+        String className = "org.apache.cxf.jaxb.EclipseNamespaceMapper";
+        Class<?> cls = findClass(className, NamespaceClassCreator.class);
+        if (cls != null) {
+            return cls;
+        }
+        byte[] bts = doCreateEclipseNamespaceMapper();
+        //previous code use mcls instead of NamespaceClassGenerator.class
+        return loadClass(className, NamespaceClassCreator.class, bts);
+    }
+
+    /*
+    // This is the "prototype" for the ASM generated class below
+    public static class MapNamespacePrefixMapper2
+        extends org.eclipse.persistence.internal.oxm.record.namespaces.MapNamespacePrefixMapper {
+
+        String[] nsctxt;
+
+        public MapNamespacePrefixMapper2(Map<String, String> foo) {
+            super(foo);
+        }
+        public String[] getPreDeclaredNamespaceUris() {
+            String[] sup = super.getPreDeclaredNamespaceUris();
+            if (nsctxt == null) {
+                return sup;
+            }
+            List<String> s = new ArrayList<>(Arrays.asList(sup));
+            for (int x = 1; x < nsctxt.length; x = x + 2) {
+                s.remove(nsctxt[x]);
+            }
+            return s.toArray(new String[s.size()]);
+        }
+        public void setContextualNamespaceDecls(String[] f) {
+            nsctxt = f;
+        }
+        public String[] getContextualNamespaceDecls() {
+            return nsctxt;
+        }
+    }
+    */
+    //CHECKSTYLE:OFF
+    //bunch of really long ASM based methods that cannot be shortened easily
+    private byte[] doCreateEclipseNamespaceMapper() {
+        OpcodesProxy Opcodes = helper.getOpCodes();
+        String slashedName = "org/apache/cxf/jaxb/EclipseNamespaceMapper";
+        ASMHelper.ClassWriter cw = helper.createClassWriter();
+        if (cw == null) {
+            return null;
+        }
+        String superName = "org/eclipse/persistence/internal/oxm/record/namespaces/MapNamespacePrefixMapper";
+        ASMHelper.FieldVisitor fv;
+        ASMHelper.MethodVisitor mv;
+        cw.visit(Opcodes.V1_6,
+                Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
+                slashedName, null,
+                superName, null);
+
+        cw.visitSource("EclipseNamespaceMapper.java", null);
+
+        fv = cw.visitField(Opcodes.ACC_PRIVATE, "nsctxt", "[Ljava/lang/String;", null, null);
+        fv.visitEnd();
+
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Ljava/util/Map;)V",
+                "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
+        mv.visitCode();
+        ASMHelper.Label l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
+                superName, "<init>", "(Ljava/util/Map;)V", false);
+        ASMHelper.Label l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitInsn(Opcodes.RETURN);
+        ASMHelper.Label l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setContextualNamespaceDecls", "([Ljava/lang/String;)V",
+                null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(47, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitFieldInsn(Opcodes.PUTFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(48, l1);
+        mv.visitInsn(Opcodes.RETURN);
+        l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLocalVariable("this", "L" + slashedName + ";", null, l0, l2, 0);
+        mv.visitLocalVariable("contextualNamespaceDecls", "[Ljava/lang/String;", null, l0, l2, 1);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getContextualNamespaceDecls", "()[Ljava/lang/String;", null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(51, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+        mv.visitInsn(Opcodes.ARETURN);
+        l1 = helper.createLabel();
+
+        mv.visitLabel(l1);
+        mv.visitLocalVariable("this", "L" + slashedName + ";", null, l0, l1, 0);
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getPreDeclaredNamespaceUris", "()[Ljava/lang/String;", null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(1036, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
+                superName,
+                "getPreDeclaredNamespaceUris", "()[Ljava/lang/String;", false);
+        mv.visitVarInsn(Opcodes.ASTORE, 1);
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(1037, l1);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+        l2 = helper.createLabel();
+        mv.visitJumpInsn(Opcodes.IFNONNULL, l2);
+        ASMHelper.Label l3 = helper.createLabel();
+        mv.visitLabel(l3);
+        mv.visitLineNumber(1038, l3);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitInsn(Opcodes.ARETURN);
+        mv.visitLabel(l2);
+        mv.visitLineNumber(1040, l2);
+        mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"[Ljava/lang/String;"}, 0, null);
+        mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
+        mv.visitInsn(Opcodes.DUP);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/Arrays", "asList",
+                "([Ljava/lang/Object;)Ljava/util/List;", false);
+        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>",
+                "(Ljava/util/Collection;)V", false);
+        mv.visitVarInsn(Opcodes.ASTORE, 2);
+        ASMHelper.Label l4 = helper.createLabel();
+        mv.visitLabel(l4);
+        mv.visitLineNumber(1041, l4);
+        mv.visitInsn(Opcodes.ICONST_1);
+        mv.visitVarInsn(Opcodes.ISTORE, 3);
+        ASMHelper.Label l5 = helper.createLabel();
+        mv.visitLabel(l5);
+        ASMHelper.Label l6 = helper.createLabel();
+        mv.visitJumpInsn(Opcodes.GOTO, l6);
+        ASMHelper.Label l7 = helper.createLabel();
+        mv.visitLabel(l7);
+        mv.visitLineNumber(1042, l7);
+        mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] {"java/util/List", Opcodes.INTEGER}, 0, null);
+        mv.visitVarInsn(Opcodes.ALOAD, 2);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+        mv.visitVarInsn(Opcodes.ILOAD, 3);
+        mv.visitInsn(Opcodes.AALOAD);
+        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "remove", "(Ljava/lang/Object;)Z", true);
+        mv.visitInsn(Opcodes.POP);
+        ASMHelper.Label l8 = helper.createLabel();
+        mv.visitLabel(l8);
+        mv.visitLineNumber(1041, l8);
+        mv.visitIincInsn(3, 2);
+        mv.visitLabel(l6);
+        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+        mv.visitVarInsn(Opcodes.ILOAD, 3);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD,
+                slashedName,
+                "nsctxt", "[Ljava/lang/String;");
+        mv.visitInsn(Opcodes.ARRAYLENGTH);
+        mv.visitJumpInsn(Opcodes.IF_ICMPLT, l7);
+        ASMHelper.Label l9 = helper.createLabel();
+        mv.visitLabel(l9);
+        mv.visitLineNumber(1044, l9);
+        mv.visitVarInsn(Opcodes.ALOAD, 2);
+        mv.visitVarInsn(Opcodes.ALOAD, 2);
+        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "size", "()I", true);
+        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
+        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
+                "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", true);
+        mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/String;");
+        mv.visitInsn(Opcodes.ARETURN);
+        ASMHelper.Label l10 = helper.createLabel();
+        mv.visitLabel(l10);
+        mv.visitLocalVariable("this", "L" + slashedName + ";",
+                null, l0, l10, 0);
+        mv.visitLocalVariable("sup", "[Ljava/lang/String;", null, l1, l10, 1);
+        mv.visitLocalVariable("s", "Ljava/util/List;", "Ljava/util/List<Ljava/lang/String;>;", l4, l10, 2);
+        mv.visitLocalVariable("x", "I", null, l5, l9, 3);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+
+    private byte[] createNamespaceWrapperInternal(String postFix) {
+
+        String superName = "com/sun/xml/"
+                + ("RI".equals(postFix) ? "" : "internal/")
+                + "bind/marshaller/NamespacePrefixMapper";
+        String postFixedName = "org/apache/cxf/jaxb/NamespaceMapper" + postFix;
+        ASMHelper.ClassWriter cw = helper.createClassWriter();
+        if (cw == null) {
+            return null;
+        }
+        ASMHelper.FieldVisitor fv;
+        ASMHelper.MethodVisitor mv;
+        OpcodesProxy opcodes= helper.getOpCodes();
+        cw.visit(opcodes.V1_6,
+                opcodes.ACC_PUBLIC + opcodes.ACC_FINAL + opcodes.ACC_SUPER,
+                postFixedName, null,
+                superName, null);
+
+        cw.visitSource("NamespaceMapper.java", null);
+
+        fv = cw.visitField(opcodes.ACC_PRIVATE + opcodes.ACC_FINAL,
+                "nspref", "Ljava/util/Map;",
+                "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;", null);
+        fv.visitEnd();
+
+        fv = cw.visitField(opcodes.ACC_PRIVATE, "nsctxt", "[Ljava/lang/String;", null, null);
+        fv.visitEnd();
+
+        fv = cw.visitField(opcodes.ACC_PRIVATE + opcodes.ACC_FINAL + opcodes.ACC_STATIC,
+                "EMPTY_STRING", "[Ljava/lang/String;", null, null);
+        fv.visitEnd();
+
+        mv = cw.visitMethod(opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
+        mv.visitCode();
+        ASMHelper.Label l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(30, l0);
+        mv.visitInsn(opcodes.ICONST_0);
+        mv.visitTypeInsn(opcodes.ANEWARRAY, "java/lang/String");
+        mv.visitFieldInsn(opcodes.PUTSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
+        mv.visitInsn(opcodes.RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(opcodes.ACC_PUBLIC, "<init>",
+                "(Ljava/util/Map;)V",
+                "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(32, l0);
+        mv.visitVarInsn(opcodes.ALOAD, 0);
+        mv.visitMethodInsn(opcodes.INVOKESPECIAL, superName, "<init>", "()V", false);
+        ASMHelper.Label l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(29, l1);
+        mv.visitVarInsn(opcodes.ALOAD, 0);
+        mv.visitFieldInsn(opcodes.GETSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
+        mv.visitFieldInsn(opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
+        ASMHelper.Label l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLineNumber(33, l2);
+        mv.visitVarInsn(opcodes.ALOAD, 0);
+        mv.visitVarInsn(opcodes.ALOAD, 1);
+        mv.visitFieldInsn(opcodes.PUTFIELD, postFixedName, "nspref", "Ljava/util/Map;");
+        ASMHelper.Label l3 = helper.createLabel();
+        mv.visitLabel(l3);
+        mv.visitLineNumber(34, l3);
+        mv.visitInsn(opcodes.RETURN);
+        ASMHelper.Label l4 = helper.createLabel();
+        mv.visitLabel(l4);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
+        mv.visitLocalVariable("nspref",
+                "Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;",
+                l0, l4, 1);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(opcodes.ACC_PUBLIC, "getPreferredPrefix",
+                "(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;",
+                null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(39, l0);
+        mv.visitVarInsn(opcodes.ALOAD, 0);
+        mv.visitFieldInsn(opcodes.GETFIELD, postFixedName, "nspref", "Ljava/util/Map;");
+        mv.visitVarInsn(opcodes.ALOAD, 1);
+        mv.visitMethodInsn(opcodes.INVOKEINTERFACE, "java/util/Map",
+                "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
+        mv.visitTypeInsn(opcodes.CHECKCAST, "java/lang/String");
+        mv.visitVarInsn(opcodes.ASTORE, 4);
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(40, l1);
+        mv.visitVarInsn(opcodes.ALOAD, 4);
+        l2 = helper.createLabel();
+        mv.visitJumpInsn(opcodes.IFNULL, l2);
+        l3 = helper.createLabel();
+        mv.visitLabel(l3);
+        mv.visitLineNumber(41, l3);
+        mv.visitVarInsn(opcodes.ALOAD, 4);
+        mv.visitInsn(opcodes.ARETURN);
+        mv.visitLabel(l2);
+        mv.visitLineNumber(43, l2);
+        mv.visitFrame(opcodes.F_APPEND, 1, new Object[] {"java/lang/String"}, 0, null);
+        mv.visitVarInsn(opcodes.ALOAD, 2);
+        mv.visitInsn(opcodes.ARETURN);
+        l4 = helper.createLabel();
+        mv.visitLabel(l4);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
+        mv.visitLocalVariable("namespaceUri", "Ljava/lang/String;", null, l0, l4, 1);
+        mv.visitLocalVariable("suggestion", "Ljava/lang/String;", null, l0, l4, 2);
+        mv.visitLocalVariable("requirePrefix", "Z", null, l0, l4, 3);
+        mv.visitLocalVariable("prefix", "Ljava/lang/String;", null, l1, l4, 4);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(opcodes.ACC_PUBLIC, "setContextualNamespaceDecls", "([Ljava/lang/String;)V", null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(47, l0);
+        mv.visitVarInsn(opcodes.ALOAD, 0);
+        mv.visitVarInsn(opcodes.ALOAD, 1);
+        mv.visitFieldInsn(opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(48, l1);
+        mv.visitInsn(opcodes.RETURN);
+        l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l2, 0);
+        mv.visitLocalVariable("contextualNamespaceDecls", "[Ljava/lang/String;", null, l0, l2, 1);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(opcodes.ACC_PUBLIC, "getContextualNamespaceDecls", "()[Ljava/lang/String;", null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(51, l0);
+        mv.visitVarInsn(opcodes.ALOAD, 0);
+        mv.visitFieldInsn(opcodes.GETFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
+        mv.visitInsn(opcodes.ARETURN);
+        l1 = helper.createLabel();
+
+        mv.visitLabel(l1);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l1, 0);
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+    //CHECKSTYLE:ON
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/ASMHelperImpl.java b/transform/src/patch/java/org/apache/cxf/common/util/ASMHelperImpl.java
new file mode 100644
index 0000000..cc01f14
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/ASMHelperImpl.java
@@ -0,0 +1,273 @@
+/**
+ * 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.cxf.common.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+
+
+public class ASMHelperImpl implements ASMHelper {
+    protected static final Map<Class<?>, String> PRIMITIVE_MAP = new HashMap<>();
+    protected static final Map<Class<?>, String> NONPRIMITIVE_MAP = new HashMap<>();
+    protected static final Map<Class<?>, Integer> PRIMITIVE_ZERO_MAP = new HashMap<>();
+
+    protected boolean badASM;
+    private Class<?> cwClass;
+
+    public ASMHelperImpl() {
+
+    }
+
+    static {
+        PRIMITIVE_MAP.put(Byte.TYPE, "B");
+        PRIMITIVE_MAP.put(Boolean.TYPE, "Z");
+        PRIMITIVE_MAP.put(Long.TYPE, "J");
+        PRIMITIVE_MAP.put(Integer.TYPE, "I");
+        PRIMITIVE_MAP.put(Short.TYPE, "S");
+        PRIMITIVE_MAP.put(Character.TYPE, "C");
+        PRIMITIVE_MAP.put(Float.TYPE, "F");
+        PRIMITIVE_MAP.put(Double.TYPE, "D");
+
+        NONPRIMITIVE_MAP.put(Byte.TYPE, Byte.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Boolean.TYPE, Boolean.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Long.TYPE, Long.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Integer.TYPE, Integer.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Short.TYPE, Short.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Character.TYPE, Character.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Float.TYPE, Float.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Double.TYPE, Double.class.getName().replaceAll("\\.", "/"));
+    }
+
+    private void tryClass(String s) {
+        if (cwClass == null) {
+            try {
+                Class<?> c2 = ClassLoaderUtils.loadClass(s, ASMHelperImpl.class);
+
+                //old versions don't have this, but we need it
+                Class<?> cls = ClassLoaderUtils.loadClass(c2.getPackage().getName() + ".MethodVisitor", c2);
+                cls.getMethod("visitFrame", Integer.TYPE, Integer.TYPE,
+                        Object[].class,  Integer.TYPE, Object[].class);
+                cwClass = c2;
+            } catch (Throwable t) {
+                //ignore
+            }
+        }
+    }
+    private Class<?> getASMClassWriterClass() {
+        //force this to make sure the proper OSGi import is generated
+        return org.objectweb.asm.ClassWriter.class;
+    }
+
+    public synchronized Class<?> getASMClass() throws ClassNotFoundException {
+        if (cwClass == null) {
+            //try the "real" asm first, then the others
+            tryClass("org.objectweb.asm.ClassWriter");
+            tryClass("org.apache.xbean.asm9.ClassWriter");
+            tryClass("org.apache.xbean.asm8.ClassWriter");
+            tryClass("org.apache.xbean.asm7.ClassWriter");
+            tryClass("org.apache.xbean.asm5.ClassWriter");
+            tryClass("org.apache.xbean.asm6.ClassWriter");
+            tryClass("org.apache.xbean.asm4.ClassWriter");
+            tryClass("org.apache.xbean.asm.ClassWriter");
+            tryClass("org.springframework.asm.ClassWriter");
+            if (cwClass == null) {
+                cwClass = getASMClassWriterClass();
+            }
+        }
+        return cwClass;
+    }
+    public OpcodesProxy getOpCodes() {
+        OpcodesProxy ops = new OpcodesProxy(this);
+        PRIMITIVE_ZERO_MAP.put(Byte.TYPE, ops.ICONST_0);
+        PRIMITIVE_ZERO_MAP.put(Boolean.TYPE, ops.ICONST_0);
+        PRIMITIVE_ZERO_MAP.put(Long.TYPE, ops.LCONST_0);
+        PRIMITIVE_ZERO_MAP.put(Integer.TYPE, ops.ICONST_0);
+        PRIMITIVE_ZERO_MAP.put(Short.TYPE, ops.ICONST_0);
+        PRIMITIVE_ZERO_MAP.put(Character.TYPE, ops.ICONST_0);
+        PRIMITIVE_ZERO_MAP.put(Float.TYPE, ops.FCONST_0);
+        PRIMITIVE_ZERO_MAP.put(Double.TYPE, ops.DCONST_0);
+        return ops;
+    }
+    public void setBadASM(boolean b) {
+        badASM = b;
+    }
+
+    public String getMethodSignature(Method m) {
+        StringBuilder buf = new StringBuilder("(");
+        for (Class<?> cl : m.getParameterTypes()) {
+            buf.append(getClassCode(cl));
+        }
+        buf.append(')');
+        buf.append(getClassCode(m.getReturnType()));
+
+        return buf.toString();
+    }
+
+    @Override
+    public String getNonPrimitive(Class<?> tp) {
+        return NONPRIMITIVE_MAP.get(tp);
+    }
+    @Override
+    public String getPrimitive(Class<?> tp) {
+        return PRIMITIVE_MAP.get(tp);
+    }
+
+
+
+
+    public String getClassCode(Class<?> cl) {
+        if (cl == Void.TYPE) {
+            return "V";
+        }
+        if (cl.isPrimitive()) {
+            return PRIMITIVE_MAP.get(cl);
+        }
+        if (cl.isArray()) {
+            return "[" + getClassCode(cl.getComponentType());
+        }
+        return "L" + StringUtils.periodToSlashes(cl.getName()) + ";";
+    }
+    public String getClassCode(java.lang.reflect.Type type) {
+        if (type instanceof Class) {
+            return getClassCode((Class<?>)type);
+        } else if (type instanceof GenericArrayType) {
+            GenericArrayType at = (GenericArrayType)type;
+            return "[" + getClassCode(at.getGenericComponentType());
+        } else if (type instanceof TypeVariable) {
+            TypeVariable<?> tv = (TypeVariable<?>)type;
+            java.lang.reflect.Type[] bounds = tv.getBounds();
+            if (bounds != null && bounds.length == 1) {
+                return getClassCode(bounds[0]);
+            }
+            throw new IllegalArgumentException("Unable to determine type for: " + tv);
+        } else if (type instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType)type;
+            StringBuilder a = new StringBuilder(getClassCode(pt.getRawType()));
+            if (!pt.getRawType().equals(Enum.class)) {
+                a.setLength(a.length() - 1);
+                a.append('<');
+
+                for (java.lang.reflect.Type t : pt.getActualTypeArguments()) {
+                    a.append(getClassCode(t));
+                }
+                a.append(">;");
+            }
+            return a.toString();
+        } else if (type instanceof WildcardType) {
+            WildcardType wt = (WildcardType)type;
+            StringBuilder a = new StringBuilder();
+            java.lang.reflect.Type[] lowBounds = wt.getLowerBounds();
+            java.lang.reflect.Type[] upBounds = wt.getUpperBounds();
+            for (java.lang.reflect.Type t : upBounds) {
+                a.append('+');
+                a.append(getClassCode(t));
+            }
+            for (java.lang.reflect.Type t : lowBounds) {
+                a.append('-');
+                a.append(getClassCode(t));
+            }
+            return a.toString();
+        }
+        return null;
+    }
+
+    public ClassWriter createClassWriter() {
+        Object newCw = null;
+        if (!badASM) {
+            if (cwClass == null) {
+                try {
+                    cwClass = getASMClass();
+                } catch (Throwable error) {
+                    badASM = true;
+                    throw new RuntimeException("No ASM ClassWriterFound", error);
+                }
+            }
+            // ASM >= 3.x (since cxf is java 8 min we don't care of asm 1/2)
+            try {
+                Constructor<?> cons = cwClass.getConstructor(Integer.TYPE);
+                int i = cwClass.getField("COMPUTE_MAXS").getInt(null);
+                i |= cwClass.getField("COMPUTE_FRAMES").getInt(null);
+                newCw = cons.newInstance(Integer.valueOf(i));
+            } catch (Throwable e1) {
+                // ignore
+            }
+        }
+        if (newCw != null) {
+            return ReflectionInvokationHandler.createProxyWrapper(newCw, ClassWriter.class);
+        }
+        return null;
+    }
+
+
+    public ASMType getType(final String type) {
+        try {
+            final Class<?> cls = ClassLoaderUtils.loadClass(cwClass.getPackage().getName() + ".Type", cwClass);
+            final Method m = cls.getMethod("getType", String.class);
+            final Method m2 = cls.getMethod("getOpcode", Integer.TYPE);
+            @SuppressWarnings("unused")
+            ASMType t = new ASMType() {
+                Object tp = ReflectionUtil.setAccessible(m).invoke(null, type);
+                public Object getValue() {
+                    return tp;
+                }
+                public Class<?> realType() {
+                    return cls;
+                }
+                public int getOpcode(int ireturn) {
+                    try {
+                        return (Integer)ReflectionUtil.setAccessible(m2).invoke(tp, ireturn);
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            };
+            return t;
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+    public Label createLabel() {
+        try {
+            final Class<?> cls = ClassLoaderUtils.loadClass(cwClass.getPackage().getName() + ".Label",
+                    cwClass);
+            @SuppressWarnings("unused")
+            Label l = new Label() {
+                Object l = cls.newInstance();
+                public Object getValue() {
+                    return l;
+                }
+                public Class<?> realType() {
+                    return cls;
+                }
+            };
+            return l;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/Base64Utility.java b/transform/src/patch/java/org/apache/cxf/common/util/Base64Utility.java
new file mode 100644
index 0000000..043eba7
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/Base64Utility.java
@@ -0,0 +1,474 @@
+/**
+ * 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.cxf.common.util;
+
+/**
+ * Base64Utility - this static class provides useful base64
+ *                 encoding utilities.
+ */
+
+// Java imports
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.CharBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+
+
+/**
+ * This class converts to/from base64. The alternative conversions include:
+ *
+ * encode:
+ *    byte[]     into String
+ *    byte[]     into char[]
+ *    byte[]     into OutStream
+ *    byte[]     into Writer
+ * decode:
+ *    char[]     into byte[]
+ *    String     into byte[]
+ *    char[]     into OutStream
+ *    String     into OutStream
+ *
+ */
+public final class Base64Utility {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(Base64Utility.class);
+
+
+    // base 64 character set
+    //
+    private static final char[] BCS = {
+        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+        'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+        'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+        'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+        'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', '+', '/'
+    };
+
+    private static final char[] BCS_URL_SAFE = Arrays.copyOf(BCS, BCS.length);
+
+    // base 64 padding
+    private static final char PAD = '=';
+
+    // size of base 64 decode table
+    private static final int BDTSIZE = 128;
+
+    // base 64 decode table
+    private static final byte[] BDT = new byte[128];
+
+
+    private static final int PAD_SIZE0 = 1;
+    private static final int PAD_SIZE4 = 2;
+    private static final int PAD_SIZE8 = 3;
+
+    // class static initializer for building decode table
+    static {
+        for (int i = 0;  i < BDTSIZE;  i++) {
+            BDT[i] = Byte.MAX_VALUE;
+        }
+
+        for (int i = 0;  i < BCS.length;  i++) {
+            BDT[BCS[i]] = (byte)i;
+        }
+
+        BCS_URL_SAFE[62] = '-';
+        BCS_URL_SAFE[63] = '_';
+    }
+
+
+    private Base64Utility() {
+        //utility class, never constructed
+    }
+
+
+
+    /**
+     * The <code>decode_chunk</code> routine decodes a chunk of data
+     * into its native encoding.
+     *
+     * base64 encodes each 3 octets of data into 4 characters from a
+     * limited 64 character set. The 3 octets are joined to form
+     * 24 bits which are then split into 4 x 6bit values. Each 6 bit
+     * value is then used as an index into the 64 character table of
+     * base64 chars. If the total data length is not a 3 octet multiple
+     * the '=' char is used as padding for the final 4 char group,
+     * either 1 octet + '==' or 2 octets + '='.
+     *
+     * @param   id  The input data to be processed
+     * @param   o   The offset from which to begin processing
+     * @param   l   The length (bound) at which processing is to end
+     * @return  The decoded data
+     * @exception   Base64Exception Thrown is processing fails due to
+     * formatting exceptions in the encoded data
+     */
+    public static byte[] decodeChunk(char[] id,
+                                     int o,
+                                     int l)
+        throws Base64Exception {
+
+        if (id != null && id.length == 0 && l == 0) {
+            return new byte[0];
+        }
+
+        // Keep it simple - must be >= 4. Unpadded
+        // base64 data contain < 3 octets is invalid.
+        //
+        if ((l - o) < 4) {
+            return null;
+        }
+
+        char[] ib = new char[4];
+        int ibcount = 0;
+
+        // cryan. Calc the num of octets. Each 4 chars of base64 chars
+        // (representing 24 bits) encodes 3 octets.
+        //
+        int octetCount = 3 * (l / 4);
+
+        // Final 4 chars may contain 3 octets or padded to contain
+        // 1 or 2 octets.
+        //
+        if (id[l - 1] == PAD) {
+            // TT== means last 4 chars encode 8 bits (ie subtract 2)
+            // TTT= means last 4 chars encode 16 bits (ie subtract 1)
+            octetCount -= (id[l - 2] == PAD) ? 2 : 1;
+        }
+
+        byte[] ob = new byte[octetCount];
+        int obcount = 0;
+
+        for (int i = o;  i < o + l && i < id.length;  i++) {
+            if (id[i] == PAD
+                || id[i] < BDT.length
+                && BDT[id[i]] != Byte.MAX_VALUE) {
+
+                ib[ibcount++] = id[i];
+
+                // Decode each 4 char sequence.
+                //
+                if (ibcount == ib.length) {
+                    ibcount = 0;
+                    obcount += processEncodeme(ib, ob, obcount);
+                }
+            }
+        }
+
+        if (obcount != ob.length) {
+            byte []tmp = new byte[obcount];
+            System.arraycopy(ob, 0, tmp, 0, obcount);
+            ob = tmp;
+        }
+
+        return ob;
+    }
+
+    public static byte[] decode(String id) throws Base64Exception {
+        return decode(id, false);
+    }
+
+    public static byte[] decode(String id, boolean urlSafe) throws Base64Exception {
+        if (urlSafe) {
+            id = id.replace('-', '+').replace('_', '/');
+            switch (id.length() % 4) {
+            case 0:
+                break;
+            case 2:
+                id += "==";
+                break;
+            case 3:
+                id += "=";
+                break;
+            default:
+                throw new Base64Exception(new Message("BASE64_RUNTIME_EXCEPTION", LOG));
+            }
+        }
+        try {
+            char[] cd = id.toCharArray();
+            return decodeChunk(cd, 0, cd.length);
+        } catch (Exception e) {
+            LOG.warning("Invalid base64 encoded string : " + id);
+            throw new Base64Exception(new Message("BASE64_RUNTIME_EXCEPTION", LOG), e);
+        }
+    }
+
+    public static void decode(char[] id,
+                             int o,
+                             int l,
+                             OutputStream ostream)
+        throws Base64Exception {
+
+        try {
+            ostream.write(decodeChunk(id, o, l));
+        } catch (Exception e) {
+            LOG.warning("Invalid base64 encoded string : " + new String(id));
+            throw new Base64Exception(new Message("BASE64_RUNTIME_EXCEPTION", LOG), e);
+        }
+    }
+
+    public static void decode(String id,
+                              OutputStream ostream)
+        throws Base64Exception {
+
+        try {
+            char[] cd = id.toCharArray();
+            ostream.write(decodeChunk(cd, 0, cd.length));
+        } catch (IOException ioe) {
+            throw new Base64Exception(new Message("BASE64_DECODE_IOEXCEPTION", LOG), ioe);
+        } catch (Exception e) {
+            LOG.warning("Invalid base64 encoded string : " + id);
+            throw new Base64Exception(new Message("BASE64_RUNTIME_EXCEPTION", LOG), e);
+        }
+    }
+
+    // Returns base64 representation of specified byte array.
+    //
+    public static String encode(byte[] id) {
+        return encode(id, false);
+    }
+
+    public static String encode(byte[] id, boolean urlSafe) {
+        char[] cd = encodeChunk(id, 0, id.length);
+        return new String(cd, 0, cd.length);
+    }
+
+    // Returns base64 representation of specified byte array.
+    //
+    public static char[] encodeChunk(byte[] id,
+                                     int o,
+                                     int l) {
+        return encodeChunk(id, o, l, false);
+    }
+
+    public static char[] encodeChunk(byte[] id,
+                                     int o,
+                                     int l,
+                                     boolean urlSafe) {
+        if (id != null && id.length == 0 && l == 0) {
+            return new char[0];
+        } else if (l <= 0) {
+            return null;
+        }
+
+        char[] out;
+
+        // If not a multiple of 3 octets then a final padded 4 char
+        // slot is needed.
+        //
+        if (l % 3 == 0) {
+            out = new char[l / 3 * 4];
+        } else {
+            int finalLen = !urlSafe ? 4 : l % 3 == 1 ? 2 : 3;
+            out = new char[l / 3 * 4 + finalLen];
+        }
+
+        int rindex = o;
+        int windex = 0;
+        int rest = l;
+
+        final char[] base64Table = urlSafe ? BCS_URL_SAFE : BCS;
+        while (rest >= 3) {
+            int i = ((id[rindex] & 0xff) << 16)
+                    + ((id[rindex + 1] & 0xff) << 8)
+                    + (id[rindex + 2] & 0xff);
+
+            out[windex++] = base64Table[i >> 18];
+            out[windex++] = base64Table[(i >> 12) & 0x3f];
+            out[windex++] = base64Table[(i >> 6) & 0x3f];
+            out[windex++] = base64Table[i & 0x3f];
+            rindex += 3;
+            rest -= 3;
+        }
+
+        if (rest == 1) {
+            int i = id[rindex] & 0xff;
+            out[windex++] = base64Table[i >> 2];
+            out[windex++] = base64Table[(i << 4) & 0x3f];
+            if (!urlSafe) {
+                out[windex++] = PAD;
+                out[windex] = PAD;
+            }
+        } else if (rest == 2) {
+            int i = ((id[rindex] & 0xff) << 8) + (id[rindex + 1] & 0xff);
+            out[windex++] = base64Table[i >> 10];
+            out[windex++] = base64Table[(i >> 4) & 0x3f];
+            out[windex++] = base64Table[(i << 2) & 0x3f];
+            if (!urlSafe) {
+                out[windex] = PAD;
+            }
+        }
+        return out;
+    }
+
+    public static void encodeAndStream(byte[] id,
+                                       int o,
+                                       int l,
+                                       OutputStream os) throws IOException {
+        encodeAndStream(id, o, l, false, os);
+    }
+
+    public static void encodeAndStream(byte[] id,
+                                           int o,
+                                           int l,
+                                           boolean urlSafe,
+                                           OutputStream os) throws IOException {
+        if (l <= 0) {
+            return;
+        }
+
+        int rindex = o;
+        int rest = l;
+        final char[] base64Table = urlSafe ? BCS_URL_SAFE : BCS;
+
+        char[] chunk = new char[4];
+        while (rest >= 3) {
+            int i = ((id[rindex] & 0xff) << 16)
+                    + ((id[rindex + 1] & 0xff) << 8)
+                    + (id[rindex + 2] & 0xff);
+            chunk[0] = base64Table[i >> 18];
+            chunk[1] = base64Table[(i >> 12) & 0x3f];
+            chunk[2] = base64Table[(i >> 6) & 0x3f];
+            chunk[3] = base64Table[i & 0x3f];
+            writeCharArrayToStream(chunk, 4, os);
+            rindex += 3;
+            rest -= 3;
+        }
+        if (rest == 0) {
+            return;
+        }
+        if (rest == 1) {
+            int i = id[rindex] & 0xff;
+            chunk[0] = base64Table[i >> 2];
+            chunk[1] = base64Table[(i << 4) & 0x3f];
+            if (!urlSafe) {
+                chunk[2] = PAD;
+                chunk[3] = PAD;
+            }
+        } else if (rest == 2) {
+            int i = ((id[rindex] & 0xff) << 8) + (id[rindex + 1] & 0xff);
+            chunk[0] = base64Table[i >> 10];
+            chunk[1] = base64Table[(i >> 4) & 0x3f];
+            chunk[2] = base64Table[(i << 2) & 0x3f];
+            if (!urlSafe) {
+                chunk[3] = PAD;
+            }
+        }
+        int finalLenToWrite = !urlSafe ? 4 : rest == 1 ? 2 : 3;
+        writeCharArrayToStream(chunk, finalLenToWrite, os);
+    }
+
+    private static void writeCharArrayToStream(char[] chunk, int len, OutputStream os) throws IOException {
+        // may be we can just cast to byte when creating chunk[] earlier on
+        byte[] bytes = StandardCharsets.UTF_8.encode(CharBuffer.wrap(chunk, 0, len)).array();
+        os.write(bytes);
+    }
+
+    //
+    // Outputs base64 representation of the specified byte array
+    // to a byte stream.
+    //
+    public static void encodeChunk(byte[] id,
+                                   int o,
+                                   int l,
+                                   OutputStream ostream) throws Base64Exception {
+        try {
+            ostream.write(new String(encodeChunk(id, o, l)).getBytes());
+        } catch (IOException e) {
+            throw new Base64Exception(new Message("BASE64_ENCODE_IOEXCEPTION", LOG), e);
+        }
+    }
+
+    // Outputs base64 representation of the specified byte
+    // array to a character stream.
+    //
+    public static void encode(byte[] id,
+                              int o,
+                              int l,
+                              Writer writer) throws Base64Exception {
+        try {
+            writer.write(encodeChunk(id, o, l));
+        } catch (IOException e) {
+            throw new Base64Exception(new Message("BASE64_ENCODE_WRITER_IOEXCEPTION", LOG), e);
+        }
+    }
+    //---- Private static methods --------------------------------------
+
+    /**
+     * The <code>process</code> routine processes an atomic base64
+     * unit of encoding (encodeme) into its native encoding. This class is
+     * used by decode routines to do the grunt work of decoding
+     * base64 encoded information
+     *
+     * @param   ib  Input character buffer of encoded bytes
+     * @param   ob  Output byte buffer of decoded bytes
+     * @param   p   Pointer to the encodeme of interest
+     * @return  The decoded encodeme
+     * @exception   Base64Exception Thrown is processing fails due to
+     * formatting exceptions in the encoded data
+     */
+    private static int processEncodeme(char[] ib,
+                                       byte[] ob,
+                                       int p)
+        throws Base64Exception {
+
+
+        int spad = PAD_SIZE8;
+        if (ib[3] == PAD) {
+            spad = PAD_SIZE4;
+        }
+        if (ib[2] == PAD) {
+            spad = PAD_SIZE0;
+        }
+
+        int b0 = BDT[ib[0]];
+        int b1 = BDT[ib[1]];
+        int b2 = BDT[ib[2]];
+        int b3 = BDT[ib[3]];
+
+        switch (spad) {
+        case PAD_SIZE0:
+            ob[p] = (byte)(b0 << 2 & 0xfc | b1 >> 4 & 0x3);
+            return PAD_SIZE0;
+        case PAD_SIZE4:
+            ob[p++] = (byte)(b0 << 2 & 0xfc | b1 >> 4 & 0x3);
+            ob[p] = (byte)(b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
+            return PAD_SIZE4;
+        case PAD_SIZE8:
+            ob[p++] = (byte)(b0 << 2 & 0xfc | b1 >> 4 & 0x3);
+            ob[p++] = (byte)(b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
+            ob[p] = (byte)(b2 << 6 & 0xc0 | b3 & 0x3f);
+            return PAD_SIZE8;
+        default:
+            // We should never get here
+            throw new IllegalStateException();
+        }
+    }
+
+    public static boolean isValidBase64(int ch) {
+        return ch == PAD || BDT[ch] != Byte.MAX_VALUE;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/CachedClass.java b/transform/src/patch/java/org/apache/cxf/common/util/CachedClass.java
new file mode 100644
index 0000000..fe2df06
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/CachedClass.java
@@ -0,0 +1,37 @@
+/**
+ * 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.cxf.common.util;
+
+import java.lang.ref.WeakReference;
+
+public class CachedClass {
+    private WeakReference<Class<?>> cachedClazz;
+
+    public CachedClass(Class<?> cachedClass) {
+        this.cachedClazz = new WeakReference<>(cachedClass);
+    }
+
+    public Class<?> getCachedClass() {
+        return cachedClazz == null ? null : cachedClazz.get();
+    }
+
+    public void setCachedClass(Class<?> cachedClass) {
+        this.cachedClazz = new WeakReference<>(cachedClass);
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/ClassHelper.java b/transform/src/patch/java/org/apache/cxf/common/util/ClassHelper.java
new file mode 100644
index 0000000..adec469
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/ClassHelper.java
@@ -0,0 +1,140 @@
+/**
+ * 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.cxf.common.util;
+
+
+import java.lang.reflect.Proxy;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+
+/**
+ *
+ */
+public class ClassHelper {
+
+    public static final String USE_DEFAULT_CLASS_HELPER = "org.apache.cxf.useDefaultClassHelpers";
+
+    static final ClassHelper HELPER;
+    static final ClassUnwrapper DEFAULT_UNWRAPPER;
+    static final ClassUnwrapper UNWRAPPER;
+    
+    /**
+     * Default class unwrapper implementation which delegates to the ClassHelper
+     * internal methods.
+     *
+     */
+    private static class DefaultClassUnwrapper implements ClassUnwrapper {
+        private final ClassHelper helper;
+        
+        DefaultClassUnwrapper(ClassHelper helper) {
+            this.helper = helper;
+        }
+        
+        @Override
+        public Class<?> getRealClassFromClass(Class<?> clazz) {
+            return helper.getRealClassFromClassInternal(clazz);
+        }
+        
+        @Override
+        public Class<?> getRealClass(Object o) {
+            return helper.getRealClassInternal(o);
+        }
+        
+        @Override
+        public Object getRealObject(Object o) {
+            return helper.getRealObjectInternal(o);
+        }
+    }
+
+    static {
+        HELPER = new ClassHelper();
+        DEFAULT_UNWRAPPER = new DefaultClassUnwrapper(HELPER);
+        UNWRAPPER = getClassUnwrapper(DEFAULT_UNWRAPPER);
+    }
+
+    protected ClassHelper() {
+    }
+
+    private static ClassUnwrapper getClassUnwrapper(ClassUnwrapper defaultHelper) {
+        boolean useSpring = true;
+        String s = SystemPropertyAction.getPropertyOrNull("org.apache.cxf.useSpringClassHelpers");
+        if (!StringUtils.isEmpty(s)) {
+            useSpring = "1".equals(s) || Boolean.parseBoolean(s);
+        }
+        if (useSpring) {
+            try {
+                return new SpringClassUnwrapper();
+            } catch (Throwable ex) {
+                // ignore
+            }
+        }
+        return defaultHelper;
+    }
+
+    private Class<?> getRealClassInternal(Object o) {
+        return getRealObjectInternal(o).getClass();
+    }
+
+    private Class<?> getRealClassFromClassInternal(Class<?> cls) {
+        return cls;
+    }
+
+    private Object getRealObjectInternal(Object o) {
+        return o instanceof Proxy ? Proxy.getInvocationHandler(o) : o;
+    }
+
+    public static Class<?> getRealClass(Object o) {
+        return getRealClass(null, o);
+    }
+
+    public static Class<?> getRealClassFromClass(Class<?> cls) {
+        return getRealClassFromClass(null, cls);
+    }
+
+    public static Class<?> getRealClassFromClass(Bus bus, Class<?> cls) {
+        return getContextClassUnwrapper(getBus(bus)).getRealClassFromClass(cls);
+    }
+
+    public static Object getRealObject(Object o) {
+        return getContextClassUnwrapper(getBus(null)).getRealObject(o);
+    }
+
+    public static Class<?> getRealClass(Bus bus, Object o) {
+        return getContextClassUnwrapper(getBus(bus)).getRealClass(o);
+    }
+
+    private static ClassUnwrapper getContextClassUnwrapper(Bus bus) {
+        if (bus != null && bus.getProperty(ClassUnwrapper.class.getName()) != null) {
+            return  (ClassUnwrapper) bus.getProperty(ClassUnwrapper.class.getName());
+        }
+
+        return (DEFAULT_UNWRAPPER == UNWRAPPER || checkUseDefaultClassHelper(bus)) ? DEFAULT_UNWRAPPER : UNWRAPPER;
+    }
+
+    private static Bus getBus(Bus bus) {
+        return bus == null ? BusFactory.getThreadDefaultBus() : bus;
+    }
+
+    private static boolean checkUseDefaultClassHelper(Bus bus) {
+        return bus != null && Boolean.TRUE.equals(bus.getProperty(USE_DEFAULT_CLASS_HELPER));
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/CollectionUtils.java b/transform/src/patch/java/org/apache/cxf/common/util/CollectionUtils.java
new file mode 100644
index 0000000..4e888c3
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/CollectionUtils.java
@@ -0,0 +1,126 @@
+/**
+ * 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.cxf.common.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+
+public final class CollectionUtils {
+    private CollectionUtils() {
+
+    }
+
+    public static <T> Collection<T> diff(Collection<T> c1, Collection<T> c2) {
+        if (c1 == null || c1.isEmpty() || c2 == null || c2.isEmpty()) {
+            return c1;
+        }
+        Collection<T> difference = new ArrayList<>();
+        for (T item : c1) {
+            if (!c2.contains(item)) {
+                difference.add(item);
+            }
+        }
+        return difference;
+    }
+
+    public static <T> boolean isEmpty(Collection<T> c) {
+        if (c != null && !c.isEmpty()) {
+            for (T item : c) {
+                if (item != null) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    public static <K, V> boolean isEmpty(Map<K, V> m) {
+        return m == null || m.isEmpty();
+    }
+
+    public static <S, T> Dictionary<S, T> singletonDictionary(S s, T t) {
+        return toDictionary(Collections.singletonMap(s, t));
+    }
+
+    public static <S, T> Dictionary<S, T> toDictionary(Map<S, T> map) {
+        return new MapToDictionary<>(map);
+    }
+
+    static class MapToDictionary<S, T> extends Dictionary<S, T> {
+        /**
+         * Map source.
+         **/
+        private final Map<S, T> map;
+
+        MapToDictionary(Map<S, T> map) {
+            this.map = map;
+        }
+
+
+        public Enumeration<T> elements() {
+            return map != null ? new IteratorToEnumeration<>(map.values().iterator()) : null;
+        }
+
+        public T get(Object key) {
+            return map != null ? map.get(key) : null;
+        }
+
+        public boolean isEmpty() {
+            return map == null || map.isEmpty();
+        }
+
+        public Enumeration<S> keys() {
+            return map != null ? new IteratorToEnumeration<>(map.keySet().iterator()) : null;
+        }
+
+        public T put(S key, T value) {
+            throw new UnsupportedOperationException();
+        }
+
+        public T remove(Object key) {
+            throw new UnsupportedOperationException();
+        }
+
+        public int size() {
+            return map != null ? map.size() : 0;
+        }
+
+        static class IteratorToEnumeration<X> implements Enumeration<X> {
+            private final Iterator<X> iter;
+
+            IteratorToEnumeration(Iterator<X> iter) {
+                this.iter = iter;
+            }
+
+            public boolean hasMoreElements() {
+                return iter != null && iter.hasNext();
+            }
+
+            public X nextElement() {
+                return iter != null ? iter.next() : null;
+            }
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/Compiler.java b/transform/src/patch/java/org/apache/cxf/common/util/Compiler.java
new file mode 100644
index 0000000..9d0c819
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/Compiler.java
@@ -0,0 +1,382 @@
+/**
+ * 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.cxf.common.util;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import org.apache.cxf.helpers.FileUtils;
+
+public class Compiler {
+    private long maxMemory = Runtime.getRuntime().maxMemory();
+    private boolean verbose;
+    private String target;
+    private String outputDir;
+    private String classPath;
+    private String encoding;
+    private boolean forceFork = Boolean.getBoolean(Compiler.class.getName() + "-fork");
+    private File classpathTmpFile;
+    private List<String> errors = new LinkedList<>();
+    private List<String> warnings = new LinkedList<>();
+
+    public Compiler() {
+    }
+
+    public List<String> getErrors() {
+        return errors;
+    }
+    public List<String> getWarnings() {
+        return warnings;
+    }
+
+    public void setMaxMemory(long l) {
+        maxMemory = l;
+    }
+    public void setVerbose(boolean b) {
+        verbose = b;
+    }
+    public void setTarget(String s) {
+        target = s;
+    }
+    public void setOutputDir(File s) {
+        if (s != null) {
+            outputDir = s.getAbsolutePath().replace(File.pathSeparatorChar, '/');
+        } else {
+            outputDir = null;
+        }
+    }
+    public void setOutputDir(String s) {
+        outputDir = s.replace(File.pathSeparatorChar, '/');
+    }
+    public void setClassPath(String s) {
+        classPath = StringUtils.isEmpty(s) ? null : s;
+    }
+
+    // https://issues.apache.org/jira/browse/CXF-8049
+    private String getSystemClassPath() {
+        String javaClasspath = SystemPropertyAction.getProperty("java.class.path");
+
+        if (!StringUtils.isEmpty(javaClasspath)) {
+            List<String> correctedEntries = new ArrayList<>();
+
+            String[] toks = javaClasspath.split(File.pathSeparator);
+            
+            for (String tok: toks) {
+                // if any classpath entry contains a whitespace char, 
+                // enclose the entry in double quotes
+                if (tok.matches(".*\\s+.*")) {
+                    correctedEntries.add("\"" + tok + "\"");
+                } else {
+                    correctedEntries.add(tok);
+                }
+            }
+
+            return String.join(File.pathSeparator, correctedEntries);
+        }
+
+        return javaClasspath;
+    }
+
+    protected void addArgs(List<String> list) {
+        if (!StringUtils.isEmpty(encoding)) {
+            list.add("-encoding");
+            list.add(encoding);
+        }
+        if (!StringUtils.isEmpty(target)) {
+            list.add("-target");
+            list.add(target);
+            list.add("-source");
+            list.add(target);
+        }
+
+        if (!StringUtils.isEmpty(outputDir)) {
+            list.add("-d");
+            list.add(outputDir);
+        }
+
+        if (StringUtils.isEmpty(classPath)) {
+            String javaClasspath = getSystemClassPath();
+            boolean classpathSetted = !StringUtils.isEmpty(javaClasspath);
+            if (!classpathSetted) {
+                File f = new File(getClass().getClassLoader().getResource(".").getFile());
+                f = new File(f, "../lib");
+                if (f.exists() && f.isDirectory()) {
+                    list.add("-extdirs");
+                    list.add(f.toString());
+                }
+            } else {
+                list.add("-classpath");
+                list.add(javaClasspath);
+            }
+        } else {
+            list.add("-classpath");
+            list.add(classPath);
+        }
+
+    }
+    public boolean compileFiles(File[] files) {
+        List<String> f = new ArrayList<>(files.length);
+        for (File file : files) {
+            f.add(file.getAbsolutePath());
+        }
+        return compileFiles(f.toArray(new String[0]));
+    }
+    public boolean compileFiles(List<File> files) {
+        List<String> f = new ArrayList<>(files.size());
+        for (File file : files) {
+            f.add(file.getAbsolutePath());
+        }
+        return compileFiles(f.toArray(new String[0]));
+    }
+    public boolean compileFiles(String[] files) {
+        String endorsed = SystemPropertyAction.getProperty("java.endorsed.dirs");
+        if (!forceFork) {
+            return useJava6Compiler(files);
+        }
+
+        List<String> list = new ArrayList<>();
+
+        // Start of honoring java.home for used javac
+        String fsep = File.separator;
+        String javacstr = "javac";
+        String platformjavacname = "javac";
+
+        if (SystemPropertyAction.getProperty("os.name").toLowerCase().indexOf("windows") > -1) {
+            platformjavacname = "javac.exe";
+        }
+
+        if (new File(SystemPropertyAction.getProperty("java.home") + fsep + platformjavacname).exists()) {
+            // check if java.home is jdk home
+            javacstr = SystemPropertyAction.getProperty("java.home") + fsep + platformjavacname;
+        } else if (new File(SystemPropertyAction.getProperty("java.home") + fsep + ".." + fsep + "bin" + fsep
+                            + platformjavacname).exists()) {
+            // check if java.home is jre home
+            javacstr = SystemPropertyAction.getProperty("java.home") + fsep + ".." + fsep + "bin" + fsep
+                       + platformjavacname;
+        } else if (new File(SystemPropertyAction.getProperty("java.home") + fsep + "bin" + fsep
+                            + platformjavacname).exists()) {
+            //java9
+            javacstr = SystemPropertyAction.getProperty("java.home") + fsep + "bin" + fsep
+                + platformjavacname;
+        }
+        list.add(javacstr);
+        // End of honoring java.home for used javac
+
+        if (!StringUtils.isEmpty(endorsed)) {
+            list.add("-endorseddirs");
+            list.add(endorsed);
+        }
+
+        //fix for CXF-2081, set maximum heap of this VM to javac.
+        list.add("-J-Xmx" + maxMemory);
+
+        addArgs(list);
+        int classpathIdx = list.indexOf("-classpath");
+        String classpath = list.get(classpathIdx + 1);
+        checkLongClasspath(classpath, list, classpathIdx);
+        int idx = list.size();
+        Collections.addAll(list, files);
+
+        return internalCompile(list.toArray(new String[0]), idx);
+    }
+
+    protected boolean useJava6Compiler(String[] files) {
+        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+        if (compiler == null) {
+            throw new IllegalStateException(
+                "No compiler detected, make sure you are running on top of a JDK instead of a JRE.");
+        }
+        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
+        Iterable<? extends JavaFileObject> fileList = fileManager.getJavaFileObjectsFromStrings(Arrays
+            .asList(files));
+
+        return internalJava6Compile(compiler, wrapJavaFileManager(fileManager), setupDiagnosticListener(),
+                                    fileList);
+    }
+
+    protected JavaFileManager wrapJavaFileManager(StandardJavaFileManager standardJavaFileManger) {
+        return standardJavaFileManger;
+    }
+
+    protected DiagnosticListener<JavaFileObject> setupDiagnosticListener() {
+        return new DiagnosticListener<JavaFileObject>() {
+            public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+                switch (diagnostic.getKind()) {
+                case ERROR:
+                    errors.add(diagnostic.toString());
+                    if (verbose) {
+                        System.err.println(diagnostic.toString());
+                    }
+                    break;
+                case WARNING:
+                case MANDATORY_WARNING:
+                    warnings.add(diagnostic.toString());
+                    if (verbose) {
+                        System.err.println(diagnostic.toString());
+                    }
+                    break;
+                default:
+                    break;
+                }
+            }
+        };
+    }
+
+    protected boolean internalJava6Compile(JavaCompiler compiler, JavaFileManager fileManager,
+                                           DiagnosticListener<JavaFileObject> listener,
+                                           Iterable<? extends JavaFileObject> fileList) {
+        List<String> args = new ArrayList<>();
+        addArgs(args);
+        CompilationTask task = compiler.getTask(null, fileManager, listener, args, null, fileList);
+        Boolean ret = task.call();
+        try {
+            fileManager.close();
+        } catch (IOException e) {
+            System.err.print("[ERROR] IOException during compiling.");
+            e.printStackTrace();
+        }
+        return ret;
+    }
+
+    public boolean internalCompile(String[] args, int sourceFileIndex) {
+        File tmpFile = null;
+        try {
+            final String[] cmdArray;
+            if (isLongCommandLines(args) && sourceFileIndex >= 0) {
+                tmpFile = FileUtils.createTempFile("cxf-compiler", null);
+                try (PrintWriter out = new PrintWriter(new FileWriter(tmpFile))) {
+                    for (int i = sourceFileIndex; i < args.length; i++) {
+                        if (args[i].indexOf(' ') > -1) {
+                            args[i] = args[i].replace(File.separatorChar, '/');
+                            //
+                            // javac gives an error if you use forward slashes
+                            // with package-info.java. Refer to:
+                            // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6198196
+                            //
+                            if (args[i].indexOf("package-info.java") > -1
+                                && SystemPropertyAction.getProperty("os.name")
+                                    .toLowerCase().indexOf("windows") > -1) {
+                                out.println('"' + args[i].replaceAll("/", "\\\\\\\\") + '"');
+                            } else {
+                                out.println('"' + args[i] + '"');
+                            }
+                        } else {
+                            out.println(args[i]);
+                        }
+                    }
+                    out.flush();
+                }
+                cmdArray = new String[sourceFileIndex + 1];
+                System.arraycopy(args, 0, cmdArray, 0, sourceFileIndex);
+                cmdArray[sourceFileIndex] = "@" + tmpFile;
+            } else {
+                cmdArray = new String[args.length];
+                System.arraycopy(args, 0, cmdArray, 0, args.length);
+            }
+
+            if (SystemPropertyAction.getProperty("os.name").toLowerCase().indexOf("windows") > -1) {
+                for (int i = 0; i < cmdArray.length; i++) {
+                    if (cmdArray[i].indexOf("package-info") == -1) {
+                        cmdArray[i] = cmdArray[i].replace('\\', '/');
+                    }
+                }
+            }
+
+            final Process p = Runtime.getRuntime().exec(cmdArray);
+
+            if (p.getErrorStream() != null) {
+                StreamPrinter errorStreamPrinter = new StreamPrinter(p.getErrorStream(), "", System.out);
+                errorStreamPrinter.start();
+            }
+
+            if (p.getInputStream() != null) {
+                StreamPrinter infoStreamPrinter = new StreamPrinter(p.getInputStream(), "[INFO]", System.out);
+                infoStreamPrinter.start();
+            }
+
+            return p.waitFor() == 0 ? true : false;
+        } catch (SecurityException e) {
+            System.err.println("[ERROR] SecurityException during exec() of compiler \"" + args[0] + "\".");
+        } catch (InterruptedException e) {
+            // ignore
+
+        } catch (IOException e) {
+            System.err.print("[ERROR] IOException during exec() of compiler \"" + args[0] + "\"");
+            System.err.println(". Check your path environment variable.");
+        } finally {
+            if (tmpFile != null && tmpFile.exists()) {
+                FileUtils.delete(tmpFile);
+            }
+            if (classpathTmpFile != null && classpathTmpFile.exists()) {
+                FileUtils.delete(classpathTmpFile);
+            }
+        }
+
+        return false;
+    }
+
+    private boolean isLongCommandLines(String[] args) {
+        StringBuilder strBuffer = new StringBuilder();
+        for (int i = 0; i < args.length; i++) {
+            strBuffer.append(args[i]);
+        }
+        return strBuffer.length() > 4096;
+    }
+
+    private boolean isLongClasspath(String classpath) {
+        return classpath.length() > 2048;
+    }
+
+    private void checkLongClasspath(String classpath, List<String> list, int classpathIdx) {
+        if (isLongClasspath(classpath)) {
+            try {
+                classpathTmpFile = FileUtils.createTempFile("cxf-compiler-classpath", null);
+                try (PrintWriter out = new PrintWriter(new FileWriter(classpathTmpFile))) {
+                    out.println(classpath);
+                    out.flush();
+                }
+                list.set(classpathIdx + 1, "@" + classpathTmpFile);
+            } catch (IOException e) {
+                System.err.print("[ERROR] can't write long classpath to @argfile");
+            }
+        }
+    }
+
+    public void setEncoding(String string) {
+        encoding = string;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/ModCountCopyOnWriteArrayList.java b/transform/src/patch/java/org/apache/cxf/common/util/ModCountCopyOnWriteArrayList.java
new file mode 100644
index 0000000..daa6407
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/ModCountCopyOnWriteArrayList.java
@@ -0,0 +1,156 @@
+/**
+ * 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.cxf.common.util;
+
+import java.util.Collection;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public final class ModCountCopyOnWriteArrayList<T> extends CopyOnWriteArrayList<T> {
+    private static final long serialVersionUID = 1783937035760941219L;
+    private AtomicInteger modCount = new AtomicInteger();
+
+    public ModCountCopyOnWriteArrayList() {
+        super();
+    }
+    public ModCountCopyOnWriteArrayList(Collection<? extends T> c) {
+        super(c);
+        if (c instanceof ModCountCopyOnWriteArrayList) {
+            modCount.set(((ModCountCopyOnWriteArrayList<?>)c).getModCount());
+        }
+    }
+
+    public int getModCount() {
+        return modCount.get();
+    }
+
+    public void setModCount(int i) {
+        modCount.set(i);
+    }
+
+    @Override
+    public void add(int index, T element) {
+        super.add(index, element);
+        modCount.incrementAndGet();
+    }
+
+    @Override
+    public boolean add(T element) {
+        if (super.add(element)) {
+            modCount.incrementAndGet();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean addAll(Collection<? extends T> c) {
+        if (super.addAll(c)) {
+            modCount.incrementAndGet();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean addAll(int index, Collection<? extends T> c) {
+        if (super.addAll(index, c)) {
+            modCount.incrementAndGet();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public int addAllAbsent(Collection<? extends T> c) {
+        int i = super.addAllAbsent(c);
+        if (i > 0) {
+            modCount.incrementAndGet();
+        }
+        return i;
+    }
+
+    @Override
+    public boolean addIfAbsent(T element) {
+        if (super.addIfAbsent(element)) {
+            modCount.incrementAndGet();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void clear() {
+        super.clear();
+        modCount.incrementAndGet();
+    }
+
+    @Override
+    public T remove(int index) {
+        T t = super.remove(index);
+        if (t != null) {
+            modCount.incrementAndGet();
+        }
+        return t;
+    }
+
+    @Override
+    public boolean remove(Object o) {
+        if (super.remove(o)) {
+            modCount.incrementAndGet();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean removeAll(Collection<?> c) {
+        if (super.removeAll(c)) {
+            modCount.incrementAndGet();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean retainAll(Collection<?> c) {
+        if (super.retainAll(c)) {
+            modCount.incrementAndGet();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() + modCount.get();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof ModCountCopyOnWriteArrayList) {
+            return super.equals(o) && modCount.get()
+                == ((ModCountCopyOnWriteArrayList<?>)o).getModCount();
+        }
+        return false;
+    }
+
+}
+
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/PackageUtils.java b/transform/src/patch/java/org/apache/cxf/common/util/PackageUtils.java
new file mode 100644
index 0000000..9d014c8
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/PackageUtils.java
@@ -0,0 +1,181 @@
+/**
+ * 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.cxf.common.util;
+
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.cxf.helpers.JavaUtils;
+
+
+public final class PackageUtils {
+
+    private PackageUtils() {
+
+    }
+
+    static String getPackageName(String className) {
+        int pos = className.lastIndexOf('.');
+        if (pos != -1) {
+            return className.substring(0, pos);
+        }
+        return "";
+    }
+
+    public static String getPackageName(Class<?> clazz) {
+        String className = clazz.getName();
+        if (className.startsWith("[L")) {
+            className = className.substring(2);
+        }
+        return getPackageName(className);
+    }
+
+    public static String getSharedPackageName(List<Class<?>> classes) {
+        if (classes.isEmpty()) {
+            return "";
+        }
+        List<List<String>> lParts = new ArrayList<>(classes.size());
+        List<String> currentParts = new ArrayList<>();
+        for (Class<?> cls : classes) {
+            if (!Proxy.isProxyClass(cls)) {
+                lParts.add(Arrays.asList(getPackageName(cls).split("\\.")));
+            }
+        }
+        for (int i = 0; i < lParts.get(0).size(); i++) {
+            int j = 1;
+            for (; j < lParts.size(); j++) {
+                if (i > (lParts.get(j).size() - 1) || !lParts.get(j).get(i).equals(lParts.get(0).get(i))) {
+                    break;
+                }
+            }
+            if (j == lParts.size()) {
+                currentParts.add(lParts.get(j - 1).get(i));
+            } else {
+                break;
+            }
+        }
+        return String.join(".", currentParts);
+    }
+
+    public static String parsePackageName(String namespace, String defaultPackageName) {
+        return (defaultPackageName != null && !defaultPackageName.trim().isEmpty())
+            ? defaultPackageName : getPackageNameByNameSpaceURI(namespace.trim());
+    }
+
+    public static String getPackageNameByNameSpaceURI(String nameSpaceURI) {
+        int idx = nameSpaceURI.indexOf(':');
+        boolean urnScheme = false;
+        if (idx >= 0) {
+            final String scheme = nameSpaceURI.substring(0, idx);
+            urnScheme = "urn".equalsIgnoreCase(scheme);
+            if ("http".equalsIgnoreCase(scheme) || urnScheme) {
+                nameSpaceURI = nameSpaceURI.substring(idx + (urnScheme ? 1 : 3)); //
+            }
+        }
+
+        List<String> tokens = tokenize(nameSpaceURI, "/:");
+        if (tokens.isEmpty()) {
+            return null;
+        }
+
+        if (tokens.size() > 1) {
+            String lastToken = tokens.get(tokens.size() - 1);
+            idx = lastToken.lastIndexOf('.');
+            if (idx > 0) {
+                lastToken = lastToken.replace('.', '_');
+                tokens.set(tokens.size() - 1, lastToken);
+            }
+        }
+
+        String domain = tokens.remove(0);
+        List<String> r = tokenize(domain, urnScheme ? ".-" : ".");
+        Collections.reverse(r);
+        if ("www".equalsIgnoreCase(r.get(r.size() - 1))) {
+            // remove leading www
+            r.remove(r.size() - 1);
+        }
+
+        // replace the domain name with tokenized items
+        tokens.addAll(0, r);
+
+        // iterate through the tokens and apply xml->java name algorithm
+        for (int i = 0; i < tokens.size(); i++) {
+
+            // get the token and remove illegal chars
+            String token = tokens.get(i);
+            token = removeIllegalIdentifierChars(token);
+
+            token = token.toLowerCase();
+
+            // this will check for reserved keywords
+            if (JavaUtils.isJavaKeyword(token)) {
+                token = '_' + token;
+            }
+
+            tokens.set(i, token);
+        }
+
+        // concat all the pieces and return it
+        return String.join(".", tokens);
+    }
+
+    private static List<String> tokenize(String str, String sep) {
+        StringTokenizer tokens = new StringTokenizer(str, sep);
+        List<String> r = new ArrayList<>();
+
+        while (tokens.hasMoreTokens()) {
+            r.add(tokens.nextToken());
+        }
+        return r;
+    }
+
+    private static String removeIllegalIdentifierChars(String token) {
+        StringBuilder newToken = new StringBuilder();
+        for (int i = 0; i < token.length(); i++) {
+            char c = token.charAt(i);
+
+            if (i == 0 && !Character.isJavaIdentifierStart(c)) {
+                // prefix an '_' if the first char is illegal
+                newToken.append('_').append(c);
+            } else if (!Character.isJavaIdentifierPart(c)) {
+                // replace the char with an '_' if it is illegal
+                newToken.append('_');
+            } else {
+                // add the legal char
+                newToken.append(c);
+            }
+        }
+        return newToken.toString();
+    }
+
+    public static String getNamespace(String packageName) {
+        if (packageName == null || packageName.isEmpty()) {
+            return null;
+        }
+        final List<String> parts = Arrays.asList(packageName.split("\\."));
+        Collections.reverse(parts);
+        return "http://" + String.join(".", parts) + '/';
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/ProxyClassLoader.java b/transform/src/patch/java/org/apache/cxf/common/util/ProxyClassLoader.java
new file mode 100644
index 0000000..073ca46
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/ProxyClassLoader.java
@@ -0,0 +1,89 @@
+/**
+ * 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.cxf.common.util;
+
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Utility class loader that can be used to create proxies in cases where
+ * the the client classes are not visible to the loader of the
+ * service class.
+ */
+public class ProxyClassLoader extends ClassLoader {
+    private final Class<?>[] classes;
+    private final Set<ClassLoader> loaders = new HashSet<>();
+    private boolean checkSystem;
+
+    public ProxyClassLoader(ClassLoader parent) {
+        super(parent);
+        classes = null;
+    }
+
+    public ProxyClassLoader(ClassLoader parent, Class<?>[] cls) {
+        super(parent);
+        classes = cls;
+    }
+
+    public void addLoader(ClassLoader loader) {
+        if (loader == null) {
+            checkSystem = true;
+        } else {
+            loaders.add(loader);
+        }
+    }
+
+    @Override
+    public Class<?> findClass(String name) throws ClassNotFoundException {
+        if (classes != null) {
+            for (Class<?> c : classes) {
+                if (name.equals(c.getName())) {
+                    return c;
+                }
+            }
+        }
+        for (ClassLoader loader : loaders) {
+            try {
+                return loader.loadClass(name);
+            } catch (ClassNotFoundException | NoClassDefFoundError cnfe) {
+                // Try next
+            }
+        }
+        if (checkSystem) {
+            try {
+                return getSystemClassLoader().loadClass(name);
+            } catch (ClassNotFoundException | NoClassDefFoundError cnfe) {
+                // Try next
+            }
+        }
+        throw new ClassNotFoundException(name);
+    }
+
+    @Override
+    public URL findResource(String name) {
+        for (ClassLoader loader : loaders) {
+            URL url = loader.getResource(name);
+            if (url != null) {
+                return url;
+            }
+        }
+        return null;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/ProxyHelper.java b/transform/src/patch/java/org/apache/cxf/common/util/ProxyHelper.java
new file mode 100644
index 0000000..380e2bb
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/ProxyHelper.java
@@ -0,0 +1,140 @@
+/**
+ * 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.cxf.common.util;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+
+/**
+ *
+ */
+public class ProxyHelper {
+    static final ProxyHelper HELPER;
+    static {
+        ProxyHelper theHelper;
+        try {
+            theHelper = new CglibProxyHelper();
+        } catch (Throwable ex) {
+            theHelper = new ProxyHelper();
+        }
+        HELPER = theHelper;
+    }
+   
+    private static final Logger LOG = LogUtils.getL7dLogger(ProxyHelper.class);
+    
+    protected ProxyClassLoaderCache proxyClassLoaderCache = 
+        new ProxyClassLoaderCache();
+      
+    
+    protected ProxyHelper() {
+    }
+
+    protected Object getProxyInternal(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) {
+        ClassLoader combinedLoader = getClassLoaderForInterfaces(loader, interfaces);
+        return Proxy.newProxyInstance(combinedLoader, interfaces, handler);
+    }
+
+    /**
+     * Return a classloader that can see all the given interfaces If the given loader can see all interfaces
+     * then it is used. If not then a combined classloader of all interface classloaders is returned.
+     *
+     * @param loader use supplied class loader
+     * @param interfaces
+     * @return classloader that sees all interfaces
+     */
+    private ClassLoader getClassLoaderForInterfaces(final ClassLoader loader, final Class<?>[] interfaces) {
+        if (canSeeAllInterfaces(loader, interfaces)) {
+            LOG.log(Level.FINE, "current classloader " + loader + " can see all interface");
+            return loader;
+        }
+        String sortedNameFromInterfaceArray = getSortedNameFromInterfaceArray(interfaces);
+        ClassLoader cachedLoader = proxyClassLoaderCache.getProxyClassLoader(loader, interfaces);
+        if (canSeeAllInterfaces(cachedLoader, interfaces)) {
+            LOG.log(Level.FINE, "find required loader from ProxyClassLoader cache with key" 
+                 + sortedNameFromInterfaceArray);
+            return cachedLoader;
+        } else {
+            LOG.log(Level.FINE, "find a loader from ProxyClassLoader cache with interfaces " 
+                + sortedNameFromInterfaceArray
+                + " but can't see all interfaces");
+            for (Class<?> currentInterface : interfaces) {
+                String ifName = currentInterface.getName();
+                
+                if (!ifName.startsWith("org.apache.cxf") && !ifName.startsWith("java")) {
+                    // remove the stale ProxyClassLoader and recreate one
+                    proxyClassLoaderCache.removeStaleProxyClassLoader(currentInterface);
+                    cachedLoader = proxyClassLoaderCache.getProxyClassLoader(loader, interfaces);
+                    
+                }
+            }
+        }
+               
+        return cachedLoader;
+    }
+    
+    private String getSortedNameFromInterfaceArray(Class<?>[] interfaces) {
+        SortedArraySet<String> arraySet = new SortedArraySet<>();
+        for (Class<?> currentInterface : interfaces) {
+            arraySet.add(currentInterface.getName() + ClassLoaderUtils.getClassLoaderName(currentInterface));
+        }
+        return arraySet.toString();
+    }
+
+
+    private boolean canSeeAllInterfaces(ClassLoader loader, Class<?>[] interfaces) {
+        for (Class<?> currentInterface : interfaces) {
+            String ifName = currentInterface.getName();
+            try {
+                Class<?> ifClass = Class.forName(ifName, true, loader);
+                if (ifClass != currentInterface) {
+                    return false;
+                }
+                //we need to check all the params/returns as well as the Proxy creation
+                //will try to create methods for all of this even if they aren't used
+                //by the client and not available in the clients classloader
+                for (Method m : ifClass.getMethods()) {
+                    Class<?> returnType = m.getReturnType();
+                    if (!returnType.isPrimitive()) {
+                        Class.forName(returnType.getName(), true, loader);
+                    }
+                    for (Class<?> p : m.getParameterTypes()) {
+                        if (!p.isPrimitive()) {
+                            Class.forName(p.getName(), true, loader);
+                        }
+                    }
+                }
+            } catch (NoClassDefFoundError | ClassNotFoundException e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static Object getProxy(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) {
+        return HELPER.getProxyInternal(loader, interfaces, handler);
+    }
+    
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/ReflectionInvokationHandler.java b/transform/src/patch/java/org/apache/cxf/common/util/ReflectionInvokationHandler.java
new file mode 100644
index 0000000..1b4d904
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/ReflectionInvokationHandler.java
@@ -0,0 +1,199 @@
+/**
+ * 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.cxf.common.util;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Iterator;
+
+/**
+ *
+ */
+public class ReflectionInvokationHandler implements InvocationHandler {
+    private Object target;
+
+    public ReflectionInvokationHandler(Object obj) {
+        target = obj;
+    }
+
+    public Object getTarget() {
+        return target;
+    }
+
+    /** {@inheritDoc}*/
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        WrapReturn wr = method.getAnnotation(WrapReturn.class);
+        final Class<?> targetClass = target.getClass();
+        final Class<?>[] parameterTypes = getParameterTypes(method, args);
+        try {
+            Method m;
+            try {
+                m = targetClass.getMethod(method.getName(), parameterTypes);
+            } catch (NoSuchMethodException nsme) {
+
+                boolean[] optionals = new boolean[method.getParameterTypes().length];
+                int i = 0;
+                int optionalNumber = 0;
+                for (final Annotation[] a : method.getParameterAnnotations()) {
+                    optionals[i] = false;
+                    for (final Annotation potential : a) {
+                        if (Optional.class.equals(potential.annotationType())) {
+                            optionals[i] = true;
+                            optionalNumber++;
+                            break;
+                        }
+                    }
+                    i++;
+                }
+
+                Class<?>[] newParams = new Class<?>[args.length - optionalNumber];
+                Object[] newArgs = new Object[args.length - optionalNumber];
+                int argI = 0;
+                for (int j = 0; j < parameterTypes.length; j++) {
+                    if (optionals[j]) {
+                        continue;
+                    }
+                    newArgs[argI] = args[j];
+                    newParams[argI] = parameterTypes[j];
+                    argI++;
+                }
+                m = targetClass.getMethod(method.getName(), newParams);
+                args = newArgs;
+            }
+            ReflectionUtil.setAccessible(m);
+            return wrapReturn(wr, m.invoke(target, args));
+        } catch (InvocationTargetException e) {
+            throw e.getCause();
+        } catch (NoSuchMethodException e) {
+            for (Method m2 : targetClass.getMethods()) {
+                if (m2.getName().equals(method.getName())
+                    && m2.getParameterTypes().length == method.getParameterTypes().length) {
+                    boolean found = true;
+                    for (int x = 0; x < m2.getParameterTypes().length; x++) {
+                        if (args[x] != null
+                            && !m2.getParameterTypes()[x].isInstance(args[x])) {
+                            found = false;
+                        }
+                    }
+                    if (found) {
+                        ReflectionUtil.setAccessible(m2);
+                        return wrapReturn(wr, m2.invoke(target, args));
+                    }
+                }
+            }
+            throw e;
+        }
+    }
+    private Class<?>[] getParameterTypes(Method method, Object[] args) {
+        Class<?>[] types = method.getParameterTypes();
+        final Annotation[][] parAnnotations = method.getParameterAnnotations();
+        for (int x = 0; x < types.length; x++) {
+            UnwrapParam p = getUnwrapParam(parAnnotations[x]);
+            if (p != null) {
+                String s = p.methodName();
+                String tn = p.typeMethodName();
+                try {
+                    Method m = args[x].getClass().getMethod(s);
+                    if ("#default".equals(tn)) {
+                        types[x] = m.getReturnType();
+                    } else {
+                        Method m2 = args[x].getClass().getMethod(tn);
+                        types[x] = (Class<?>)ReflectionUtil.setAccessible(m2).invoke(args[x]);
+                    }
+                    args[x] = ReflectionUtil.setAccessible(m).invoke(args[x]);
+                } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        }
+        return types;
+    }
+
+    private UnwrapParam getUnwrapParam(Annotation[] annotations) {
+        for (Annotation a : annotations) {
+            if (a instanceof UnwrapParam) {
+                return (UnwrapParam)a;
+            }
+        }
+        return null;
+    }
+
+    private static Object wrapReturn(WrapReturn wr, Object t) {
+        if (wr == null || t == null) {
+            return t;
+        }
+        if (wr.iterator()) {
+            return new WrapperIterator(wr.value(), (Iterator<?>)t);
+        }
+        return createProxyWrapper(t, wr.value());
+    }
+
+    public static <T> T createProxyWrapper(Object target, Class<T> inf) {
+        InvocationHandler h = new ReflectionInvokationHandler(target);
+        return inf.cast(Proxy.newProxyInstance(inf.getClassLoader(), new Class<?>[] {inf}, h));
+    }
+
+    @Target(ElementType.PARAMETER)
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Optional {
+    }
+
+    @Target(ElementType.METHOD)
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface WrapReturn {
+        Class<?> value();
+        boolean iterator() default false;
+    }
+
+    @Target(ElementType.PARAMETER)
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface UnwrapParam {
+        String methodName() default "getValue";
+        String typeMethodName() default "#default";
+    }
+
+    private static class WrapperIterator implements Iterator<Object> {
+        Class<?> cls;
+        Iterator<?> internal;
+        WrapperIterator(Class<?> c, Iterator<?> it) {
+            internal = it;
+            cls = c;
+        }
+        public boolean hasNext() {
+            return internal.hasNext();
+        }
+        public Object next() {
+            Object obj = internal.next();
+            return createProxyWrapper(obj, cls);
+        }
+        
+        @Override
+        public void remove() {
+            internal.remove();
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/SortedArraySet.java b/transform/src/patch/java/org/apache/cxf/common/util/SortedArraySet.java
new file mode 100644
index 0000000..9c2b139
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/SortedArraySet.java
@@ -0,0 +1,266 @@
+/**
+ * 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.cxf.common.util;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.SortedSet;
+import java.util.concurrent.atomic.AtomicReference;
+
+
+/**
+ * This class implements most of the <tt>Set</tt> interface, backed by a
+ * sorted Array.  This makes iterators very fast, lookups are log(n), but
+ * adds are fairly expensive.
+ *
+ * This class is also threadsafe, but without synchronizations.   Lookups
+ * and iterators will iterate over the state of the Set when the iterator
+ * was created.
+ *
+ * If no data is stored in the Set, it uses very little memory.  The backing
+ * array is created on demand.
+ *
+ * This class is primarly useful for stuff that will be setup at startup, but
+ * then iterated over MANY times during runtime.
+ *
+ * @param <T>
+ */
+public final class SortedArraySet<T> implements SortedSet<T> {
+    final AtomicReference<T[]> data = new AtomicReference<>();
+
+    public void clear() {
+        data.set(null);
+    }
+
+    public boolean isEmpty() {
+        T[] tmp = data.get();
+        return tmp == null || tmp.length == 0;
+    }
+
+    public Iterator<T> iterator() {
+        return new SASIterator<>(data.get());
+    }
+
+    public int size() {
+        T[] tmp = data.get();
+        return tmp == null ? 0 : tmp.length;
+    }
+
+    @SuppressWarnings("unchecked")
+    private T[] newArray(int size) {
+        return (T[])new Object[size];
+    }
+
+    public boolean add(T o) {
+        if (!contains(o)) {
+            T[] tmp = data.get();
+            T[] tmp2;
+            if (tmp == null) {
+                tmp2 = newArray(1);
+                tmp2[0] = o;
+            } else {
+                tmp2 = newArray(tmp.length + 1);
+                System.arraycopy(tmp, 0, tmp2, 0, tmp.length);
+                tmp2[tmp2.length - 1] = o;
+                Arrays.sort(tmp2);
+            }
+
+            if (!data.compareAndSet(tmp, tmp2)) {
+                return add(o);
+            }
+            return true;
+        }
+        return false;
+    }
+    public boolean addAll(Collection<? extends T> c) {
+        boolean val = false;
+        for (T t : c) {
+            val |= add(t);
+        }
+        return val;
+    }
+    public boolean containsAll(Collection<?> c) {
+        boolean val = false;
+        for (Object t : c) {
+            val |= contains(t);
+        }
+        return val;
+    }
+
+    public boolean contains(Object o) {
+        T[] tmp = data.get();
+        if (tmp == null) {
+            return false;
+        }
+        return Arrays.binarySearch(tmp, o) >= 0;
+    }
+
+    public boolean removeAll(Collection<?> c) {
+        boolean val = false;
+        for (Object t : c) {
+            val |= remove(t);
+        }
+        return val;
+    }
+    public boolean retainAll(Collection<?> c) {
+        boolean val = false;
+        for (T t : this) {
+            if (!c.contains(t)) {
+                val |= remove(t);
+            }
+        }
+        return val;
+    }
+
+    public boolean remove(Object o) {
+        T[] tmp = data.get();
+
+        if (tmp == null) {
+            return false;
+        }
+        int idx = Arrays.binarySearch(tmp, o);
+        if (idx != -1) {
+            if (tmp.length == 1
+                && !data.compareAndSet(tmp, null)) {
+                return remove(o);
+            }
+            T[] tmp2 = newArray(tmp.length - 1);
+            System.arraycopy(tmp, 0, tmp2, 0, idx);
+            System.arraycopy(tmp, idx + 1, tmp2, idx, tmp.length - 1 - idx);
+            if (!data.compareAndSet(tmp, tmp2)) {
+                return remove(o);
+            }
+            return true;
+        }
+        return false;
+    }
+
+
+    public Object[] toArray() {
+        T[] tmp = data.get();
+        if (tmp == null) {
+            return new Object[0];
+        }
+        T[] tmp2 = newArray(tmp.length);
+        System.arraycopy(tmp, 0, tmp2, 0, tmp.length);
+        return tmp2;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <X> X[] toArray(X[] a) {
+        T[] tmp = data.get();
+        if (tmp == null) {
+            if (a.length != 0) {
+                return (X[])java.lang.reflect.Array.
+                    newInstance(a.getClass().getComponentType(), 0);
+            }
+            return a;
+        }
+
+        if (a.length < tmp.length) {
+            a = (X[])java.lang.reflect.Array.
+                newInstance(a.getClass().getComponentType(), tmp.length);
+        }
+        System.arraycopy(tmp, 0, a, 0, tmp.length);
+        if (a.length > tmp.length) {
+            a[tmp.length] = null;
+        }
+        return a;
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean equals(Object o) {
+        if (!(o instanceof SortedArraySet)) {
+            return false;
+        }
+        SortedArraySet<T> as = (SortedArraySet<T>)o;
+        return Arrays.equals(data.get(), as.data.get());
+    }
+    public String toString() {
+        return Arrays.toString(data.get());
+    }
+    public int hashCode() {
+        return Arrays.hashCode(data.get());
+    }
+
+
+    private class SASIterator<X> implements Iterator<X> {
+        final X[] data;
+        int idx;
+
+        SASIterator(X[] d) {
+            data = d;
+        }
+
+        public boolean hasNext() {
+            return data != null && idx != data.length;
+        }
+
+        public X next() {
+            if (data == null || idx == data.length) {
+                throw new NoSuchElementException();
+            }
+            return data[idx++];
+        }
+
+        @Override
+        public void remove() {
+            if (idx > 0) {
+                SortedArraySet.this.remove((Object)data[idx - 1]);
+            }
+        }
+    }
+
+
+    public Comparator<? super T> comparator() {
+        return null;
+    }
+
+    public T first() {
+        T[] tmp = data.get();
+        if (tmp == null || tmp.length == 0) {
+            return null;
+        }
+        return tmp[0];
+    }
+
+    public T last() {
+        T[] tmp = data.get();
+        if (tmp == null || tmp.length == 0) {
+            return null;
+        }
+        return tmp[tmp.length - 1];
+    }
+
+    public SortedSet<T> headSet(T toElement) {
+        throw new UnsupportedOperationException();
+    }
+
+    public SortedSet<T> subSet(T fromElement, T toElement) {
+        throw new UnsupportedOperationException();
+    }
+
+    public SortedSet<T> tailSet(T fromElement) {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/SpringClassUnwrapper.java b/transform/src/patch/java/org/apache/cxf/common/util/SpringClassUnwrapper.java
new file mode 100644
index 0000000..a196eb0
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/SpringClassUnwrapper.java
@@ -0,0 +1,111 @@
+/**
+ * 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.cxf.common.util;
+
+import org.springframework.aop.TargetSource;
+import org.springframework.aop.framework.Advised;
+import org.springframework.aop.support.AopUtils;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.util.ClassUtils;
+
+/**
+ *
+ */
+class SpringClassUnwrapper implements ClassUnwrapper {
+    SpringClassUnwrapper() throws ClassNotFoundException {
+        Class.forName("org.springframework.aop.support.AopUtils");
+        Class.forName("org.springframework.aop.framework.Advised");
+    }
+
+    @Override
+    public Class<?> getRealClassFromClass(Class<?> cls) {
+        if (ClassUtils.isCglibProxyClass(cls)) {
+            final Class<?> superclass = cls.getSuperclass();
+            // Lambda's generated class names also contain $$ which makes them trigger CGLIB
+            // proxy path. Adding more checks to handle this particular case.
+            if (superclass != null && (superclass != Object.class || wasCglibEnhanced(cls))) {
+                return getRealClassFromClass(superclass);
+            }
+        }
+        return cls;
+    }
+
+    @Override
+    public Object getRealObject(Object o) {
+        if (o instanceof Advised) {
+            try {
+
+                Advised advised = (Advised)o;
+                Object target = advised.getTargetSource().getTarget();
+                //could be a proxy of a proxy.....
+                return getRealObject(target);
+            } catch (Exception ex) {
+                // ignore
+            }
+        }
+        return o;
+    }
+
+    @Override
+    public Class<?> getRealClass(Object o) {
+        if (AopUtils.isAopProxy(o) && (o instanceof Advised)) {
+            Advised advised = (Advised)o;
+            try {
+                TargetSource targetSource = advised.getTargetSource();
+
+                final Object target;
+                try {
+                    target = targetSource.getTarget();
+                } catch (BeanCreationException ex) {
+                    // some scopes such as 'request' may not
+                    // be active on the current thread yet
+                    return getRealClassFromClass(targetSource.getTargetClass());
+                }
+
+                if (target == null) {
+                    Class<?> targetClass = AopUtils.getTargetClass(o);
+                    if (targetClass != null) {
+                        return getRealClassFromClass(targetClass);
+                    }
+                } else {
+                    return getRealClass(target);
+                }
+            } catch (Exception ex) {
+                // ignore
+            }
+
+        } else if (ClassUtils.isCglibProxyClass(o.getClass())) {
+            return getRealClassFromClass(AopUtils.getTargetClass(o));
+        }
+        
+        return o.getClass();
+    }
+
+    /**
+     * This additional check is not very reliable since CGLIB allows to
+     * supply own NamingPolicy implementations. However, it works with native
+     * CGLIB proxies ("byCGLIB$$") as well as Spring CGLIB proxies (by "BySpringCGLIB$$").
+     * More expensive approach is to use reflection and inspect the class declared methods, 
+     * looking for CGLIB-specific ones like CGLIB$BIND_CALLBACKS. 
+     */
+    private static boolean wasCglibEnhanced(Class<?> cls) {
+        return cls.getName().contains("CGLIB");
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/SpringClasspathScanner.java b/transform/src/patch/java/org/apache/cxf/common/util/SpringClasspathScanner.java
new file mode 100644
index 0000000..9113d77
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/SpringClasspathScanner.java
@@ -0,0 +1,202 @@
+/**
+ * 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.cxf.common.util;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.util.ClassUtils;
+
+class SpringClasspathScanner extends ClasspathScanner {
+
+    private static final boolean IN_OSGI =  isSpringInOsgi();
+    
+    
+    SpringClasspathScanner() throws Exception {
+        Class.forName("org.springframework.core.io.support.PathMatchingResourcePatternResolver");
+        Class.forName("org.springframework.core.type.classreading.CachingMetadataReaderFactory");
+    }
+    private static boolean isSpringInOsgi() {
+        try {
+            Class.forName("org.springframework.osgi.io.OsgiBundleResourcePatternResolver");
+            Class.forName("org.springframework.osgi.util.BundleDelegatingClassLoader");
+            return true;
+        } catch (Throwable ex) {
+            return false;
+        }
+    }
+
+    @Override
+    protected Map< Class< ? extends Annotation >, Collection< Class< ? > > > findClassesInternal(
+        Collection< String > basePackages,
+        List<Class< ? extends Annotation > > annotations,
+        ClassLoader loader)
+        throws IOException, ClassNotFoundException {
+
+        ResourcePatternResolver resolver = getResolver(loader);
+        MetadataReaderFactory factory = new CachingMetadataReaderFactory(resolver);
+
+        final Map< Class< ? extends Annotation >, Collection< Class< ? > > > classes =
+            new HashMap<>();
+        final Map< Class< ? extends Annotation >, Collection< String > > matchingInterfaces =
+            new HashMap<>();
+        final Map<String, String[]> nonMatchingClasses = new HashMap<>();
+
+        for (Class< ? extends Annotation > annotation: annotations) {
+            classes.put(annotation, new HashSet<>());
+            matchingInterfaces.put(annotation, new HashSet<>());
+        }
+
+        if (basePackages == null || basePackages.isEmpty()) {
+            return classes;
+        }
+
+        for (final String basePackage: basePackages) {
+            final boolean scanAllPackages = basePackage.equals(WILDCARD);
+            final String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+                + (scanAllPackages ? "" : ClassUtils.convertClassNameToResourcePath(basePackage))
+                + ALL_CLASS_FILES;
+
+            final Resource[] resources = resolver.getResources(packageSearchPath);
+
+
+            for (final Resource resource: resources) {
+                final MetadataReader reader = factory.getMetadataReader(resource);
+                final AnnotationMetadata metadata = reader.getAnnotationMetadata();
+
+                if (scanAllPackages && shouldSkip(metadata.getClassName())) {
+                    continue;
+                }
+
+                for (Class< ? extends Annotation > annotation: annotations) {
+                    boolean concreteClass = !metadata.isInterface() && !metadata.isAbstract();
+                    if (metadata.isAnnotated(annotation.getName())) {
+                        if (concreteClass) {
+                            classes.get(annotation).add(loadClass(metadata.getClassName(), loader));
+                        } else {
+                            matchingInterfaces.get(annotation).add(metadata.getClassName());
+                        }
+                    } else if (concreteClass && metadata.getInterfaceNames().length > 0) {
+                        nonMatchingClasses.put(metadata.getClassName(), metadata.getInterfaceNames());
+                    }
+                }
+            }
+        }
+        if (!nonMatchingClasses.isEmpty()) {
+            for (Map.Entry<Class<? extends Annotation>, Collection<String>> e1 : matchingInterfaces.entrySet()) {
+                for (Map.Entry<String, String[]> e2 : nonMatchingClasses.entrySet()) {
+                    for (String intName : e2.getValue()) {
+                        if (e1.getValue().contains(intName)) {
+                            classes.get(e1.getKey()).add(loadClass(e2.getKey(), loader));
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        for (Map.Entry<Class<? extends Annotation>, Collection<String>> e : matchingInterfaces.entrySet()) {
+            if (classes.get(e.getKey()).isEmpty()) {
+                for (String intName : e.getValue()) {
+                    classes.get(e.getKey()).add(loadClass(intName, loader));
+                }
+            }
+        }
+
+        return classes;
+    }
+
+    @Override
+    protected List<URL> findResourcesInternal(Collection<String> basePackages,
+                                              String extension,
+                                              ClassLoader loader)
+        throws IOException {
+        final List<URL> resourceURLs = new ArrayList<>();
+        if (basePackages == null || basePackages.isEmpty()) {
+            return resourceURLs;
+        }
+        ResourcePatternResolver resolver = getResolver(loader);
+
+        for (final String basePackage: basePackages) {
+            final boolean scanAllPackages = basePackage.equals(WILDCARD);
+
+            String theBasePackage = basePackage;
+            if (theBasePackage.startsWith(CLASSPATH_URL_SCHEME)) {
+                theBasePackage = theBasePackage.substring(CLASSPATH_URL_SCHEME.length());
+            }
+
+            final String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+                + (scanAllPackages ? "" : basePackage.contains(WILDCARD) ? basePackage
+                    : ClassUtils.convertClassNameToResourcePath(theBasePackage)) + ALL_FILES + "." + extension;
+
+            final Resource[] resources = resolver.getResources(packageSearchPath);
+            for (final Resource resource: resources) {
+                resourceURLs.add(resource.getURL());
+            }
+        }
+
+        return resourceURLs;
+    }
+
+    private ResourcePatternResolver getResolver(ClassLoader loader) {
+        ResourcePatternResolver resolver = null;
+        
+        if (IN_OSGI) {
+            resolver = SpringOsgiUtil.getResolver(loader);
+        }
+        if (resolver == null) {
+            resolver = loader != null
+                ? new PathMatchingResourcePatternResolver(loader) : new PathMatchingResourcePatternResolver();
+        }
+        return resolver;
+    }
+
+    private boolean shouldSkip(final String classname) {
+        for (String packageToSkip: PACKAGES_TO_SKIP) {
+            if (classname.startsWith(packageToSkip)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private Class<?> loadClass(String className, ClassLoader loader)
+        throws ClassNotFoundException {
+        if (loader == null) {
+            return ClassLoaderUtils.loadClass(className, getClass());
+        }
+        return loader.loadClass(className);
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/StreamPrinter.java b/transform/src/patch/java/org/apache/cxf/common/util/StreamPrinter.java
new file mode 100644
index 0000000..fa88287
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/StreamPrinter.java
@@ -0,0 +1,63 @@
+/**
+ * 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.cxf.common.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+class StreamPrinter extends Thread {
+    private InputStream is;
+    private String msg;
+    private OutputStream os;
+
+    StreamPrinter(InputStream stream, String type, OutputStream redirect) {
+        is = stream;
+        msg = type;
+        os = redirect;
+    }
+
+    @Override
+    public void run() {
+        try {
+            PrintWriter pw = null;
+            if (os != null) {
+                pw = new PrintWriter(os);
+            }
+            InputStreamReader isr = new InputStreamReader(is);
+            BufferedReader br = new BufferedReader(isr);
+            String line = br.readLine();
+            while (line != null) {
+                if (pw != null) {
+                    pw.println(msg + " " + line);
+                }
+                line = br.readLine();
+            }
+            if (pw != null) {
+                pw.flush();
+            }
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/util/URIParserUtil.java b/transform/src/patch/java/org/apache/cxf/common/util/URIParserUtil.java
new file mode 100644
index 0000000..462896f
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/util/URIParserUtil.java
@@ -0,0 +1,209 @@
+/**
+ * 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.cxf.common.util;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.StringTokenizer;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+
+public final class URIParserUtil {
+    private static final String EXCLUDED_CHARS = "<>\"{}|\\^`";
+
+    private URIParserUtil() {
+        // complete
+    }
+
+    private static boolean isExcluded(char ch) {
+        return ch <= 0x20 || ch >= 0x7F || EXCLUDED_CHARS.indexOf(ch) != -1;
+    }
+
+    public static URL[] pathToURLs(String path) {
+        StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
+        URL[] urls = new URL[st.countTokens()];
+        int count = 0;
+        while (st.hasMoreTokens()) {
+            File file = new File(st.nextToken());
+            URL url = null;
+            try {
+                url = file.toURI().toURL();
+            } catch (MalformedURLException e) {
+                e.printStackTrace();
+            }
+            if (url != null) {
+                urls[count++] = url;
+            }
+        }
+        if (urls.length != count) {
+            URL[] tmp = new URL[count];
+            System.arraycopy(urls, 0, tmp, 0, count);
+            urls = tmp;
+        }
+        return urls;
+    }
+
+    public static String escapeChars(String s) {
+        StringBuilder sb = new StringBuilder(s.length());
+
+        for (int x = 0; x < s.length(); x++) {
+            char ch = s.charAt(x);
+            if (isExcluded(ch)) {
+                byte[] bytes = Character.toString(ch).getBytes(StandardCharsets.UTF_8);
+                for (byte b : bytes) {
+                    sb.append('%');
+                    StringUtils.byteToHex(b, sb);
+                }
+            } else {
+                sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+    public static String normalize(final String uri) {
+        URL url = null;
+        String result;
+        try {
+            url = new URL(uri);
+            result = escapeChars(url.toURI().normalize().toString().replace('\\', '/'));
+        } catch (MalformedURLException e1) {
+            try {
+                if (uri.startsWith("classpath:")) {
+                    url = ClassLoaderUtils.getResource(uri.substring(10), URIParserUtil.class);
+                    return url != null ? url.toExternalForm() : uri;
+                }
+                File file = new File(uri);
+                if (file.exists()) {
+                    return file.toURI().normalize().toString();
+                }
+                final String f;
+                if (uri.indexOf(':') != -1 && !uri.startsWith("/")) {
+                    f = "file:/" + uri;
+                } else {
+                    f = "file:" + uri;
+                }
+                url = new URL(f);
+                return escapeChars(url.toString().replace("\\", "/"));
+            } catch (Exception e2) {
+                return escapeChars(uri.replace("\\", "/"));
+            }
+        } catch (URISyntaxException e) {
+            result = escapeChars(url.toString().replace("\\", "/"));
+        }
+        return result;
+    }
+
+    public static String getAbsoluteURI(final String arg) {
+        if (arg == null) {
+            return null;
+        }
+
+        try {
+            URI uri = new URI(arg);
+            if ("file".equalsIgnoreCase(uri.getScheme())) {
+                if (!uri.isOpaque()) {
+                    return uri.normalize().toString();
+                }
+                return new File("").toURI().resolve(uri.getPath()).toString();
+            }
+            return normalize(arg);
+        } catch (Exception e2) {
+            return normalize(arg);
+        }
+    }
+
+    public static String relativize(String base, String toBeRelativized) throws URISyntaxException {
+        if (base == null || toBeRelativized == null) {
+            return null;
+        }
+        return relativize(new URI(base), new URI(toBeRelativized));
+    }
+
+    /**
+     * This is a custom implementation for doing what URI.relativize(URI uri) should be
+     * doing but is not actually doing when URI roots do not fully match.
+     * See http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6226081
+     *
+     * @param baseURI              The base URI
+     * @param toBeRelativizedURI   The URI to be relativized
+     * @return                  The string value of the URI you'd expect to get as result
+     *                          of calling baseURI.relativize(toBeRelativizedURI).
+     *                          null is returned if the parameters are null or are not
+     *                          both absolute or not absolute.
+     * @throws URISyntaxException
+     */
+    public static String relativize(URI baseURI, URI toBeRelativizedURI) throws URISyntaxException {
+        if (baseURI == null || toBeRelativizedURI == null) {
+            return null;
+        }
+        if (baseURI.isAbsolute() ^ toBeRelativizedURI.isAbsolute()) {
+            return null;
+        }
+        final String base = baseURI.getSchemeSpecificPart();
+        final String toBeRelativized = toBeRelativizedURI.getSchemeSpecificPart();
+        final int l1 = base.length();
+        final int l2 = toBeRelativized.length();
+        if (l1 == 0) {
+            return toBeRelativized;
+        }
+        int slashes = 0;
+        StringBuilder sb = new StringBuilder();
+        boolean differenceFound = false;
+        for (int i = 0; i < l1; i++) {
+            char c = base.charAt(i);
+            if (i < l2) {
+                if (!differenceFound && c == toBeRelativized.charAt(i)) {
+                    sb.append(c);
+                } else {
+                    differenceFound = true;
+                    if (c == '/') {
+                        slashes++;
+                    }
+                }
+            } else {
+                if (c == '/') {
+                    slashes++;
+                }
+            }
+        }
+        String rResolved = new URI(getRoot(sb.toString())).relativize(new URI(toBeRelativized)).toString();
+        StringBuilder relativizedPath = new StringBuilder();
+        for (int i = 0; i < slashes; i++) {
+            relativizedPath.append("../");
+        }
+        relativizedPath.append(rResolved);
+        return relativizedPath.toString();
+    }
+
+    private static String getRoot(String uri) {
+        int idx = uri.lastIndexOf('/');
+        if (idx == uri.length() - 1) {
+            return uri;
+        } else if (idx == -1) {
+            return "";
+        } else {
+            return uri.substring(0, idx + 1);
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/common/xmlschema/SchemaCollection.java b/transform/src/patch/java/org/apache/cxf/common/xmlschema/SchemaCollection.java
new file mode 100644
index 0000000..0f3a579
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/common/xmlschema/SchemaCollection.java
@@ -0,0 +1,389 @@
+/**
+ * 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.cxf.common.xmlschema;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaAll;
+import org.apache.ws.commons.schema.XmlSchemaAttribute;
+import org.apache.ws.commons.schema.XmlSchemaAttributeGroupRef;
+import org.apache.ws.commons.schema.XmlSchemaAttributeOrGroupRef;
+import org.apache.ws.commons.schema.XmlSchemaChoice;
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaComplexContentExtension;
+import org.apache.ws.commons.schema.XmlSchemaComplexContentRestriction;
+import org.apache.ws.commons.schema.XmlSchemaComplexType;
+import org.apache.ws.commons.schema.XmlSchemaContent;
+import org.apache.ws.commons.schema.XmlSchemaContentModel;
+import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.XmlSchemaParticle;
+import org.apache.ws.commons.schema.XmlSchemaSequence;
+import org.apache.ws.commons.schema.XmlSchemaSequenceMember;
+import org.apache.ws.commons.schema.XmlSchemaSimpleContentExtension;
+import org.apache.ws.commons.schema.XmlSchemaSimpleContentRestriction;
+import org.apache.ws.commons.schema.XmlSchemaType;
+import org.apache.ws.commons.schema.extensions.ExtensionRegistry;
+import org.apache.ws.commons.schema.resolver.URIResolver;
+import org.apache.ws.commons.schema.utils.NamespaceMap;
+import org.apache.ws.commons.schema.utils.NamespacePrefixList;
+import org.apache.ws.commons.schema.utils.XmlSchemaObjectBase;
+
+/**
+ * Wrapper class for XmlSchemaCollection that deals with various quirks and bugs.
+ */
+public class SchemaCollection {
+
+    private final XmlSchemaCollection xmlSchemaCollection;
+    private final Map<XmlSchema, Set<XmlSchemaType>> xmlTypesCheckedForCrossImportsPerSchema
+        = new HashMap<>();
+
+    public SchemaCollection() {
+        this(new XmlSchemaCollection());
+    }
+
+    public SchemaCollection(XmlSchemaCollection col) {
+        xmlSchemaCollection = col;
+        if (xmlSchemaCollection.getNamespaceContext() == null) {
+            // an empty prefix map avoids extra checks for null.
+            xmlSchemaCollection.setNamespaceContext(new NamespaceMap());
+        }
+    }
+
+    public XmlSchemaCollection getXmlSchemaCollection() {
+        return xmlSchemaCollection;
+    }
+
+    public boolean equals(Object obj) {
+        if (obj instanceof SchemaCollection) {
+            return xmlSchemaCollection.equals(((SchemaCollection)obj).xmlSchemaCollection);
+        } else if (obj instanceof XmlSchemaCollection) {
+            return xmlSchemaCollection.equals(obj);
+        }
+        return false;
+    }
+
+    public XmlSchemaElement getElementByQName(QName qname) {
+        return xmlSchemaCollection.getElementByQName(qname);
+    }
+
+    public XmlSchemaAttribute getAttributeByQName(QName qname) {
+        return xmlSchemaCollection.getAttributeByQName(qname);
+    }
+
+    public ExtensionRegistry getExtReg() {
+        return xmlSchemaCollection.getExtReg();
+    }
+
+    public NamespacePrefixList getNamespaceContext() {
+        return xmlSchemaCollection.getNamespaceContext();
+    }
+
+    public XmlSchemaType getTypeByQName(QName schemaTypeName) {
+        return xmlSchemaCollection.getTypeByQName(schemaTypeName);
+    }
+
+    public XmlSchema[] getXmlSchema(String systemId) {
+        return xmlSchemaCollection.getXmlSchema(systemId);
+    }
+
+    public XmlSchema[] getXmlSchemas() {
+        return xmlSchemaCollection.getXmlSchemas();
+    }
+
+    public int hashCode() {
+        return xmlSchemaCollection.hashCode();
+    }
+
+    public void init() {
+        xmlSchemaCollection.init();
+    }
+
+    public XmlSchema read(Element elem, String uri) {
+        return xmlSchemaCollection.read(elem, uri);
+    }
+
+    public XmlSchema read(Document d, String uri) {
+        return xmlSchemaCollection.read(d, uri);
+    }
+
+    public XmlSchema read(Element elem) {
+        return xmlSchemaCollection.read(elem);
+    }
+
+    public void setBaseUri(String baseUri) {
+        xmlSchemaCollection.setBaseUri(baseUri);
+    }
+
+    public void setExtReg(ExtensionRegistry extReg) {
+        xmlSchemaCollection.setExtReg(extReg);
+    }
+
+    public void setNamespaceContext(NamespacePrefixList namespaceContext) {
+        xmlSchemaCollection.setNamespaceContext(namespaceContext);
+    }
+
+    public void setSchemaResolver(URIResolver schemaResolver) {
+        xmlSchemaCollection.setSchemaResolver(schemaResolver);
+    }
+
+    /**
+     * This function is not part of the XmlSchema API. Who knows why?
+     *
+     * @param namespaceURI targetNamespace
+     * @return schema, or null.
+     */
+    public XmlSchema getSchemaByTargetNamespace(String namespaceURI) {
+        for (XmlSchema schema : xmlSchemaCollection.getXmlSchemas()) {
+            if (namespaceURI != null && namespaceURI.equals(schema.getTargetNamespace())
+                || namespaceURI == null && schema.getTargetNamespace() == null) {
+                return schema;
+            }
+        }
+        return null;
+    }
+
+    public XmlSchema getSchemaForElement(QName name) {
+        for (XmlSchema schema : xmlSchemaCollection.getXmlSchemas()) {
+            if (name.getNamespaceURI().equals(schema.getTargetNamespace())) {
+
+                if (schema.getElementByName(name.getLocalPart()) != null) {
+                    return schema;
+                } else if (schema.getElementByName(name) != null) {
+                    return schema;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Once upon a time, XmlSchema had a bug in the constructor used in this function. So this wrapper was
+     * created to hold a workaround.
+     *
+     * @param namespaceURI TNS for new schema.
+     * @return new schema
+     */
+
+    public XmlSchema newXmlSchemaInCollection(String namespaceURI) {
+        return new XmlSchema(namespaceURI, xmlSchemaCollection);
+    }
+
+    /**
+     * Validate that a qualified name points to some namespace in the schema.
+     *
+     * @param qname
+     */
+    public void validateQNameNamespace(QName qname) {
+        // astonishingly, xmlSchemaCollection has no accessor by target URL.
+        if ("".equals(qname.getNamespaceURI())) {
+            return; // references to the 'unqualified' namespace are OK even if there is no schema for it.
+        }
+        for (XmlSchema schema : xmlSchemaCollection.getXmlSchemas()) {
+            if (schema.getTargetNamespace().equals(qname.getNamespaceURI())) {
+                return;
+            }
+        }
+        throw new InvalidXmlSchemaReferenceException(qname + " refers to unknown namespace.");
+    }
+
+    public void validateElementName(QName referrer, QName elementQName) {
+        XmlSchemaElement element = xmlSchemaCollection.getElementByQName(elementQName);
+        if (element == null) {
+            throw new InvalidXmlSchemaReferenceException(referrer + " references non-existent element "
+                                                         + elementQName);
+        }
+    }
+
+    public void validateTypeName(QName referrer, QName typeQName) {
+        XmlSchemaType type = xmlSchemaCollection.getTypeByQName(typeQName);
+        if (type == null) {
+            throw new InvalidXmlSchemaReferenceException(referrer + " references non-existent type "
+                                                         + typeQName);
+        }
+    }
+
+    public void addCrossImports() {
+        /*
+         * We need to inventory all the cross-imports to see if any are missing.
+         */
+        for (XmlSchema schema : xmlSchemaCollection.getXmlSchemas()) {
+            addOneSchemaCrossImports(schema);
+        }
+    }
+
+    private void addOneSchemaCrossImports(XmlSchema schema) {
+        /*
+         * We need to visit all the top-level items.
+         */
+        for (XmlSchemaElement element : schema.getElements().values()) {
+            addElementCrossImportsElement(schema, element);
+        }
+        for (XmlSchemaAttribute attribute : schema.getAttributes().values()) {
+            XmlSchemaUtils.addImportIfNeeded(schema, attribute.getRef().getTargetQName());
+            XmlSchemaUtils.addImportIfNeeded(schema, attribute.getSchemaTypeName());
+        }
+        for (XmlSchemaType type : schema.getSchemaTypes().values()) {
+            addCrossImportsType(schema, type);
+        }
+    }
+
+    private void addElementCrossImportsElement(XmlSchema schema, XmlSchemaElement item) {
+        XmlSchemaElement element = item;
+        XmlSchemaUtils.addImportIfNeeded(schema, element.getRef().getTargetQName());
+        XmlSchemaUtils.addImportIfNeeded(schema, element.getSchemaTypeName());
+        // if there's an anonymous type, it might have element refs in it.
+        XmlSchemaType schemaType = element.getSchemaType();
+        if (!crossImportsAdded(schema, schemaType)) {
+            addCrossImportsType(schema, schemaType);
+        }
+    }
+
+    /**
+     * Determines whether the schema has already received (cross) imports for the schemaType
+     *
+     * @param schema
+     * @param schemaType
+     * @return false if cross imports for schemaType must still be added to schema
+     */
+    private boolean crossImportsAdded(XmlSchema schema, XmlSchemaType schemaType) {
+        boolean result = true;
+        if (schemaType != null) {
+            Set<XmlSchemaType> xmlTypesCheckedForCrossImports;
+            if (!xmlTypesCheckedForCrossImportsPerSchema.containsKey(schema)) {
+                xmlTypesCheckedForCrossImports = new HashSet<>();
+                xmlTypesCheckedForCrossImportsPerSchema.put(schema, xmlTypesCheckedForCrossImports);
+            } else {
+                xmlTypesCheckedForCrossImports = xmlTypesCheckedForCrossImportsPerSchema.get(schema);
+            }
+            if (!xmlTypesCheckedForCrossImports.contains(schemaType)) {
+                // cross imports for this schemaType have not yet been added
+                xmlTypesCheckedForCrossImports.add(schemaType);
+                result = false;
+            }
+        }
+        return result;
+    }
+
+    private void addCrossImportsType(XmlSchema schema, XmlSchemaType schemaType) {
+        // the base type might cross schemas.
+        if (schemaType instanceof XmlSchemaComplexType) {
+            XmlSchemaComplexType complexType = (XmlSchemaComplexType)schemaType;
+            XmlSchemaUtils.addImportIfNeeded(schema, complexType.getBaseSchemaTypeName());
+            addCrossImports(schema, complexType.getContentModel());
+            addCrossImportsAttributeList(schema, complexType.getAttributes());
+            // could it be a choice or something else?
+
+            if (complexType.getParticle() instanceof XmlSchemaChoice) {
+                XmlSchemaChoice choice = (XmlSchemaChoice)complexType.getParticle();
+                addCrossImports(schema, choice);
+            } else if (complexType.getParticle() instanceof XmlSchemaAll) {
+                XmlSchemaAll all = (XmlSchemaAll)complexType.getParticle();
+                addCrossImports(schema, all);
+            } else if (complexType.getParticle() instanceof XmlSchemaSequence) {
+                XmlSchemaSequence sequence = (XmlSchemaSequence)complexType.getParticle();
+                addCrossImports(schema, sequence);
+            }
+        }
+    }
+    private void addCrossImports(XmlSchema schema, XmlSchemaAll all) {
+        for (XmlSchemaObjectBase seqMember : all.getItems()) {
+            if (seqMember instanceof XmlSchemaElement) {
+                addElementCrossImportsElement(schema, (XmlSchemaElement)seqMember);
+            }
+        }
+    }
+
+    private void addCrossImports(XmlSchema schema, XmlSchemaChoice choice) {
+        for (XmlSchemaObjectBase seqMember : choice.getItems()) {
+            if (seqMember instanceof XmlSchemaElement) {
+                addElementCrossImportsElement(schema, (XmlSchemaElement)seqMember);
+            }
+        }
+    }
+    private void addCrossImports(XmlSchema schema, XmlSchemaSequence sequence) {
+        for (XmlSchemaSequenceMember seqMember : sequence.getItems()) {
+            if (seqMember instanceof XmlSchemaElement) {
+                addElementCrossImportsElement(schema, (XmlSchemaElement)seqMember);
+            }
+        }
+    }
+
+    private void addCrossImportsAttributeList(XmlSchema schema, List<XmlSchemaAttributeOrGroupRef> list) {
+        for (XmlSchemaAttributeOrGroupRef attr : list) {
+            final QName ref;
+            if (attr instanceof XmlSchemaAttribute) {
+                ref = ((XmlSchemaAttribute)attr).getRef().getTargetQName();
+            } else {
+                XmlSchemaAttributeGroupRef groupRef = (XmlSchemaAttributeGroupRef)attr;
+                ref = groupRef.getRef().getTargetQName();
+            }
+
+            if (ref != null) {
+                XmlSchemaUtils.addImportIfNeeded(schema, ref);
+            }
+        }
+    }
+
+    private void addCrossImports(XmlSchema schema, XmlSchemaContentModel contentModel) {
+        if (contentModel == null) {
+            return;
+        }
+        XmlSchemaContent content = contentModel.getContent();
+        if (content == null) {
+            return;
+        }
+        if (content instanceof XmlSchemaComplexContentExtension) {
+            XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)content;
+            XmlSchemaUtils.addImportIfNeeded(schema, extension.getBaseTypeName());
+            addCrossImportsAttributeList(schema, extension.getAttributes());
+            XmlSchemaParticle particle = extension.getParticle();
+            if (particle instanceof XmlSchemaSequence) {
+                addCrossImports(schema, (XmlSchemaSequence)particle);
+            } else if (particle instanceof XmlSchemaChoice) {
+                addCrossImports(schema, (XmlSchemaChoice)particle);
+            } else if (particle instanceof XmlSchemaAll) {
+                addCrossImports(schema, (XmlSchemaAll)particle);
+            }
+        } else if (content instanceof XmlSchemaComplexContentRestriction) {
+            XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction)content;
+            XmlSchemaUtils.addImportIfNeeded(schema, restriction.getBaseTypeName());
+            addCrossImportsAttributeList(schema, restriction.getAttributes());
+        } else if (content instanceof XmlSchemaSimpleContentExtension) {
+            XmlSchemaSimpleContentExtension extension = (XmlSchemaSimpleContentExtension)content;
+            XmlSchemaUtils.addImportIfNeeded(schema, extension.getBaseTypeName());
+            addCrossImportsAttributeList(schema, extension.getAttributes());
+        } else if (content instanceof XmlSchemaSimpleContentRestriction) {
+            XmlSchemaSimpleContentRestriction restriction = (XmlSchemaSimpleContentRestriction)content;
+            XmlSchemaUtils.addImportIfNeeded(schema, restriction.getBaseTypeName());
+            addCrossImportsAttributeList(schema, restriction.getAttributes());
+        }
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/configuration/jsse/MultiKeyPasswordKeyManager.java b/transform/src/patch/java/org/apache/cxf/configuration/jsse/MultiKeyPasswordKeyManager.java
new file mode 100644
index 0000000..6a1aee5
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/configuration/jsse/MultiKeyPasswordKeyManager.java
@@ -0,0 +1,84 @@
+/**
+ * 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.cxf.configuration.jsse;
+
+import java.net.Socket;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.X509KeyManager;
+
+public class MultiKeyPasswordKeyManager implements X509KeyManager {
+    private final KeyStore mKeyStore;
+    private final String mKeyAlias;
+    private final String mKeyPassword;
+
+    public MultiKeyPasswordKeyManager(KeyStore keystore, String keyAlias, String keyPassword) {
+        mKeyStore = keystore;
+        mKeyAlias = keyAlias;
+        mKeyPassword = keyPassword;
+    }
+
+    public String[] getClientAliases(String keyType, Principal[] issuers) {
+        return new String[] {
+            mKeyAlias
+        };
+    }
+
+    public String[] getServerAliases(String keyType, Principal[] issuers) {
+        return new String[] {
+            mKeyAlias
+        };
+    }
+    public X509Certificate[] getCertificateChain(String alias) {
+        final Certificate[] chain;
+        try {
+            chain = mKeyStore.getCertificateChain(alias);
+        } catch (KeyStoreException kse) {
+            throw new RuntimeException(kse);
+        }
+        final X509Certificate[] certChain = new X509Certificate[chain.length];
+        for (int i = 0; i < chain.length; i++) {
+            certChain[i] = (X509Certificate)chain[i];
+        }
+        return certChain;
+    }
+
+    public PrivateKey getPrivateKey(String alias) {
+        try {
+            return (PrivateKey)mKeyStore.getKey(alias, mKeyPassword.toCharArray());
+        } catch (GeneralSecurityException gse) {
+            throw new RuntimeException(gse);
+        }
+    }
+
+    public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
+        return mKeyAlias;
+    }
+
+    public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
+        return mKeyAlias;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/configuration/jsse/TLSClientParameters.java b/transform/src/patch/java/org/apache/cxf/configuration/jsse/TLSClientParameters.java
new file mode 100644
index 0000000..3e0099a
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/configuration/jsse/TLSClientParameters.java
@@ -0,0 +1,258 @@
+/**
+ * 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.cxf.configuration.jsse;
+
+import java.util.List;
+import java.util.Objects;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * This class extends {@link TLSParameterBase} with client-specific
+ * SSL/TLS parameters.
+ *
+ */
+public class TLSClientParameters extends TLSParameterBase {
+    private boolean disableCNCheck;
+    private SSLSocketFactory sslSocketFactory;
+    private int sslCacheTimeout = 86400;
+    private boolean useHttpsURLConnectionDefaultSslSocketFactory;
+    private boolean useHttpsURLConnectionDefaultHostnameVerifier;
+    private HostnameVerifier hostnameVerifier;
+    private SSLContext sslContext;
+
+    /**
+     * Set custom HostnameVerifier
+     * @param verifier hostname verifier
+     */
+    public void setHostnameVerifier(HostnameVerifier verifier) {
+        hostnameVerifier = verifier;
+    }
+
+    /**
+     * Get custom HostnameVerifier
+     * @return hostname verifier
+     */
+    public HostnameVerifier getHostnameVerifier() {
+        return hostnameVerifier;
+    }
+    /**
+     * Set whether or not JSEE should omit checking if the host name
+     * specified in the URL matches that of the Common Name
+     * (CN) on the server's certificate. Default is false;
+     * this attribute should not be set to true during production use.
+     */
+    public void setDisableCNCheck(boolean disableCNCheck) {
+        this.disableCNCheck = disableCNCheck;
+    }
+
+    /**
+     * Returns whether or not JSSE omits checking if the
+     * host name specified in the URL matches that of the Common Name
+     * (CN) on the server's certificate.
+     */
+    public boolean isDisableCNCheck() {
+        return disableCNCheck;
+    }
+
+    /**
+     * This sets the SSLSocketFactory to use, causing all other properties of
+     * this bean (and its superclass) to get ignored (this takes precendence).
+     */
+    public final void setSSLSocketFactory(SSLSocketFactory factory) {
+        sslSocketFactory = factory;
+    }
+
+
+    /**
+     * Returns the SSLSocketFactory to be used, or null if none has been set.
+     */
+    public final SSLSocketFactory getSSLSocketFactory() {
+        return sslSocketFactory;
+    }
+
+    /**
+     * Returns the SSL cache timeout in seconds if it has been configured or the default value
+     */
+    public int getSslCacheTimeout() {
+        return sslCacheTimeout;
+    }
+
+    /**
+     * This sets the SSL Session Cache timeout value in seconds for client sessions handled by CXF
+     */
+    public void setSslCacheTimeout(int sslCacheTimeout) {
+        this.sslCacheTimeout = sslCacheTimeout;
+    }
+
+
+    /**
+     * Returns whether or not {@link javax.net.ssl.HttpsURLConnection#getDefaultSSLSocketFactory()} should be
+     * used to create https connections. If <code>true</code> , {@link #getJsseProvider()} ,
+     * {@link #getSecureSocketProtocol()}, {@link #getTrustManagers()}, {@link #getKeyManagers()},
+     * {@link #getSecureRandom()}, {@link #getCipherSuites()} and {@link #getCipherSuitesFilter()} are
+     * ignored.
+     */
+    public boolean isUseHttpsURLConnectionDefaultSslSocketFactory() {
+        return useHttpsURLConnectionDefaultSslSocketFactory;
+    }
+
+    /**
+     * Sets whether or not {@link javax.net.ssl.HttpsURLConnection#getDefaultSSLSocketFactory()} should be
+     * used to create https connections.
+     *
+     * @see #isUseHttpsURLConnectionDefaultSslSocketFactory()
+     */
+    public void setUseHttpsURLConnectionDefaultSslSocketFactory(
+                      boolean useHttpsURLConnectionDefaultSslSocketFactory) {
+        this.useHttpsURLConnectionDefaultSslSocketFactory = useHttpsURLConnectionDefaultSslSocketFactory;
+    }
+
+    /**
+     * Returns whether or not {@link javax.net.ssl.HttpsURLConnection#getDefaultHostnameVerifier()} should be
+     * used to create https connections. If <code>true</code>, {@link #isDisableCNCheck()} is ignored.
+     */
+    public boolean isUseHttpsURLConnectionDefaultHostnameVerifier() {
+        return useHttpsURLConnectionDefaultHostnameVerifier;
+    }
+
+    /**
+     * Sets whether or not {@link javax.net.ssl.HttpsURLConnection#getDefaultHostnameVerifier()} should be
+     * used to create https connections.
+     *
+     * @see #isUseHttpsURLConnectionDefaultHostnameVerifier()
+     */
+    public void setUseHttpsURLConnectionDefaultHostnameVerifier(
+                      boolean useHttpsURLConnectionDefaultHostnameVerifier) {
+        this.useHttpsURLConnectionDefaultHostnameVerifier = useHttpsURLConnectionDefaultHostnameVerifier;
+    }
+
+    public int hashCode() {
+        int hash = disableCNCheck ? 37 : 17;
+        if (sslSocketFactory != null) {
+            hash = hash * 41 + System.identityHashCode(sslSocketFactory);
+        }
+        if (sslContext != null) {
+            hash = hash * 41 + System.identityHashCode(sslContext);
+        }
+        hash = hash(hash, useHttpsURLConnectionDefaultSslSocketFactory);
+        hash = hash(hash, useHttpsURLConnectionDefaultHostnameVerifier);
+        hash = hash(hash, sslCacheTimeout);
+        hash = hash(hash, secureRandom);
+        hash = hash(hash, protocol);
+        hash = hash(hash, certAlias);
+        hash = hash(hash, provider);
+        for (String cs : ciphersuites) {
+            hash = hash(hash, cs);
+        }
+        hash = hash(hash, keyManagers);
+        hash = hash(hash, trustManagers);
+        if (cipherSuiteFilters != null) {
+            hash = hash(hash, cipherSuiteFilters.getInclude());
+            hash = hash(hash, cipherSuiteFilters.getExclude());
+        }
+        if (certConstraints != null) {
+            hash = hash(hash, certConstraints.getIssuerDNConstraints());
+            hash = hash(hash, certConstraints.getSubjectDNConstraints());
+        }
+        return hash;
+    }
+    private int hash(int i, Object o) {
+        if (o != null) {
+            return i * 37 + o.hashCode();
+        }
+        return i;
+    }
+    private int hash(int i, Object[] os) {
+        if (os == null) {
+            return i;
+        }
+        for (Object o : os) {
+            i = hash(i, o);
+        }
+        return i;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o instanceof TLSClientParameters) {
+            TLSClientParameters that = (TLSClientParameters)o;
+            boolean eq = disableCNCheck == that.disableCNCheck;
+            eq &= sslSocketFactory == that.sslSocketFactory;
+            eq &= sslContext == that.sslContext;
+            eq &= useHttpsURLConnectionDefaultSslSocketFactory == that.useHttpsURLConnectionDefaultSslSocketFactory;
+            eq &= useHttpsURLConnectionDefaultHostnameVerifier == that.useHttpsURLConnectionDefaultHostnameVerifier;
+            eq &= sslCacheTimeout == that.sslCacheTimeout;
+            eq &= secureRandom == that.secureRandom;
+            eq &= Objects.equals(certAlias, that.certAlias);
+            eq &= Objects.equals(protocol, that.protocol);
+            eq &= Objects.equals(provider, that.provider);
+            eq &= equals(ciphersuites, that.ciphersuites);
+            eq &= Objects.deepEquals(keyManagers, that.keyManagers);
+            eq &= Objects.deepEquals(trustManagers, that.trustManagers);
+            if (cipherSuiteFilters != null) {
+                if (that.cipherSuiteFilters != null) {
+                    eq &= equals(cipherSuiteFilters.getExclude(), that.cipherSuiteFilters.getExclude());
+                    eq &= equals(cipherSuiteFilters.getInclude(), that.cipherSuiteFilters.getInclude());
+                } else {
+                    eq = false;
+                }
+            } else {
+                eq &= that.cipherSuiteFilters == null;
+            }
+            if (certConstraints != null) {
+                if (that.certConstraints != null) {
+                    eq &= Objects.equals(certConstraints.getIssuerDNConstraints(),
+                                 that.certConstraints.getIssuerDNConstraints());
+                    eq &= Objects.equals(certConstraints.getSubjectDNConstraints(),
+                                 that.certConstraints.getSubjectDNConstraints());
+                } else {
+                    eq = false;
+                }
+            } else {
+                eq &= that.certConstraints == null;
+            }
+            return eq;
+        }
+        return false;
+    }
+
+    private static boolean equals(final List<?> obj1, final List<?> obj2) {
+        return obj1.equals(obj2);
+    }
+
+    /**
+     * Get the SSLContext parameter to use (if it has been set)
+     */
+    public SSLContext getSslContext() {
+        return sslContext;
+    }
+
+    /**
+     * Set an SSLContext parameter to use to create https connections
+     */
+    public void setSslContext(SSLContext sslContext) {
+        this.sslContext = sslContext;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/configuration/jsse/TLSParameterJaxBUtils.java b/transform/src/patch/java/org/apache/cxf/configuration/jsse/TLSParameterJaxBUtils.java
new file mode 100644
index 0000000..bd16aa4
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/configuration/jsse/TLSParameterJaxBUtils.java
@@ -0,0 +1,420 @@
+/**
+ * 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.cxf.configuration.jsse;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Paths;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.net.ssl.CertPathTrustManagerParameters;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.configuration.security.CertStoreType;
+import org.apache.cxf.configuration.security.KeyManagersType;
+import org.apache.cxf.configuration.security.KeyStoreType;
+import org.apache.cxf.configuration.security.SecureRandomParameters;
+import org.apache.cxf.configuration.security.TrustManagersType;
+import org.apache.cxf.resource.ResourceManager;
+
+/**
+ * This class provides some functionality to convert the JAXB
+ * generated types in the security.xsd to the items needed
+ * to programatically configure the HTTPConduit and HTTPDestination
+ * with TLSClientParameters and TLSServerParameters respectively.
+ */
+public final class TLSParameterJaxBUtils {
+
+    private static final Logger LOG =
+        LogUtils.getL7dLogger(TLSParameterJaxBUtils.class);
+
+    private TLSParameterJaxBUtils() {
+        // empty
+    }
+    /**
+     * This method converts the JAXB generated type into a SecureRandom.
+     */
+    public static SecureRandom getSecureRandom(
+            SecureRandomParameters secureRandomParams
+    ) throws GeneralSecurityException {
+
+        SecureRandom secureRandom = null;
+        if (secureRandomParams != null) {
+            String secureRandomAlg =
+                secureRandomParams.getAlgorithm();
+            String randomProvider =
+                secureRandomParams.getProvider();
+            if (randomProvider != null) {
+                secureRandom = secureRandomAlg != null
+                               ? SecureRandom.getInstance(
+                                       secureRandomAlg,
+                                       randomProvider)
+                               : null;
+            } else {
+                secureRandom = secureRandomAlg != null
+                               ? SecureRandom.getInstance(
+                                       secureRandomAlg)
+                               : null;
+            }
+        }
+        return secureRandom;
+    }
+
+    public static KeyStore getKeyStore(KeyStoreType kst) throws GeneralSecurityException, IOException {
+        return getKeyStore(kst, false);
+    }
+
+    /**
+     * This method converts a JAXB generated KeyStoreType into a KeyStore.
+     */
+    public static KeyStore getKeyStore(KeyStoreType kst, boolean trustStore)
+        throws GeneralSecurityException,
+               IOException {
+
+        if (kst == null) {
+            return null;
+        }
+        final String type;
+        if (trustStore) {
+            type = SSLUtils.getTrustStoreType(kst.isSetType()
+                                     ? kst.getType() : null, LOG, KeyStore.getDefaultType());
+        } else {
+            type = SSLUtils.getKeystoreType(kst.isSetType()
+                                 ? kst.getType() : null, LOG, KeyStore.getDefaultType());
+        }
+
+        char[] password = kst.isSetPassword()
+                    ? deobfuscate(kst.getPassword())
+                    : null;
+        if (password == null) {
+            final String tmp;
+            if (trustStore) {
+                tmp = SSLUtils.getTruststorePassword(null, LOG);
+            } else {
+                tmp = SSLUtils.getKeystorePassword(null, LOG);
+            }
+            if (tmp != null) {
+                password = tmp.toCharArray();
+            }
+        }
+        final String provider;
+        if (trustStore) {
+            provider = SSLUtils.getTruststoreProvider(kst.isSetProvider() ? kst.getProvider() : null, LOG);
+        } else {
+            provider = SSLUtils.getKeystoreProvider(kst.isSetProvider() ? kst.getProvider() : null, LOG);
+        }
+        KeyStore keyStore = provider == null
+                    ? KeyStore.getInstance(type)
+                    : KeyStore.getInstance(type, provider);
+
+        if (kst.isSetFile()) {
+            try (InputStream kstInputStream = Files.newInputStream(Paths.get(kst.getFile()))) {
+                keyStore.load(kstInputStream, password);
+            }
+        } else if (kst.isSetResource()) {
+            final InputStream is = getResourceAsStream(kst.getResource());
+            if (is == null) {
+                final String msg =
+                    "Could not load keystore resource " + kst.getResource();
+                LOG.severe(msg);
+                throw new IOException(msg);
+            }
+            keyStore.load(is, password);
+        } else if (kst.isSetUrl()) {
+            keyStore.load(new URL(kst.getUrl()).openStream(), password);
+        } else {
+            final String loc;
+            if (trustStore) {
+                loc = SSLUtils.getTruststore(null, LOG);
+            } else {
+                loc = SSLUtils.getKeystore(null, LOG);
+            }
+            if (loc != null) {
+                try (InputStream ins = Files.newInputStream(Paths.get(loc))) {
+                    keyStore.load(ins, password);
+                } catch (NoSuchFileException ex) {
+                    // Fall back to load the location as a stream
+                    try (InputStream ins = getResourceAsStream(loc)) {
+                        keyStore.load(ins, password);
+                    }
+                }
+            }
+        }
+        return keyStore;
+    }
+
+    /**
+     * This method converts a JAXB generated CertStoreType into a KeyStore.
+     */
+    public static KeyStore getKeyStore(final CertStoreType pst)
+        throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
+
+        if (pst == null) {
+            return null;
+        }
+        String type;
+        if (pst.isSetType()) {
+            type = pst.getType();
+        } else {
+            type = KeyStore.getDefaultType();
+        }
+        if (pst.isSetFile()) {
+            InputStream is = Files.newInputStream(Paths.get(pst.getFile()));
+            return createTrustStore(is, type);
+        }
+        if (pst.isSetResource()) {
+            final InputStream is = getResourceAsStream(pst.getResource());
+            if (is == null) {
+                final String msg =
+                    "Could not load truststore resource " + pst.getResource();
+                LOG.severe(msg);
+                throw new IOException(msg);
+            }
+            return createTrustStore(is, type);
+        }
+        if (pst.isSetUrl()) {
+            return createTrustStore(new URL(pst.getUrl()).openStream(), type);
+        }
+        throw new IllegalArgumentException("Could not create KeyStore based on information in CertStoreType");
+    }
+
+    private static InputStream getResourceAsStream(String resource) {
+        InputStream is = ClassLoaderUtils.getResourceAsStream(resource, TLSParameterJaxBUtils.class);
+        if (is == null) {
+            Bus bus = BusFactory.getThreadDefaultBus(true);
+            ResourceManager rm = bus.getExtension(ResourceManager.class);
+            if (rm != null) {
+                is = rm.getResourceAsStream(resource);
+            }
+        }
+        return is;
+    }
+
+    /**
+     * Create a KeyStore containing the trusted CA certificates contained
+     * in the supplied input stream.
+     */
+    private static KeyStore createTrustStore(final InputStream is, String type)
+        throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
+
+        final Collection<? extends Certificate> certs = loadCertificates(is);
+        final KeyStore keyStore =
+            KeyStore.getInstance(type);
+        keyStore.load(null, null);
+        for (Certificate cert : certs) {
+            final X509Certificate xcert = (X509Certificate) cert;
+            keyStore.setCertificateEntry(
+                xcert.getSubjectX500Principal().getName(),
+                cert
+            );
+        }
+        return keyStore;
+    }
+
+    /**
+     * load the certificates as X.509 certificates
+     */
+    private static Collection<? extends Certificate> loadCertificates(final InputStream is)
+        throws IOException, CertificateException {
+
+        final CertificateFactory factory = CertificateFactory.getInstance("X.509");
+        return factory.generateCertificates(is);
+    }
+
+    private static char[] deobfuscate(String s) {
+        // From the Jetty org.eclipse.jetty.http.security.Password class
+        if (!s.startsWith("OBF:")) {
+            return s.toCharArray();
+        }
+        s = s.substring(4);
+
+        char[] b = new char[s.length() / 2];
+        int l = 0;
+        for (int i = 0; i < s.length(); i += 4) {
+            String x = s.substring(i, i + 4);
+            int i0 = Integer.parseInt(x, 36);
+            int i1 = i0 / 256;
+            int i2 = i0 % 256;
+            b[l++] = (char) ((i1 + i2 - 254) / 2);
+        }
+
+        return new String(b, 0, l).toCharArray();
+    }
+
+    /**
+     * This method converts the JAXB KeyManagersType into a list of
+     * JSSE KeyManagers.
+     */
+    public static KeyManager[] getKeyManagers(KeyManagersType kmc)
+        throws GeneralSecurityException,
+               IOException {
+
+        KeyStore keyStore = getKeyStore(kmc.getKeyStore(), false);
+
+        String alg = kmc.isSetFactoryAlgorithm()
+                     ? kmc.getFactoryAlgorithm()
+                     : KeyManagerFactory.getDefaultAlgorithm();
+
+        char[] keyPass = getKeyPassword(kmc);
+
+        KeyManagerFactory fac =
+                     kmc.isSetProvider()
+                     ? KeyManagerFactory.getInstance(alg, kmc.getProvider())
+                     : KeyManagerFactory.getInstance(alg);
+
+        fac.init(keyStore, keyPass);
+
+        return fac.getKeyManagers();
+    }
+
+    /**
+     * This method converts the JAXB KeyManagersType into a list of
+     * JSSE KeyManagers.
+     */
+    public static KeyManager[] getKeyManagers(KeyManagersType kmc, String alias)
+        throws GeneralSecurityException,
+               IOException {
+
+        KeyStore keyStore = getKeyStore(kmc.getKeyStore(), false);
+
+        String alg = kmc.isSetFactoryAlgorithm()
+                     ? kmc.getFactoryAlgorithm()
+                     : KeyManagerFactory.getDefaultAlgorithm();
+
+        char[] keyPass = getKeyPassword(kmc);
+
+        KeyManagerFactory fac =
+                     kmc.isSetProvider()
+                     ? KeyManagerFactory.getInstance(alg, kmc.getProvider())
+                     : KeyManagerFactory.getInstance(alg);
+
+        try {
+            fac.init(keyStore, keyPass);
+
+            return fac.getKeyManagers();
+        } catch (java.security.UnrecoverableKeyException uke) {
+            //jsse has the restriction that different key in keystore
+            //cannot has different password, use MultiKeyPasswordKeyManager
+            //as fallback when this happen
+            MultiKeyPasswordKeyManager manager
+                = new MultiKeyPasswordKeyManager(keyStore, alias,
+                                             new String(keyPass));
+            return new KeyManager[]{manager};
+        }
+    }
+
+    private static char[] getKeyPassword(KeyManagersType kmc) {
+        char[] keyPass = kmc.isSetKeyPassword()
+            ? deobfuscate(kmc.getKeyPassword())
+            : null;
+
+        if (keyPass != null) {
+            return keyPass;
+        }
+
+        String callbackHandlerClass = kmc.getKeyPasswordCallbackHandler();
+        if (callbackHandlerClass == null) {
+            return null;
+        }
+        try {
+            final CallbackHandler ch = (CallbackHandler) ClassLoaderUtils
+                .loadClass(callbackHandlerClass, TLSParameterJaxBUtils.class).newInstance();
+            String prompt = kmc.getKeyStore().getFile();
+            if (prompt == null) {
+                prompt = kmc.getKeyStore().getResource();
+            }
+            PasswordCallback pwCb = new PasswordCallback(prompt, false);
+            PasswordCallback[] callbacks = new PasswordCallback[] {pwCb};
+            ch.handle(callbacks);
+            keyPass = callbacks[0].getPassword();
+        } catch (Exception e) {
+            LOG.log(Level.WARNING,
+                    "Cannot load key password from callback handler: " + e.getMessage(), e);
+        }
+        return keyPass;
+    }
+
+    /**
+     * This method converts the JAXB TrustManagersType into a list of
+     * JSSE TrustManagers.
+     */
+    @Deprecated
+    public static TrustManager[] getTrustManagers(TrustManagersType tmc)
+        throws GeneralSecurityException,
+               IOException {
+        return getTrustManagers(tmc, false);
+    }
+
+    public static TrustManager[] getTrustManagers(TrustManagersType tmc, boolean enableRevocation)
+        throws GeneralSecurityException,
+               IOException {
+
+        final KeyStore keyStore =
+            tmc.isSetKeyStore()
+                ? getKeyStore(tmc.getKeyStore(), true)
+                : (tmc.isSetCertStore()
+                    ? getKeyStore(tmc.getCertStore())
+                    : null);
+
+        String alg = tmc.isSetFactoryAlgorithm()
+                     ? tmc.getFactoryAlgorithm()
+                     : TrustManagerFactory.getDefaultAlgorithm();
+
+        TrustManagerFactory fac =
+                     tmc.isSetProvider()
+                     ? TrustManagerFactory.getInstance(alg, tmc.getProvider())
+                     : TrustManagerFactory.getInstance(alg);
+
+        if (enableRevocation) {
+            PKIXBuilderParameters param = new PKIXBuilderParameters(keyStore, new X509CertSelector());
+            param.setRevocationEnabled(true);
+
+            fac.init(new CertPathTrustManagerParameters(param));
+        } else {
+            fac.init(keyStore);
+        }
+
+        return fac.getTrustManagers();
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/configuration/spring/ConfigurerImpl.java b/transform/src/patch/java/org/apache/cxf/configuration/spring/ConfigurerImpl.java
new file mode 100644
index 0000000..d920936
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/configuration/spring/ConfigurerImpl.java
@@ -0,0 +1,288 @@
+/**
+ * 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.cxf.configuration.spring;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.configuration.Configurable;
+import org.apache.cxf.configuration.Configurer;
+import org.apache.cxf.extension.BusExtension;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.AbstractBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
+import org.springframework.beans.factory.wiring.BeanWiringInfo;
+import org.springframework.beans.factory.wiring.BeanWiringInfoResolver;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+
+@NoJSR250Annotations
+public class ConfigurerImpl extends BeanConfigurerSupport
+    implements Configurer, ApplicationContextAware, BusExtension {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(ConfigurerImpl.class);
+
+    private Set<ApplicationContext> appContexts;
+    private final Map<String, List<MatcherHolder>> wildCardBeanDefinitions = new TreeMap<>();
+    private BeanFactory beanFactory;
+
+    static class MatcherHolder implements Comparable<MatcherHolder> {
+        Matcher matcher;
+        String wildCardId;
+        MatcherHolder(String orig, Matcher matcher) {
+            wildCardId = orig;
+            this.matcher = matcher;
+        }
+        
+        @Override
+        public int compareTo(MatcherHolder mh) {
+            int literalCharsLen1 = this.wildCardId.replace("*", "").length();
+            int literalCharsLen2 = mh.wildCardId.replace("*", "").length();
+            // The expression with more literal characters should end up on the top of the list
+            return Integer.compare(literalCharsLen1, literalCharsLen2) * -1;
+        }
+    }
+
+    public ConfigurerImpl() {
+        // complete
+    }
+
+    public ConfigurerImpl(ApplicationContext ac) {
+        setApplicationContext(ac);
+    }
+
+    @Override
+    public void setBeanFactory(BeanFactory beanFactory) {
+        this.beanFactory = beanFactory;
+        super.setBeanFactory(beanFactory);
+    }
+
+    private void initWildcardDefinitionMap() {
+        if (null != appContexts) {
+            for (ApplicationContext appContext : appContexts) {
+                for (String n : appContext.getBeanDefinitionNames()) {
+                    if (isWildcardBeanName(n)) {
+                        AutowireCapableBeanFactory bf = appContext.getAutowireCapableBeanFactory();
+                        BeanDefinitionRegistry bdr = (BeanDefinitionRegistry) bf;
+                        BeanDefinition bd = bdr.getBeanDefinition(n);
+                        String className = bd.getBeanClassName();
+                        if (null != className) {
+                            final String name = n.charAt(0) != '*' ? n
+                                    : "." + n.replaceAll("\\.", "\\."); //old wildcard
+                            try {
+                                Matcher matcher = Pattern.compile(name).matcher("");
+                                List<MatcherHolder> m = wildCardBeanDefinitions.get(className);
+                                if (m == null) {
+                                    m = new ArrayList<>();
+                                    wildCardBeanDefinitions.put(className, m);
+                                }
+                                MatcherHolder holder = new MatcherHolder(n, matcher);
+                                m.add(holder);
+                            } catch (PatternSyntaxException npe) {
+                                //not a valid patter, we'll ignore
+                            }
+                        } else {
+                            LogUtils.log(LOG, Level.WARNING, "WILDCARD_BEAN_ID_WITH_NO_CLASS_MSG", n);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void configureBean(Object beanInstance) {
+        configureBean(null, beanInstance, true);
+    }
+
+    public void configureBean(String bn, Object beanInstance) {
+        configureBean(bn, beanInstance, true);
+    }
+    public synchronized void configureBean(String bn, Object beanInstance, boolean checkWildcards) {
+
+        if (null == appContexts) {
+            return;
+        }
+
+        if (null == bn) {
+            bn = getBeanName(beanInstance);
+            if (null == bn) {
+                return;
+            }
+        }
+
+        if (checkWildcards) {
+            configureWithWildCard(bn, beanInstance);
+        }
+
+        final String beanName = bn;
+        setBeanWiringInfoResolver(new BeanWiringInfoResolver() {
+            public BeanWiringInfo resolveWiringInfo(Object instance) {
+                if (!beanName.isEmpty()) {
+                    return new BeanWiringInfo(beanName);
+                }
+                return null;
+            }
+        });
+
+        for (ApplicationContext appContext : appContexts) {
+            if (appContext.containsBean(bn)) {
+                this.setBeanFactory(appContext.getAutowireCapableBeanFactory());
+            }
+        }
+
+        try {
+            //this will prevent a call into the AbstractBeanFactory.markBeanAsCreated(...)
+            //which saves ALL the names into a HashSet.  For URL based configuration,
+            //this can leak memory
+            if (beanFactory instanceof AbstractBeanFactory) {
+                ((AbstractBeanFactory)beanFactory).getMergedBeanDefinition(bn);
+            }
+            super.configureBean(beanInstance);
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Successfully performed injection.");
+            }
+        } catch (NoSuchBeanDefinitionException ex) {
+            // users often wonder why the settings in their configuration files seem
+            // to have no effect - the most common cause is that they have been using
+            // incorrect bean ids
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.log(Level.FINE, "NO_MATCHING_BEAN_MSG", beanName);
+            }
+        }
+    }
+
+    private void configureWithWildCard(String bn, Object beanInstance) {
+        if (!wildCardBeanDefinitions.isEmpty()) {
+            Class<?> clazz = beanInstance.getClass();
+            while (!Object.class.equals(clazz)) {
+                String className = clazz.getName();
+                List<MatcherHolder> matchers = wildCardBeanDefinitions.get(className);
+                if (matchers != null) {
+                    for (MatcherHolder m : matchers) {
+                        synchronized (m.matcher) {
+                            m.matcher.reset(bn);
+                            if (m.matcher.matches()) {
+                                configureBean(m.wildCardId, beanInstance, false);
+                                return;
+                            }
+                        }
+                    }
+                }
+                clazz = clazz.getSuperclass();
+            }
+        }
+    }
+
+    private boolean isWildcardBeanName(String bn) {
+        return bn.indexOf('*') != -1 || bn.indexOf('?') != -1
+            || (bn.indexOf('(') != -1 && bn.indexOf(')') != -1);
+    }
+
+    protected String getBeanName(Object beanInstance) {
+        if (beanInstance instanceof Configurable) {
+            return ((Configurable)beanInstance).getBeanName();
+        }
+        String beanName = null;
+        Method m = null;
+        try {
+            m = beanInstance.getClass().getDeclaredMethod("getBeanName", (Class[])null);
+        } catch (NoSuchMethodException ex) {
+            try {
+                m = beanInstance.getClass().getMethod("getBeanName", (Class[])null);
+            } catch (NoSuchMethodException e) {
+                //ignore
+            }
+        }
+        if (m != null) {
+            try {
+                beanName = (String)(m.invoke(beanInstance));
+            } catch (Exception ex) {
+                LogUtils.log(LOG, Level.WARNING, "ERROR_DETERMINING_BEAN_NAME_EXC", ex);
+            }
+        }
+
+        if (null == beanName) {
+            LogUtils.log(LOG, Level.FINE, "COULD_NOT_DETERMINE_BEAN_NAME_MSG",
+                         beanInstance.getClass().getName());
+        }
+
+        return beanName;
+    }
+
+    public final void setApplicationContext(ApplicationContext ac) {
+        appContexts = new CopyOnWriteArraySet<>();
+        addApplicationContext(ac);
+        this.beanFactory = ac.getAutowireCapableBeanFactory();
+        super.setBeanFactory(this.beanFactory);
+    }
+
+    public final void addApplicationContext(ApplicationContext ac) {
+        if (!appContexts.contains(ac)) {
+            appContexts.add(ac);
+            List<ApplicationContext> inactiveApplicationContexts = new ArrayList<>();
+            Iterator<ApplicationContext> it = appContexts.iterator();
+            while (it.hasNext()) {
+                ApplicationContext c = it.next();
+                if (c instanceof ConfigurableApplicationContext
+                    && !((ConfigurableApplicationContext)c).isActive()) {
+                    inactiveApplicationContexts.add(c);
+                }
+            }
+            // Remove the inactive application context here can avoid the UnsupportedOperationException
+            for (ApplicationContext context : inactiveApplicationContexts) {
+                appContexts.remove(context);
+            }
+            initWildcardDefinitionMap();
+        }
+    }
+
+    @Override
+    public void destroy() {
+        super.destroy();
+        appContexts.clear();
+    }
+
+    public Class<?> getRegistrationType() {
+        return Configurer.class;
+    }
+
+    protected Set<ApplicationContext> getAppContexts() {
+        return appContexts;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/databinding/source/SourceDataBinding.java b/transform/src/patch/java/org/apache/cxf/databinding/source/SourceDataBinding.java
new file mode 100644
index 0000000..5321779
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/databinding/source/SourceDataBinding.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.cxf.databinding.source;
+
+
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.w3c.dom.Node;
+
+import org.apache.cxf.common.xmlschema.SchemaCollection;
+import org.apache.cxf.databinding.DataReader;
+import org.apache.cxf.databinding.DataWriter;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.ServiceModelVisitor;
+import org.apache.cxf.service.model.MessagePartInfo;
+import org.apache.cxf.service.model.ServiceInfo;
+import org.apache.ws.commons.schema.constants.Constants;
+
+/**
+ * A simple databinding implementation which reads and writes Source objects.
+ */
+public class SourceDataBinding extends org.apache.cxf.databinding.AbstractDataBinding {
+
+    public static final String PREFERRED_FORMAT = "source-preferred-format";
+
+    final Class<?> preferred;
+
+    public SourceDataBinding() {
+        super();
+        preferred = null;
+    }
+    public SourceDataBinding(Class<?> pref) {
+        super();
+        preferred = pref;
+    }
+
+    public void initialize(Service service) {
+        for (ServiceInfo serviceInfo : service.getServiceInfos()) {
+            SchemaCollection schemaCollection = serviceInfo.getXmlSchemaCollection();
+            if (schemaCollection.getXmlSchemas().length > 1) {
+                // Schemas are already populated.
+                continue;
+            }
+            new ServiceModelVisitor(serviceInfo) {
+                @Override
+                public void begin(MessagePartInfo part) {
+                    if (part.getTypeQName() != null || part.getElementQName() != null) {
+                        return;
+                    }
+                    part.setTypeQName(Constants.XSD_ANYTYPE);
+                }
+            } .walk();
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public <T> DataReader<T> createReader(Class<T> cls) {
+        if (cls == XMLStreamReader.class) {
+            return (DataReader<T>) new XMLStreamDataReader(preferred);
+        } else if (cls == Node.class) {
+            return (DataReader<T>) new NodeDataReader();
+        } else {
+            throw new UnsupportedOperationException("The type " + cls.getName() + " is not supported.");
+        }
+    }
+
+    public Class<?>[] getSupportedReaderFormats() {
+        return new Class<?>[] {XMLStreamReader.class, Node.class};
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> DataWriter<T> createWriter(Class<T> cls) {
+        if (cls == XMLStreamWriter.class) {
+            return (DataWriter<T>) new XMLStreamDataWriter();
+        } else if (cls == Node.class) {
+            return (DataWriter<T>) new NodeDataWriter();
+        }
+        throw new UnsupportedOperationException("The type " + cls.getName() + " is not supported.");
+    }
+
+    public Class<?>[] getSupportedWriterFormats() {
+        return new Class<?>[] {XMLStreamWriter.class, Node.class};
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/databinding/stax/StaxDataBinding.java b/transform/src/patch/java/org/apache/cxf/databinding/stax/StaxDataBinding.java
new file mode 100644
index 0000000..3cb836b
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/databinding/stax/StaxDataBinding.java
@@ -0,0 +1,187 @@
+/**
+ * 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.cxf.databinding.stax;
+
+import java.util.Collection;
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.validation.Schema;
+
+import org.w3c.dom.Node;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.xmlschema.SchemaCollection;
+import org.apache.cxf.databinding.AbstractInterceptorProvidingDataBinding;
+import org.apache.cxf.databinding.DataReader;
+import org.apache.cxf.databinding.DataWriter;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.interceptor.StaxInEndingInterceptor;
+import org.apache.cxf.message.Attachment;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.ServiceModelVisitor;
+import org.apache.cxf.service.model.MessagePartInfo;
+import org.apache.cxf.service.model.ServiceInfo;
+import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.ws.commons.schema.constants.Constants;
+
+/**
+ * A simple databinding implementation which reads and writes Source objects.
+ * This will not work with the standard databinding interceptors.
+ */
+public class StaxDataBinding extends AbstractInterceptorProvidingDataBinding {
+
+    private XMLStreamDataReader xsrReader;
+    private XMLStreamDataWriter xswWriter;
+
+    public StaxDataBinding() {
+        super();
+        this.xsrReader = new XMLStreamDataReader();
+        this.xswWriter = new XMLStreamDataWriter();
+        inInterceptors.add(new StaxInEndingInterceptor(Phase.POST_INVOKE));
+        inFaultInterceptors.add(new StaxInEndingInterceptor(Phase.POST_INVOKE));
+
+        inInterceptors.add(RemoveStaxInEndingInterceptor.INSTANCE);
+        inFaultInterceptors.add(RemoveStaxInEndingInterceptor.INSTANCE);
+    }
+
+    static class RemoveStaxInEndingInterceptor extends AbstractPhaseInterceptor<Message> {
+        static final RemoveStaxInEndingInterceptor INSTANCE = new RemoveStaxInEndingInterceptor();
+
+        RemoveStaxInEndingInterceptor() {
+            super(Phase.PRE_INVOKE);
+            addBefore(StaxInEndingInterceptor.class.getName());
+        }
+
+        public void handleMessage(Message message) {
+            message.getInterceptorChain().remove(StaxInEndingInterceptor.INSTANCE);
+        }
+    }
+
+
+    public void initialize(Service service) {
+        for (ServiceInfo serviceInfo : service.getServiceInfos()) {
+            SchemaCollection schemaCollection = serviceInfo.getXmlSchemaCollection();
+            if (schemaCollection.getXmlSchemas().length > 1) {
+                // Schemas are already populated.
+                continue;
+            }
+            new ServiceModelVisitor(serviceInfo) {
+                
+                @Override
+                public void begin(MessagePartInfo part) {
+                    if (part.getTypeQName() != null || part.getElementQName() != null) {
+                        return;
+                    }
+                    part.setTypeQName(Constants.XSD_ANYTYPE);
+                }
+            } .walk();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> DataReader<T> createReader(Class<T> cls) {
+        if (cls == XMLStreamReader.class) {
+            return (DataReader<T>) xsrReader;
+        }
+        throw new UnsupportedOperationException("The type " + cls.getName() + " is not supported.");
+    }
+
+    public Class<?>[] getSupportedReaderFormats() {
+        return new Class<?>[] {XMLStreamReader.class};
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> DataWriter<T> createWriter(Class<T> cls) {
+        if (cls == XMLStreamWriter.class) {
+            return (DataWriter<T>) xswWriter;
+        }
+        throw new UnsupportedOperationException("The type " + cls.getName() + " is not supported.");
+    }
+
+    public Class<?>[] getSupportedWriterFormats() {
+        return new Class<?>[] {XMLStreamWriter.class, Node.class};
+    }
+
+    public static class XMLStreamDataReader implements DataReader<XMLStreamReader> {
+
+        public Object read(MessagePartInfo part, XMLStreamReader input) {
+            return read(null, input, part.getTypeClass());
+        }
+
+        public Object read(QName name, XMLStreamReader input, Class<?> type) {
+            return input;
+        }
+
+        public Object read(XMLStreamReader reader) {
+            return reader;
+        }
+
+        public void setSchema(Schema s) {
+        }
+
+        public void setAttachments(Collection<Attachment> attachments) {
+        }
+
+        public void setProperty(String prop, Object value) {
+        }
+    }
+
+    public static class XMLStreamDataWriter implements DataWriter<XMLStreamWriter> {
+        private static final Logger LOG = LogUtils.getL7dLogger(XMLStreamDataWriter.class);
+
+        public void write(Object obj, MessagePartInfo part, XMLStreamWriter output) {
+            write(obj, output);
+        }
+
+        public void write(Object obj, XMLStreamWriter writer) {
+            try {
+                if (obj instanceof XMLStreamReader) {
+                    XMLStreamReader xmlStreamReader = (XMLStreamReader) obj;
+                    StaxUtils.copy(xmlStreamReader, writer);
+                    xmlStreamReader.close();
+                } else if (obj instanceof XMLStreamWriterCallback) {
+                    ((XMLStreamWriterCallback) obj).write(writer);
+                } else {
+                    throw new UnsupportedOperationException("Data types of "
+                                                            + obj.getClass() + " are not supported.");
+                }
+            } catch (XMLStreamException e) {
+                throw new Fault("COULD_NOT_READ_XML_STREAM", LOG, e);
+            }
+        }
+
+        public void setSchema(Schema s) {
+        }
+
+        public void setAttachments(Collection<Attachment> attachments) {
+        }
+
+        public void setProperty(String key, Object value) {
+        }
+
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/endpoint/AbstractConduitSelector.java b/transform/src/patch/java/org/apache/cxf/endpoint/AbstractConduitSelector.java
new file mode 100644
index 0000000..250e523
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/endpoint/AbstractConduitSelector.java
@@ -0,0 +1,308 @@
+/**
+ * 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.cxf.endpoint;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Logger;
+
+import org.apache.cxf.BusException;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.Conduit;
+import org.apache.cxf.transport.ConduitInitiator;
+import org.apache.cxf.transport.ConduitInitiatorManager;
+import org.apache.cxf.transport.MessageObserver;
+import org.apache.cxf.ws.addressing.AttributedURIType;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+
+
+/**
+ * Abstract base class holding logic common to any ConduitSelector
+ * that retrieves a Conduit from the ConduitInitiator.
+ */
+public abstract class AbstractConduitSelector implements ConduitSelector, Closeable {
+    public static final String CONDUIT_COMPARE_FULL_URL
+        = "org.apache.cxf.ConduitSelector.compareFullUrl";
+    protected static final String KEEP_CONDUIT_ALIVE = "KeepConduitAlive";
+
+
+    //collection of conduits that were created so we can close them all at the end
+    protected List<Conduit> conduits = new CopyOnWriteArrayList<>();
+
+   
+    protected Endpoint endpoint;
+
+
+    public AbstractConduitSelector() {
+    }
+
+    /**
+     * Constructor, allowing a specific conduit to override normal selection.
+     *
+     * @param c specific conduit
+     */
+    public AbstractConduitSelector(Conduit c) {
+        if (c != null) {
+            conduits.add(c);
+        }
+    }
+
+    public void close() {
+        for (Conduit c : conduits) {
+            c.close();
+        }
+        conduits.clear();
+    }
+
+    protected void removeConduit(Conduit conduit) {
+        if (conduit != null) {
+            conduit.close();
+            conduits.remove(conduit);
+        }
+    }
+
+    /**
+     * Mechanics to actually get the Conduit from the ConduitInitiator
+     * if necessary.
+     *
+     * @param message the current Message
+     */
+    protected Conduit getSelectedConduit(Message message) {
+        Conduit c = findCompatibleConduit(message);
+        if (c == null) {
+            Exchange exchange = message.getExchange();
+            EndpointInfo ei = endpoint.getEndpointInfo();
+            String transportID = ei.getTransportId();
+            try {
+                ConduitInitiatorManager conduitInitiatorMgr = exchange.getBus()
+                    .getExtension(ConduitInitiatorManager.class);
+                if (conduitInitiatorMgr != null) {
+                    ConduitInitiator conduitInitiator =
+                        conduitInitiatorMgr.getConduitInitiator(transportID);
+                    if (conduitInitiator != null) {
+                        c = createConduit(message, exchange, conduitInitiator);
+                    } else {
+                        getLogger().warning("ConduitInitiator not found: "
+                                            + ei.getAddress());
+                    }
+                } else {
+                    getLogger().warning("ConduitInitiatorManager not found");
+                }
+            } catch (BusException | IOException ex) {
+                throw new Fault(ex);
+            }
+        }
+        if (c != null && c.getTarget() != null && c.getTarget().getAddress() != null) {
+            replaceEndpointAddressPropertyIfNeeded(message, c.getTarget().getAddress().getValue(), c);
+        }
+        //the search for the conduit could cause extra properties to be reset/loaded.
+        message.resetContextCache();
+        message.put(Conduit.class, c);
+        return c;
+    }
+
+    protected Conduit createConduit(Message message, Exchange exchange, ConduitInitiator conduitInitiator)
+        throws IOException {
+        Conduit c;
+        synchronized (endpoint) {
+            if (!conduits.isEmpty()) {
+                c = findCompatibleConduit(message);
+                if (c != null) {
+                    return c;
+                }
+            }
+            EndpointInfo ei = endpoint.getEndpointInfo();
+            String add = (String)message.get(Message.ENDPOINT_ADDRESS);
+            String basePath = (String)message.get(Message.BASE_PATH);
+            if (StringUtils.isEmpty(add)
+                || add.equals(ei.getAddress())) {
+                c = conduitInitiator.getConduit(ei, exchange.getBus());
+                replaceEndpointAddressPropertyIfNeeded(message, add, c);
+            } else {
+                EndpointReferenceType epr = new EndpointReferenceType();
+                AttributedURIType ad = new AttributedURIType();
+                ad.setValue(StringUtils.isEmpty(basePath) ? add : basePath);
+                epr.setAddress(ad);
+                c = conduitInitiator.getConduit(ei, epr, exchange.getBus());
+            }
+            MessageObserver observer =
+                exchange.get(MessageObserver.class);
+            if (observer != null) {
+                c.setMessageObserver(observer);
+            } else {
+                getLogger().warning("MessageObserver not found");
+            }
+            conduits.add(c);
+        }
+        return c;
+    }
+
+    // Some conduits may replace the endpoint address after it has already been prepared
+    // but before the invocation has been done (ex, org.apache.cxf.clustering.LoadDistributorTargetSelector)
+    // which may affect JAX-RS clients where actual endpoint address property may include additional path
+    // segments.
+    protected boolean replaceEndpointAddressPropertyIfNeeded(Message message,
+                                                             String endpointAddress,
+                                                             Conduit cond) {
+        return false;
+    }
+
+    /**
+     * @return the encapsulated Endpoint
+     */
+    public Endpoint getEndpoint() {
+        return endpoint;
+    }
+
+    /**
+     * @param ep the endpoint to encapsulate
+     */
+    public void setEndpoint(Endpoint ep) {
+        endpoint = ep;
+    }
+
+    /**
+     * Called on completion of the MEP for which the Conduit was required.
+     *
+     * @param exchange represents the completed MEP
+     */
+    public void complete(Exchange exchange) {
+        // Clients expecting explicit InputStream responses
+        // will need to keep low level conduits operating on InputStreams open
+        // and will be responsible for closing the streams
+
+        if (PropertyUtils.isTrue(exchange.get(KEEP_CONDUIT_ALIVE))) {
+            return;
+        }
+        try {
+            if (exchange.getInMessage() != null) {
+                Conduit c = exchange.getOutMessage().get(Conduit.class);
+                if (c == null) {
+                    getSelectedConduit(exchange.getInMessage()).close(exchange.getInMessage());
+                } else {
+                    c.close(exchange.getInMessage());
+                }
+            }
+        } catch (IOException e) {
+            //IGNORE
+        }
+    }
+    /**
+     * @return the logger to use
+     */
+    protected abstract Logger getLogger();
+
+    /**
+     * If address protocol was changed, conduit should be re-initialised
+     *
+     * @param message the current Message
+     */
+    protected Conduit findCompatibleConduit(Message message) {
+        Conduit c = message.get(Conduit.class);
+        if (c == null
+            && message.getExchange() != null
+            && message.getExchange().getOutMessage() != null
+            && message.getExchange().getOutMessage() != message) {
+            c = message.getExchange().getOutMessage().get(Conduit.class);
+        }
+        if (c != null) {
+            return c;
+        }
+        ContextualBooleanGetter cbg = new ContextualBooleanGetter(message);
+        for (Conduit c2 : conduits) {
+            if (c2.getTarget() == null
+                || c2.getTarget().getAddress() == null
+                || c2.getTarget().getAddress().getValue() == null) {
+                continue;
+            }
+            String conduitAddress = c2.getTarget().getAddress().getValue();
+
+            EndpointInfo ei = endpoint.getEndpointInfo();
+            String actualAddress = ei.getAddress();
+
+            String messageAddress = (String)message.get(Message.ENDPOINT_ADDRESS);
+            if (messageAddress != null) {
+                actualAddress = messageAddress;
+            }
+
+            if (matchAddresses(conduitAddress, actualAddress, cbg)) {
+                return c2;
+            }
+        }
+        for (Conduit c2 : conduits) {
+            if (c2.getTarget() == null
+                || c2.getTarget().getAddress() == null
+                || c2.getTarget().getAddress().getValue() == null) {
+                return c2;
+            }
+        }
+        return null;
+    }
+
+    private boolean matchAddresses(String conduitAddress, String actualAddress, ContextualBooleanGetter cbg) {
+        if (conduitAddress.length() == actualAddress.length()) {
+            //let's be optimistic and try full comparison first, regardless of CONDUIT_COMPARE_FULL_URL value,
+            //which can be expensive to fetch; as a matter of fact, anyway, if the addresses fully match,
+            //their hosts also match
+            if (conduitAddress.equalsIgnoreCase(actualAddress)) {
+                return true;
+            }
+            return !cbg.isFullComparison() && matchAddressSubstrings(conduitAddress, actualAddress);
+        }
+        return !cbg.isFullComparison() && matchAddressSubstrings(conduitAddress, actualAddress);
+    }
+
+    //smart address substring comparison that tries to avoid building and comparing substrings unless strictly required
+    private boolean matchAddressSubstrings(String conduitAddress, String actualAddress) {
+        int idx = conduitAddress.indexOf(':');
+        if (idx == actualAddress.indexOf(':')) {
+            if (idx <= 0) {
+                return true;
+            }
+            return conduitAddress.substring(0, idx).equalsIgnoreCase(actualAddress.substring(0, idx));
+        }
+        //no possible match as for sure the substrings before idx will be different
+        return false;
+    }
+
+    private static final class ContextualBooleanGetter {
+        private Boolean value;
+        private final Message message;
+
+        ContextualBooleanGetter(Message message) {
+            this.message = message;
+        }
+
+        public boolean isFullComparison() {
+            if (value == null) {
+                value = MessageUtils.getContextualBoolean(message, CONDUIT_COMPARE_FULL_URL, false);
+            }
+            return value;
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/endpoint/ClientCallback.java b/transform/src/patch/java/org/apache/cxf/endpoint/ClientCallback.java
new file mode 100644
index 0000000..467b5a8
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/endpoint/ClientCallback.java
@@ -0,0 +1,166 @@
+/**
+ * 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.cxf.endpoint;
+
+import java.util.Map;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.cxf.message.Message;
+
+/**
+ * Asynchronous callback object for calls to {@link Client#invoke(ClientCallback, String, Object...)}
+ * and related functions.
+ *
+ * The default behavior of this expects the following pattern:
+ * <ol>
+ * <li>ClientCallback cb = new ClientCallback();<>
+ * <li>client.invoke(cb, "someMethod", ....);</li>
+ * <li>cb.wait();</li>
+ * <li>// CXF calls notify on the callback object when the operation is complete.</li>
+ * </ol>
+ */
+public class ClientCallback implements Future<Object[]> {
+    protected final CompletableFuture<Object[]> delegate = new CompletableFuture<>();
+    protected Map<String, Object> context;
+    protected boolean started;
+
+    public ClientCallback() {
+    }
+
+    /**
+     * Called when a message is first received prior to any actions
+     * being applied to the message.   The InterceptorChain is setup so
+     * modifications to that can be done.
+     */
+    public void start(Message msg) {
+        started = true;
+    }
+
+    /**
+     * If the processing of the incoming message proceeds normally, this
+     * method is called with the response context values and the resulting objects.
+     *
+     * The default behavior just stores the objects and calls notifyAll to wake
+     * up threads waiting for the response.
+     *
+     * @param ctx
+     * @param res
+     */
+    public void handleResponse(Map<String, Object> ctx, Object[] res) {
+        context = ctx;
+        delegate.complete(res);
+
+        synchronized (this) {
+            notifyAll();
+        }
+    }
+
+    /**
+     * If processing of the incoming message results in an exception, this
+     * method is called with the resulting exception.
+     *
+     * The default behavior just stores the objects and calls notifyAll to wake
+     * up threads waiting for the response.
+     *
+     * @param ctx
+     * @param ex
+     */
+    public void handleException(Map<String, Object> ctx, Throwable ex) {
+        context = ctx;
+        delegate.completeExceptionally(ex);
+        
+        synchronized (this) {
+            notifyAll();
+        }
+    }
+
+
+    public boolean cancel(boolean mayInterruptIfRunning) {
+        if (!started) {
+            delegate.cancel(mayInterruptIfRunning);
+            
+            synchronized (this) {
+                notifyAll();
+            }
+            
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * return the map of items returned from an operation.
+     * @return the response context
+     * @throws InterruptedException if the operation was cancelled.
+     * @throws ExecutionException if the operation resulted in a fault.
+     */
+    public Map<String, Object> getResponseContext() throws InterruptedException, ExecutionException {
+        synchronized (this) {
+            if (!delegate.isDone()) {
+                wait();
+            }
+        }
+        if (delegate.isCancelled()) {
+            throw new InterruptedException("Operation Cancelled");
+        }
+        if (delegate.isCompletedExceptionally()) {
+            delegate.get();
+        }
+        return context;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object[] get() throws InterruptedException, ExecutionException {
+        try {
+            return delegate.get();
+        } catch (final CancellationException ex) {
+            // Preserving the exception raised by former implementation
+            throw new InterruptedException("Operation has been cancelled");
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object[] get(long timeout, TimeUnit unit) throws InterruptedException, 
+            ExecutionException, TimeoutException {
+        try {
+            return delegate.get(timeout, unit);
+        } catch (final CancellationException ex) {
+            // Preserving the exception raised by former implementation
+            throw new InterruptedException("Operation has been cancelled");
+        }
+    }
+
+    public boolean isCancelled() {
+        return delegate.isCancelled();
+    }
+
+    public boolean isDone() {
+        return delegate.isDone();
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/endpoint/ClientImpl.java b/transform/src/patch/java/org/apache/cxf/endpoint/ClientImpl.java
new file mode 100644
index 0000000..53d3a43
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/endpoint/ClientImpl.java
@@ -0,0 +1,1192 @@
+/**
+ * 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.cxf.endpoint;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.handler.MessageContext;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.binding.Binding;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.classloader.ClassLoaderUtils.ClassLoaderHolder;
+import org.apache.cxf.common.i18n.UncheckedException;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.AbstractBasicInterceptorProvider;
+import org.apache.cxf.interceptor.ClientOutFaultObserver;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.interceptor.InterceptorChain;
+import org.apache.cxf.interceptor.InterceptorProvider;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageContentsList;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.phase.PhaseChainCache;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.apache.cxf.phase.PhaseManager;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.model.BindingInfo;
+import org.apache.cxf.service.model.BindingMessageInfo;
+import org.apache.cxf.service.model.BindingOperationInfo;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.service.model.MessageInfo;
+import org.apache.cxf.service.model.ServiceInfo;
+import org.apache.cxf.transport.Conduit;
+import org.apache.cxf.transport.MessageObserver;
+import org.apache.cxf.workqueue.SynchronousExecutor;
+
+public class ClientImpl
+    extends AbstractBasicInterceptorProvider
+    implements Client, Retryable, MessageObserver {
+
+    public static final String THREAD_LOCAL_REQUEST_CONTEXT = "thread.local.request.context";
+    /**
+     * When a synchronous request/response invoke is done using an asynchronous transport mechanism,
+     * this is the timeout used for waiting for the response.  Default is 60 seconds.
+     */
+    public static final String SYNC_TIMEOUT = "cxf.synchronous.timeout";
+
+    public static final String FINISHED = "exchange.finished";
+
+    private static final Logger LOG = LogUtils.getL7dLogger(ClientImpl.class);
+
+    protected Bus bus;
+    protected ConduitSelector conduitSelector;
+    protected ClientOutFaultObserver outFaultObserver;
+    protected int synchronousTimeout = 60000; // default 60 second timeout
+
+    protected PhaseChainCache outboundChainCache = new PhaseChainCache();
+    protected PhaseChainCache inboundChainCache = new PhaseChainCache();
+
+    protected Map<String, Object> currentRequestContext = new ConcurrentHashMap<>(8, 0.75f, 4);
+    protected Thread latestContextThread;
+    protected Map<Thread, EchoContext> requestContext
+        = Collections.synchronizedMap(new WeakHashMap<Thread, EchoContext>());
+
+    protected Map<Thread, ResponseContext> responseContext
+        = Collections.synchronizedMap(new WeakHashMap<Thread, ResponseContext>());
+
+    protected Executor executor;
+
+    public ClientImpl(Bus b, Endpoint e) {
+        this(b, e, (ConduitSelector)null);
+    }
+
+    public ClientImpl(Bus b, Endpoint e, Conduit c) {
+        this(b, e, new PreexistingConduitSelector(c));
+    }
+
+    public ClientImpl(Bus b, Endpoint e, ConduitSelector sc) {
+        bus = b;
+        outFaultObserver = new ClientOutFaultObserver(bus);
+        getConduitSelector(sc).setEndpoint(e);
+        notifyLifecycleManager();
+    }
+
+    /**
+     * Create a Client that uses a specific EndpointImpl.
+     * @param bus
+     * @param svc
+     * @param port
+     * @param endpointImplFactory
+     */
+    public ClientImpl(Bus bus, Service svc, QName port,
+                      EndpointImplFactory endpointImplFactory) {
+        this.bus = bus;
+        outFaultObserver = new ClientOutFaultObserver(bus);
+        EndpointInfo epfo = findEndpoint(svc, port);
+
+        try {
+            if (endpointImplFactory != null) {
+                getConduitSelector().setEndpoint(endpointImplFactory.newEndpointImpl(bus, svc, epfo));
+            } else {
+                getConduitSelector().setEndpoint(new EndpointImpl(bus, svc, epfo));
+            }
+        } catch (EndpointException epex) {
+            throw new IllegalStateException("Unable to create endpoint: " + epex.getMessage(), epex);
+        }
+        notifyLifecycleManager();
+    }
+
+    public Bus getBus() {
+        return bus;
+    }
+
+    public void destroy() {
+        if (bus == null) {
+            return;
+        }
+        if (getEndpoint() != null) {
+            for (Closeable c : getEndpoint().getCleanupHooks()) {
+                try {
+                    c.close();
+                } catch (IOException e) {
+                    //ignore
+                }
+            }
+        }
+        ClientLifeCycleManager mgr = bus.getExtension(ClientLifeCycleManager.class);
+        if (null != mgr) {
+            mgr.clientDestroyed(this);
+        }
+
+        if (conduitSelector != null) {
+            if (conduitSelector instanceof Closeable) {
+                try {
+                    ((Closeable)conduitSelector).close();
+                } catch (IOException e) {
+                    //ignore, we're destroying anyway
+                }
+            } else {
+                getConduit().close();
+            }
+        }
+
+        bus = null;
+        conduitSelector = null;
+        outFaultObserver = null;
+        outboundChainCache = null;
+        inboundChainCache = null;
+
+        currentRequestContext = null;
+        requestContext.clear();
+        requestContext = null;
+        responseContext.clear();
+        responseContext = null;
+        executor = null;
+    }
+
+    private void notifyLifecycleManager() {
+        ClientLifeCycleManager mgr = bus.getExtension(ClientLifeCycleManager.class);
+        if (null != mgr) {
+            mgr.clientCreated(this);
+        }
+    }
+
+    private EndpointInfo findEndpoint(Service svc, QName port) {
+        if (port != null) {
+            EndpointInfo epfo = svc.getEndpointInfo(port);
+            if (epfo == null) {
+                throw new IllegalArgumentException("The service " + svc.getName()
+                                                   + " does not have an endpoint " + port + ".");
+            }
+            return epfo;
+        }
+        
+        for (ServiceInfo svcfo : svc.getServiceInfos()) {
+            for (EndpointInfo e : svcfo.getEndpoints()) {
+                BindingInfo bfo = e.getBinding();
+                String bid = bfo.getBindingId();
+                if ("http://schemas.xmlsoap.org/wsdl/soap/".equals(bid)
+                    || "http://schemas.xmlsoap.org/wsdl/soap12/".equals(bid)) {
+                    for (Object o : bfo.getExtensors().get()) {
+                        try {
+                            String s = (String)o.getClass().getMethod("getTransportURI").invoke(o);
+                            if (s != null && s.endsWith("http")) {
+                                return e;
+                            }
+                        } catch (Throwable t) {
+                            //ignore
+                        }
+                    }
+                }
+            }
+        }
+        throw new UnsupportedOperationException(
+             "Only document-style SOAP 1.1 and 1.2 http are supported "
+             + "for auto-selection of endpoint; none were found.");
+    }
+
+    public Endpoint getEndpoint() {
+        return getConduitSelector().getEndpoint();
+    }
+
+    public void releaseThreadContexts() {
+        final Thread t = Thread.currentThread();
+        requestContext.remove(t);
+        responseContext.remove(t);
+    }
+
+    @Override
+    public Contexts getContexts() {
+        return new Contexts() {
+            @Override
+            public void close() throws Exception {
+                releaseThreadContexts();
+            }
+            @Override
+            public Map<String, Object> getRequestContext() {
+                return ClientImpl.this.getRequestContext();
+            }
+            @Override
+            public Map<String, Object> getResponseContext() {
+                return ClientImpl.this.getResponseContext();
+            }
+        };
+    }
+
+    public Map<String, Object> getRequestContext() {
+        if (isThreadLocalRequestContext()) {
+            final Thread t = Thread.currentThread();
+            requestContext.computeIfAbsent(t, k -> new EchoContext(currentRequestContext));
+            latestContextThread = t;
+            return requestContext.get(t);
+        }
+        return currentRequestContext;
+    }
+    public Map<String, Object> getResponseContext() {
+        if (!responseContext.containsKey(Thread.currentThread())) {
+            final Thread t = Thread.currentThread();
+            responseContext.put(t, new ResponseContext(responseContext));
+        }
+        return responseContext.get(Thread.currentThread());
+    }
+    protected Map<String, Object> setResponseContext(Map<String, Object> ctx) {
+        if (ctx instanceof ResponseContext) {
+            ResponseContext c = (ResponseContext)ctx;
+            responseContext.put(Thread.currentThread(), c);
+            return c;
+        }
+        ResponseContext c = new ResponseContext(ctx, responseContext);
+        responseContext.put(Thread.currentThread(), c);
+        return c;
+    }
+    public boolean isThreadLocalRequestContext() {
+        Object o = currentRequestContext.get(THREAD_LOCAL_REQUEST_CONTEXT);
+        if (o != null) {
+            final boolean local;
+            if (o instanceof Boolean) {
+                local = ((Boolean)o).booleanValue();
+            } else {
+                local = Boolean.parseBoolean(o.toString());
+            }
+            return local;
+        }
+        return false;
+    }
+    public void setThreadLocalRequestContext(boolean b) {
+        currentRequestContext.put(THREAD_LOCAL_REQUEST_CONTEXT, b);
+    }
+
+
+    public Object[] invoke(BindingOperationInfo oi, Object... params) throws Exception {
+        return invoke(oi, params, null);
+    }
+
+    public Object[] invoke(String operationName, Object... params) throws Exception {
+        QName q = new QName(getEndpoint().getService().getName().getNamespaceURI(), operationName);
+
+        return invoke(q, params);
+    }
+
+    public Object[] invoke(QName operationName, Object... params) throws Exception {
+        BindingOperationInfo op = getEndpoint().getEndpointInfo().getBinding().getOperation(operationName);
+        if (op == null) {
+            throw new UncheckedException(
+                new org.apache.cxf.common.i18n.Message("NO_OPERATION", LOG, operationName));
+        }
+
+        if (op.isUnwrappedCapable()) {
+            op = op.getUnwrappedOperation();
+        }
+
+        return invoke(op, params);
+    }
+
+    public Object[] invokeWrapped(String operationName, Object... params) throws Exception {
+        QName q = new QName(getEndpoint().getService().getName().getNamespaceURI(), operationName);
+
+        return invokeWrapped(q, params);
+    }
+
+    public Object[] invokeWrapped(QName operationName, Object... params) throws Exception {
+        BindingOperationInfo op = getEndpoint().getEndpointInfo().getBinding().getOperation(operationName);
+        if (op == null) {
+            throw new UncheckedException(
+                new org.apache.cxf.common.i18n.Message("NO_OPERATION", LOG, operationName));
+        }
+        return invoke(op, params);
+    }
+
+    public Object[] invoke(BindingOperationInfo oi,
+                           Object[] params,
+                           Exchange exchange) throws Exception {
+        Map<String, Object> context = new HashMap<>();
+        return invoke(oi, params, context, exchange);
+    }
+    public Object[] invoke(BindingOperationInfo oi,
+                           Object[] params,
+                           Map<String, Object> context) throws Exception {
+        return invoke(oi, params, context, (Exchange)null);
+    }
+
+    public void invoke(ClientCallback callback,
+                       String operationName,
+                       Object... params) throws Exception {
+        QName q = new QName(getEndpoint().getService().getName().getNamespaceURI(), operationName);
+        invoke(callback, q, params);
+    }
+
+    public void invoke(ClientCallback callback,
+                       QName operationName,
+                       Object... params) throws Exception {
+        BindingOperationInfo op = getEndpoint().getEndpointInfo().getBinding().getOperation(operationName);
+        if (op == null) {
+            throw new UncheckedException(
+                new org.apache.cxf.common.i18n.Message("NO_OPERATION", LOG, operationName));
+        }
+
+        if (op.isUnwrappedCapable()) {
+            op = op.getUnwrappedOperation();
+        }
+
+        invoke(callback, op, params);
+    }
+
+
+    public void invokeWrapped(ClientCallback callback,
+                              String operationName,
+                              Object... params)
+        throws Exception {
+        QName q = new QName(getEndpoint().getService().getName().getNamespaceURI(), operationName);
+        invokeWrapped(callback, q, params);
+    }
+
+    public void invokeWrapped(ClientCallback callback,
+                              QName operationName,
+                              Object... params)
+        throws Exception {
+        BindingOperationInfo op = getEndpoint().getEndpointInfo().getBinding().getOperation(operationName);
+        if (op == null) {
+            throw new UncheckedException(
+                new org.apache.cxf.common.i18n.Message("NO_OPERATION", LOG, operationName));
+        }
+        invoke(callback, op, params);
+    }
+
+
+    public void invoke(ClientCallback callback,
+                       BindingOperationInfo oi,
+                       Object... params) throws Exception {
+        invoke(callback, oi, params, null, null);
+    }
+
+    public void invoke(ClientCallback callback,
+                       BindingOperationInfo oi,
+                       Object[] params,
+                       Map<String, Object> context) throws Exception {
+        invoke(callback, oi, params, context, null);
+    }
+
+    public void invoke(ClientCallback callback,
+                       BindingOperationInfo oi,
+                       Object[] params,
+                       Exchange exchange) throws Exception {
+        invoke(callback, oi, params, null, exchange);
+    }
+
+    public void invoke(ClientCallback callback,
+                       BindingOperationInfo oi,
+                       Object[] params,
+                       Map<String, Object> context,
+                       Exchange exchange) throws Exception {
+        doInvoke(callback, oi, params, context, exchange);
+    }
+
+    public Object[] invoke(BindingOperationInfo oi,
+                           Object[] params,
+                           Map<String, Object> context,
+                           Exchange exchange) throws Exception {
+        return doInvoke(null, oi, params, context, exchange);
+    }
+
+    private Object[] doInvoke(final ClientCallback callback,
+                              BindingOperationInfo oi,
+                              Object[] params,
+                              Map<String, Object> context,
+                              Exchange exchange) throws Exception {
+        Bus origBus = BusFactory.getAndSetThreadDefaultBus(bus);
+        ClassLoaderHolder origLoader = null;
+        Map<String, Object> resContext = null;
+        try {
+            ClassLoader loader = bus.getExtension(ClassLoader.class);
+            if (loader != null) {
+                origLoader = ClassLoaderUtils.setThreadContextClassloader(loader);
+            }
+            if (exchange == null) {
+                exchange = new ExchangeImpl();
+            }
+            exchange.setSynchronous(callback == null);
+            Endpoint endpoint = getEndpoint();
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Invoke, operation info: " + oi + ", params: " + Arrays.toString(params));
+            }
+            Message message = endpoint.getBinding().createMessage();
+
+            // Make sure INVOCATION CONTEXT, REQUEST_CONTEXT and RESPONSE_CONTEXT are present
+            // on message
+            if (context == null) {
+                context = new HashMap<>();
+            }
+            Map<String, Object> reqContext = CastUtils.cast((Map<?, ?>)context.get(REQUEST_CONTEXT));
+            resContext = CastUtils.cast((Map<?, ?>)context.get(RESPONSE_CONTEXT));
+            if (reqContext == null) {
+                reqContext = new HashMap<>(getRequestContext());
+                context.put(REQUEST_CONTEXT, reqContext);
+            }
+            if (resContext == null) {
+                resContext = new ResponseContext(responseContext);
+                context.put(RESPONSE_CONTEXT, resContext);
+            }
+
+            message.put(Message.INVOCATION_CONTEXT, context);
+            setContext(reqContext, message);
+            exchange.putAll(reqContext);
+
+            setParameters(params, message);
+
+            if (null != oi) {
+                exchange.setOneWay(oi.getOutput() == null);
+            }
+
+            exchange.setOutMessage(message);
+            exchange.put(ClientCallback.class, callback);
+
+            setOutMessageProperties(message, oi);
+            setExchangeProperties(exchange, endpoint, oi);
+
+            PhaseInterceptorChain chain = setupInterceptorChain(endpoint);
+            message.setInterceptorChain(chain);
+            if (callback == null) {
+                chain.setFaultObserver(outFaultObserver);
+            } else {
+                // We need to wrap the outFaultObserver if the callback is not null
+                // calling the conduitSelector.complete to make sure the fail over feature works
+                chain.setFaultObserver(new MessageObserver() {
+                    public void onMessage(Message message) {
+                        Exception ex = message.getContent(Exception.class);
+                        if (ex != null) {
+                            completeExchange(message.getExchange());
+                            if (message.getContent(Exception.class) == null) {
+                                // handle the right response
+                                Message inMsg = message.getExchange().getInMessage();
+                                Map<String, Object> ctx = responseContext.get(Thread.currentThread());
+                                List<Object> resList = CastUtils.cast(inMsg.getContent(List.class));
+                                Object[] result = resList == null ? null : resList.toArray();
+                                callback.handleResponse(ctx, result);
+                                return;
+                            }
+                        }
+                        outFaultObserver.onMessage(message);
+                    }
+                });
+            }
+            prepareConduitSelector(message);
+
+            // add additional interceptors and such
+            modifyChain(chain, message, false);
+            try {
+                chain.doIntercept(message);
+            } catch (Fault fault) {
+                enrichFault(fault);
+                throw fault;
+            }
+
+            if (callback != null) {
+                return null;
+            }
+            return processResult(message, exchange, oi, resContext);
+        } finally {
+            //ensure ResponseContext has HTTP RESPONSE CODE
+            if (null != exchange) {
+                Integer responseCode = (Integer)exchange.get(Message.RESPONSE_CODE);
+                resContext.put(MessageContext.HTTP_RESPONSE_CODE, responseCode);
+                resContext.put(org.apache.cxf.message.Message.RESPONSE_CODE, responseCode);
+                setResponseContext(resContext);
+            }
+            if (origLoader != null) {
+                origLoader.reset();
+            }
+            if (origBus != bus) {
+                BusFactory.setThreadDefaultBus(origBus);
+            }
+        }
+    }
+
+    private void completeExchange(Exchange exchange) {
+        getConduitSelector().complete(exchange);
+    }
+
+    /**
+     * TODO This is SOAP specific code and should not be in cxf core
+     * @param fault
+     */
+    private void enrichFault(Fault fault) {
+        if (fault.getCause().getCause() instanceof IOException
+                || fault.getCause() instanceof IOException) {
+            String soap11NS = "http://schemas.xmlsoap.org/soap/envelope/";
+            String soap12NS = "http://www.w3.org/2003/05/soap-envelope";
+            QName faultCode = fault.getFaultCode();
+            //for SoapFault, if it's underlying cause is IOException,
+            //it means something like server is down or can't create
+            //connection, according to soap spec we should set fault as
+            //Server Fault
+            if (faultCode.getNamespaceURI().equals(
+                    soap11NS)
+                    && "Client".equals(faultCode.getLocalPart())) {
+                faultCode = new QName(soap11NS, "Server");
+                fault.setFaultCode(faultCode);
+            }
+            if (faultCode.getNamespaceURI().equals(
+                    soap12NS)
+                    && "Sender".equals(faultCode.getLocalPart())) {
+                faultCode = new QName(soap12NS, "Receiver");
+                fault.setFaultCode(faultCode);
+            }
+        }
+    }
+
+    protected Object[] processResult(Message message,
+                                   Exchange exchange,
+                                   BindingOperationInfo oi,
+                                   Map<String, Object> resContext) throws Exception {
+        Exception ex = null;
+        // Check to see if there is a Fault from the outgoing chain if it's an out Message
+        if (!message.get(Message.INBOUND_MESSAGE).equals(Boolean.TRUE)) {
+            ex = message.getContent(Exception.class);
+        }
+        boolean mepCompleteCalled = false;
+        if (ex != null) {
+            completeExchange(exchange);
+            mepCompleteCalled = true;
+            if (message.getContent(Exception.class) != null) {
+                throw ex;
+            }
+        }
+        ex = message.getExchange().get(Exception.class);
+        if (ex != null) {
+            if (!mepCompleteCalled) {
+                completeExchange(exchange);
+            }
+            throw ex;
+        }
+
+        //REVISIT
+        // - use a protocol neutral no-content marker instead of 202?
+        // - move the decoupled destination property name into api
+        Integer responseCode = (Integer)exchange.get(Message.RESPONSE_CODE);
+        if (null != responseCode && 202 == responseCode) {
+            Endpoint ep = exchange.getEndpoint();
+            if (null != ep && null != ep.getEndpointInfo() && null == ep.getEndpointInfo().
+                getProperty("org.apache.cxf.ws.addressing.MAPAggregator.decoupledDestination")) {
+                return null;
+            }
+        }
+
+        // Wait for a response if we need to
+        if (oi != null && !oi.getOperationInfo().isOneWay()) {
+            waitResponse(exchange);
+        }
+
+        // leave the input stream open for the caller
+        Boolean keepConduitAlive = (Boolean)exchange.get(Client.KEEP_CONDUIT_ALIVE);
+        if (keepConduitAlive == null || !keepConduitAlive) {
+            completeExchange(exchange);
+        }
+
+        // Grab the response objects if there are any
+        List<Object> resList = null;
+        Message inMsg = exchange.getInMessage();
+        if (inMsg != null) {
+            if (null != resContext) {
+                resContext.putAll(inMsg);
+                // remove the recursive reference if present
+                resContext.remove(Message.INVOCATION_CONTEXT);
+                setResponseContext(resContext);
+            }
+            resList = CastUtils.cast(inMsg.getContent(List.class));
+        }
+
+        // check for an incoming fault
+        ex = getException(exchange);
+
+        if (ex != null) {
+            throw ex;
+        }
+
+        if (resList == null   
+            && oi != null && !oi.getOperationInfo().isOneWay()) {
+            
+            BindingOperationInfo boi = oi;
+            if (boi.isUnwrapped()) {
+                boi = boi.getWrappedOperation();
+            }
+            if (!boi.getOutput().getMessageParts().isEmpty()) {
+                //we were supposed to get some output, but didn't.
+                throw new IllegalEmptyResponseException("Response message did not contain proper response data."
+                    + " Expected: " + boi.getOutput().getMessageParts().get(0).getConcreteName());
+            }
+        }
+        if (resList != null) {
+            return resList.toArray();
+        }
+
+        return null;
+    }
+    protected Exception getException(Exchange exchange) {
+        if (exchange.getInFaultMessage() != null) {
+            return exchange.getInFaultMessage().getContent(Exception.class);
+        } else if (exchange.getOutFaultMessage() != null) {
+            return exchange.getOutFaultMessage().getContent(Exception.class);
+        } else if (exchange.getInMessage() != null) {
+            return exchange.getInMessage().getContent(Exception.class);
+        }
+        return null;
+    }
+
+    protected void setContext(Map<String, Object> ctx, Message message) {
+        if (ctx != null) {
+            message.putAll(ctx);
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("set requestContext to message be" + ctx);
+            }
+        }
+    }
+
+    protected void waitResponse(Exchange exchange) throws IOException {
+        synchronized (exchange) {
+            long remaining = synchronousTimeout;
+            Long o = PropertyUtils.getLong(exchange.getOutMessage(), SYNC_TIMEOUT);
+            if (o != null) {
+                remaining = o;
+            }
+            while (!Boolean.TRUE.equals(exchange.get(FINISHED)) && remaining > 0) {
+                long start = System.currentTimeMillis();
+                try {
+                    exchange.wait(remaining);
+                } catch (InterruptedException ex) {
+                    // ignore
+                }
+                long end = System.currentTimeMillis();
+                remaining -= (int)(end - start);
+            }
+            if (!Boolean.TRUE.equals(exchange.get(FINISHED))) {
+                LogUtils.log(LOG, Level.WARNING, "RESPONSE_TIMEOUT",
+                    exchange.getBindingOperationInfo().getOperationInfo().getName().toString());
+                String msg = new org.apache.cxf.common.i18n.Message("RESPONSE_TIMEOUT", LOG, exchange
+                    .getBindingOperationInfo().getOperationInfo().getName().toString()).toString();
+                throw new IOException(msg);
+            }
+        }
+    }
+
+    protected void setParameters(Object[] params, Message message) {
+        MessageContentsList contents = new MessageContentsList(params);
+        message.setContent(List.class, contents);
+    }
+
+    public void onMessage(Message message) {
+        if (bus == null) {
+            throw new IllegalStateException("Message received on a Client that has been closed or destroyed.");
+        }
+        Endpoint endpoint = message.getExchange().getEndpoint();
+        if (endpoint == null) {
+            // in this case correlation will occur outside the transport,
+            // however there's a possibility that the endpoint may have been
+            // rebased in the meantime, so that the response will be mediated
+            // via a set of in interceptors provided by a *different* endpoint
+            //
+            endpoint = getConduitSelector().getEndpoint();
+            message.getExchange().put(Endpoint.class, endpoint);
+        }
+        message = endpoint.getBinding().createMessage(message);
+        message.getExchange().setInMessage(message);
+        message.put(Message.REQUESTOR_ROLE, Boolean.TRUE);
+        message.put(Message.INBOUND_MESSAGE, Boolean.TRUE);
+        PhaseManager pm = bus.getExtension(PhaseManager.class);
+
+        List<Interceptor<? extends Message>> i1 = bus.getInInterceptors();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Interceptors contributed by bus: " + i1);
+        }
+        List<Interceptor<? extends Message>> i2 = getInInterceptors();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Interceptors contributed by client: " + i2);
+        }
+        List<Interceptor<? extends Message>> i3 = endpoint.getInInterceptors();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Interceptors contributed by endpoint: " + i3);
+        }
+        List<Interceptor<? extends Message>> i4 = endpoint.getBinding().getInInterceptors();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Interceptors contributed by binding: " + i4);
+        }
+
+        PhaseInterceptorChain chain;
+        if (endpoint.getService().getDataBinding() instanceof InterceptorProvider) {
+            InterceptorProvider p = (InterceptorProvider)endpoint.getService().getDataBinding();
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Interceptors contributed by databinding: " + p.getInInterceptors());
+            }
+            chain = inboundChainCache.get(pm.getInPhases(), i1, i2, i3, i4,
+                                          p.getInInterceptors());
+        } else {
+            chain = inboundChainCache.get(pm.getInPhases(), i1, i2, i3, i4);
+        }
+        message.setInterceptorChain(chain);
+
+        chain.setFaultObserver(outFaultObserver);
+        modifyChain(chain, message, true);
+        modifyChain(chain, message.getExchange().getOutMessage(), true);
+
+        Bus origBus = BusFactory.getAndSetThreadDefaultBus(bus);
+        // execute chain
+        ClientCallback callback = message.getExchange().get(ClientCallback.class);
+        try {
+            if (callback != null) {
+                if (callback.isCancelled()) {
+                    completeExchange(message.getExchange());
+                    return;
+                }
+                callback.start(message);
+            }
+
+            String startingAfterInterceptorID = (String) message.get(
+                InterceptorChain.STARTING_AFTER_INTERCEPTOR_ID);
+            String startingInterceptorID = (String) message.get(
+                InterceptorChain.STARTING_AT_INTERCEPTOR_ID);
+            if (startingAfterInterceptorID != null) {
+                chain.doInterceptStartingAfter(message, startingAfterInterceptorID);
+            } else if (startingInterceptorID != null) {
+                chain.doInterceptStartingAt(message, startingInterceptorID);
+            } else if (message.getContent(Exception.class) != null) {
+                outFaultObserver.onMessage(message);
+            } else {
+                callback = message.getExchange().get(ClientCallback.class);
+
+                if (callback != null && !isPartialResponse(message)) {
+                    try {
+                        chain.doIntercept(message);
+                    } catch (Throwable error) {
+                        //so that asyn callback handler get chance to
+                        //handle non-runtime exceptions
+                        message.getExchange().setInMessage(message);
+                        Map<String, Object> resCtx = CastUtils
+                                .cast((Map<?, ?>) message.getExchange()
+                                        .getOutMessage().get(
+                                                Message.INVOCATION_CONTEXT));
+                        resCtx = CastUtils.cast((Map<?, ?>) resCtx
+                                .get(RESPONSE_CONTEXT));
+                        if (resCtx != null) {
+                            setResponseContext(resCtx);
+                        }
+                        // remove callback so that it won't be invoked twice
+                        callback = message.getExchange().remove(ClientCallback.class);
+                        if (callback != null) {
+                            callback.handleException(resCtx, error);
+                        }
+                    }
+                } else {
+                    chain.doIntercept(message);
+                }
+
+            }
+
+            callback = message.getExchange().get(ClientCallback.class);
+            if (callback == null || isPartialResponse(message)) {
+                return;
+            }
+
+            // remove callback so that it won't be invoked twice
+            callback = message.getExchange().remove(ClientCallback.class);
+            if (callback != null) {
+                message.getExchange().setInMessage(message);
+                Map<String, Object> resCtx = CastUtils.cast((Map<?, ?>)message
+                                                                .getExchange()
+                                                                .getOutMessage()
+                                                                .get(Message.INVOCATION_CONTEXT));
+                resCtx = CastUtils.cast((Map<?, ?>)resCtx.get(RESPONSE_CONTEXT));
+                if (resCtx != null && responseContext != null) {
+                    setResponseContext(resCtx);
+                }
+                try {
+                    Object[] obj = processResult(message, message.getExchange(),
+                                                 null, resCtx);
+
+                    callback.handleResponse(resCtx, obj);
+                } catch (Throwable ex) {
+                    callback.handleException(resCtx, ex);
+                }
+            }
+        } finally {
+            if (origBus != bus) {
+                BusFactory.setThreadDefaultBus(origBus);
+            }
+            synchronized (message.getExchange()) {
+                if (!isPartialResponse(message)
+                    || message.getContent(Exception.class) != null) {
+                    message.getExchange().put(FINISHED, Boolean.TRUE);
+                    message.getExchange().setInMessage(message);
+                    message.getExchange().notifyAll();
+                }
+            }
+        }
+    }
+
+    public Conduit getConduit() {
+        Message message = new MessageImpl();
+        Exchange exchange = new ExchangeImpl();
+        message.setExchange(exchange);
+        message.putAll(getRequestContext());
+        setExchangeProperties(exchange, getEndpoint(), null);
+        return getConduitSelector().selectConduit(message);
+    }
+
+    protected void prepareConduitSelector(Message message) {
+        getConduitSelector().prepare(message);
+        message.getExchange().put(ConduitSelector.class, getConduitSelector());
+    }
+
+    protected void setOutMessageProperties(Message message, BindingOperationInfo boi) {
+        message.put(Message.REQUESTOR_ROLE, Boolean.TRUE);
+        message.put(Message.INBOUND_MESSAGE, Boolean.FALSE);
+        if (null != boi) {
+            message.put(BindingMessageInfo.class, boi.getInput());
+            message.put(MessageInfo.class, boi.getOperationInfo().getInput());
+        }
+    }
+
+    protected void setExchangeProperties(Exchange exchange,
+                                         Endpoint endpoint,
+                                         BindingOperationInfo boi) {
+        if (endpoint != null) {
+            exchange.put(Endpoint.class, endpoint);
+            exchange.put(Service.class, endpoint.getService());
+            exchange.put(Binding.class, endpoint.getBinding());
+        }
+        if (boi != null) {
+            exchange.put(BindingOperationInfo.class, boi);
+        }
+
+        if (exchange.isSynchronous() || executor == null) {
+            exchange.put(MessageObserver.class, this);
+        } else {
+            exchange.put(Executor.class, executor);
+            exchange.put(MessageObserver.class, new MessageObserver() {
+                public void onMessage(final Message message) {
+                    if (!message.getExchange()
+                        .containsKey(Executor.class.getName() + ".USING_SPECIFIED")) {
+
+                        executor.execute(new Runnable() {
+                            public void run() {
+                                ClientImpl.this.onMessage(message);
+                            }
+                        });
+                    } else {
+                        ClientImpl.this.onMessage(message);
+                    }
+                }
+            });
+        }
+        exchange.put(Retryable.class, this);
+        exchange.put(Client.class, this);
+        exchange.put(Bus.class, bus);
+
+        if (endpoint != null) {
+            EndpointInfo endpointInfo = endpoint.getEndpointInfo();
+            if (boi != null) {
+                exchange.put(Message.WSDL_OPERATION, boi.getName());
+            }
+
+            QName serviceQName = endpointInfo.getService().getName();
+            exchange.put(Message.WSDL_SERVICE, serviceQName);
+
+            QName interfaceQName = endpointInfo.getService().getInterface().getName();
+            exchange.put(Message.WSDL_INTERFACE, interfaceQName);
+
+            QName portQName = endpointInfo.getName();
+            exchange.put(Message.WSDL_PORT, portQName);
+            URI wsdlDescription = endpointInfo.getProperty("URI", URI.class);
+            if (wsdlDescription == null) {
+                String address = endpointInfo.getAddress();
+                try {
+                    wsdlDescription = new URI(address + "?wsdl");
+                } catch (URISyntaxException e) {
+                    // do nothing
+                }
+                endpointInfo.setProperty("URI", wsdlDescription);
+            }
+            exchange.put(Message.WSDL_DESCRIPTION, wsdlDescription);
+        }
+    }
+
+    protected PhaseInterceptorChain setupInterceptorChain(Endpoint endpoint) {
+
+        PhaseManager pm = bus.getExtension(PhaseManager.class);
+
+        List<Interceptor<? extends Message>> i1 = bus.getOutInterceptors();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Interceptors contributed by bus: " + i1);
+        }
+        List<Interceptor<? extends Message>> i2 = getOutInterceptors();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Interceptors contributed by client: " + i2);
+        }
+        List<Interceptor<? extends Message>> i3 = endpoint.getOutInterceptors();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Interceptors contributed by endpoint: " + i3);
+        }
+        List<Interceptor<? extends Message>> i4 = endpoint.getBinding().getOutInterceptors();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Interceptors contributed by binding: " + i4);
+        }
+        List<Interceptor<? extends Message>> i5 = null;
+        if (endpoint.getService().getDataBinding() instanceof InterceptorProvider) {
+            i5 = ((InterceptorProvider)endpoint.getService().getDataBinding()).getOutInterceptors();
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Interceptors contributed by databinding: " + i5);
+            }
+        }
+        if (i5 != null) {
+            return outboundChainCache.get(pm.getOutPhases(), i1, i2, i3, i4, i5);
+        }
+        return outboundChainCache.get(pm.getOutPhases(), i1, i2, i3, i4);
+    }
+
+    protected void modifyChain(InterceptorChain chain, Message ctx, boolean in) {
+        if (ctx == null) {
+            return;
+        }
+        Collection<InterceptorProvider> providers
+            = CastUtils.cast((Collection<?>)ctx.get(Message.INTERCEPTOR_PROVIDERS));
+        if (providers != null) {
+            for (InterceptorProvider p : providers) {
+                if (in) {
+                    chain.add(p.getInInterceptors());
+                } else {
+                    chain.add(p.getOutInterceptors());
+                }
+            }
+        }
+        String key = in ? Message.IN_INTERCEPTORS : Message.OUT_INTERCEPTORS;
+        Collection<Interceptor<? extends Message>> is
+            = CastUtils.cast((Collection<?>)ctx.get(key));
+        if (is != null) {
+            chain.add(is);
+        }
+    }
+
+    protected void setEndpoint(Endpoint e) {
+        getConduitSelector().setEndpoint(e);
+    }
+
+    public int getSynchronousTimeout() {
+        return synchronousTimeout;
+    }
+
+    public void setSynchronousTimeout(int synchronousTimeout) {
+        this.synchronousTimeout = synchronousTimeout;
+    }
+
+    public final ConduitSelector getConduitSelector() {
+        return getConduitSelector(null);
+    }
+
+    protected final ConduitSelector getConduitSelector(
+        ConduitSelector override
+    ) {
+        if (null == conduitSelector) {
+            setConduitSelector(override);
+        }
+        return conduitSelector;
+    }
+
+    public final synchronized void setConduitSelector(ConduitSelector selector) {
+        conduitSelector = selector == null ? new UpfrontConduitSelector() : selector;
+    }
+
+    private boolean isPartialResponse(Message in) {
+        return Boolean.TRUE.equals(in.get(Message.PARTIAL_RESPONSE_MESSAGE));
+    }
+
+    @Override
+    public void close() throws Exception {
+        destroy();
+    }
+
+
+    public class EchoContext extends ConcurrentHashMap<String, Object> {
+        private static final long serialVersionUID = 1L;
+        public EchoContext(Map<String, Object> sharedMap) {
+            super(8, 0.75f, 4);
+            putAll(sharedMap);
+        }
+
+        public void reload() {
+            super.clear();
+            super.putAll(requestContext.get(latestContextThread));
+        }
+        
+        @Override
+        public void clear() {
+            super.clear();
+            try {
+                for (Map.Entry<Thread, EchoContext> ent : requestContext.entrySet()) {
+                    if (ent.getValue() == this) {
+                        requestContext.remove(ent.getKey());
+                        return;
+                    }
+                }
+            } catch (Throwable t) {
+                //ignore
+            }
+        }
+    }
+
+    /**
+     * Class to handle the response contexts.   The clear is overloaded to remove
+     * this context from the threadLocal caches in the ClientImpl
+     */
+    static class ResponseContext implements Map<String, Object>, Serializable {
+        private static final long serialVersionUID = 2L;
+        final Map<String, Object> wrapped;
+        final Map<Thread, ResponseContext> responseContext;
+        
+        ResponseContext(Map<String, Object> origMap, Map<Thread, ResponseContext> rc) {
+            wrapped = origMap;
+            responseContext = rc;
+        }
+
+        ResponseContext(Map<Thread, ResponseContext> rc) {
+            wrapped = new HashMap<>();
+            responseContext = rc;
+        }
+
+        @Override
+        public void clear() {
+            wrapped.clear();
+            try {
+                for (Map.Entry<Thread, ResponseContext> ent : responseContext.entrySet()) {
+                    if (ent.getValue() == this) {
+                        responseContext.remove(ent.getKey());
+                        return;
+                    }
+                }
+            } catch (Throwable t) {
+                //ignore
+            }
+        }
+
+        @Override
+        public int size() {
+            return wrapped.size();
+        }
+        @Override
+        public boolean isEmpty() {
+            return wrapped.isEmpty();
+        }
+        @Override
+        public boolean containsKey(Object key) {
+            return wrapped.containsKey(key);
+        }
+        @Override
+        public boolean containsValue(Object value) {
+            return wrapped.containsKey(value);
+        }
+        @Override
+        public Object get(Object key) {
+            return wrapped.get(key);
+        }
+        @Override
+        public Object put(String key, Object value) {
+            return wrapped.put(key, value);
+        }
+        @Override
+        public Object remove(Object key) {
+            return wrapped.remove(key);
+        }
+        @Override
+        public void putAll(Map<? extends String, ? extends Object> m) {
+            wrapped.putAll(m);
+        }
+        @Override
+        public Set<String> keySet() {
+            return wrapped.keySet();
+        }
+        @Override
+        public Collection<Object> values() {
+            return wrapped.values();
+        }
+        @Override
+        public Set<Entry<String, Object>> entrySet() {
+            return wrapped.entrySet();
+        }
+    }
+
+    public void setExecutor(Executor executor) {
+        if (!SynchronousExecutor.isA(executor)) {
+            this.executor = executor;
+        }
+    }
+
+    
+    public class IllegalEmptyResponseException extends IllegalStateException {
+        private static final long serialVersionUID = 1L;
+
+        public IllegalEmptyResponseException() {
+            super();
+        }
+
+        public IllegalEmptyResponseException(String message) {
+            super(message);
+        }
+
+        public IllegalEmptyResponseException(String message, Throwable cause) {
+            super(message, cause);
+        }
+
+        public IllegalEmptyResponseException(Throwable cause) {
+            super(cause);
+        }
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/endpoint/EndpointImpl.java b/transform/src/patch/java/org/apache/cxf/endpoint/EndpointImpl.java
new file mode 100644
index 0000000..340211b
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/endpoint/EndpointImpl.java
@@ -0,0 +1,220 @@
+/**
+ * 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.cxf.endpoint;
+
+import java.io.Closeable;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusException;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.binding.Binding;
+import org.apache.cxf.binding.BindingFactory;
+import org.apache.cxf.binding.BindingFactoryManager;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.configuration.Configurable;
+import org.apache.cxf.feature.Feature;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.AbstractAttributedInterceptorProvider;
+import org.apache.cxf.interceptor.ClientFaultConverter;
+import org.apache.cxf.interceptor.InFaultChainInitiatorObserver;
+import org.apache.cxf.interceptor.MessageSenderInterceptor;
+import org.apache.cxf.interceptor.OutFaultChainInitiatorObserver;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.model.BindingInfo;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.MessageObserver;
+
+public class EndpointImpl extends AbstractAttributedInterceptorProvider implements Endpoint, Configurable {
+
+    private static final long serialVersionUID = -7660560719050162091L;
+    private static final Logger LOG = LogUtils.getL7dLogger(EndpointImpl.class);
+    private static final ResourceBundle BUNDLE = LOG.getResourceBundle();
+
+    private Service service;
+    private Binding binding;
+    private EndpointInfo endpointInfo;
+    private Executor executor;
+    private Bus bus;
+    private MessageObserver inFaultObserver;
+    private MessageObserver outFaultObserver;
+    private List<Feature> activeFeatures;
+    private List<Closeable> cleanupHooks;
+
+    public EndpointImpl(Bus bus, Service s, QName endpointName) throws EndpointException {
+        this(bus, s, s.getEndpointInfo(endpointName));
+    }
+
+    public EndpointImpl(Bus bus, Service s, EndpointInfo ei) throws EndpointException {
+        if (ei == null) {
+            throw new NullPointerException("EndpointInfo can not be null!");
+        }
+
+        if (bus == null) {
+            this.bus = BusFactory.getThreadDefaultBus();
+        } else {
+            this.bus = bus;
+        }
+        service = s;
+        endpointInfo = ei;
+
+        createBinding(endpointInfo.getBinding());
+
+        inFaultObserver = new InFaultChainInitiatorObserver(bus);
+        outFaultObserver = new OutFaultChainInitiatorObserver(bus);
+
+        getInFaultInterceptors().add(new ClientFaultConverter());
+        getOutInterceptors().add(new MessageSenderInterceptor());
+        getOutFaultInterceptors().add(new MessageSenderInterceptor());
+    }
+
+    public String getBeanName() {
+        return endpointInfo.getName().toString() + ".endpoint";
+    }
+
+
+    public EndpointInfo getEndpointInfo() {
+        return endpointInfo;
+    }
+
+    public Service getService() {
+        return service;
+    }
+
+    public Binding getBinding() {
+        return binding;
+    }
+
+    public Executor getExecutor() {
+        return executor == null ? service.getExecutor() : executor;
+    }
+
+    public void setExecutor(Executor e) {
+        executor = e;
+    }
+
+    public Bus getBus() {
+        return bus;
+    }
+
+    public void setBus(Bus bus) {
+        this.bus = bus;
+    }
+
+    final void createBinding(BindingInfo bi) throws EndpointException {
+        if (null != bi) {
+            String namespace = bi.getBindingId();
+            try {
+                final BindingFactory bf = bus.getExtension(BindingFactoryManager.class).getBindingFactory(namespace);
+                if (null == bf) {
+                    Message msg = new Message("NO_BINDING_FACTORY", BUNDLE, namespace);
+                    throw new EndpointException(msg);
+                }
+                binding = bf.createBinding(bi);
+            } catch (BusException ex) {
+                throw new EndpointException(ex);
+            }
+        }
+    }
+
+
+    public MessageObserver getInFaultObserver() {
+        return inFaultObserver;
+    }
+
+    public MessageObserver getOutFaultObserver() {
+        return outFaultObserver;
+    }
+
+    public void setInFaultObserver(MessageObserver observer) {
+        inFaultObserver = observer;
+    }
+
+    public void setOutFaultObserver(MessageObserver observer) {
+        outFaultObserver = observer;
+
+    }
+
+    /**
+     * Utility method to make it easy to set properties from Spring.
+     *
+     * @param properties
+     */
+    public void setProperties(Map<String, Object> properties) {
+        this.putAll(properties);
+    }
+
+    /**
+     * @return the list of features <b>already</b> activated for this endpoint.
+     */
+    public List<Feature> getActiveFeatures() {
+        return activeFeatures;
+    }
+
+    /**
+     * @param features the list of features <b>already</b> activated for this endpoint.
+     */
+    public void initializeActiveFeatures(List<? extends Feature> features) {
+        activeFeatures = CastUtils.cast(features);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof EndpointImpl)) {
+            return false;
+        }
+
+        return super.equals(obj);
+    }
+
+    /**
+     * Returns the hashCode based on the EndpointInfo so that this object
+     * can be used as a map key.
+     */
+    @Override
+    public int hashCode() {
+        return endpointInfo.hashCode();
+    }
+
+    public synchronized void addCleanupHook(Closeable c) {
+        if (cleanupHooks == null) {
+            cleanupHooks = new CopyOnWriteArrayList<>();
+        }
+        cleanupHooks.add(c);
+    }
+    public List<Closeable> getCleanupHooks() {
+        if (cleanupHooks == null) {
+            return Collections.emptyList();
+        }
+        return cleanupHooks;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/endpoint/ServerImpl.java b/transform/src/patch/java/org/apache/cxf/endpoint/ServerImpl.java
new file mode 100644
index 0000000..c417cb6
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/endpoint/ServerImpl.java
@@ -0,0 +1,221 @@
+/**
+ * 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.cxf.endpoint;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.management.JMException;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusException;
+import org.apache.cxf.binding.BindingFactory;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.logging.RegexLoggingFilter;
+import org.apache.cxf.management.InstrumentationManager;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.transport.DestinationFactory;
+import org.apache.cxf.transport.DestinationFactoryManager;
+import org.apache.cxf.transport.MessageObserver;
+import org.apache.cxf.transport.MultipleEndpointObserver;
+
+public class ServerImpl implements Server {
+    private static final Logger LOG = LogUtils.getL7dLogger(ServerImpl.class);
+
+    protected final Endpoint endpoint;
+    protected final Bus bus;
+    protected final BindingFactory bindingFactory;
+
+    private Destination destination;
+    private ServerRegistry serverRegistry;
+    private ServerLifeCycleManager slcMgr;
+    private InstrumentationManager iMgr;
+    private ManagedEndpoint mep;
+    private boolean stopped = true;
+    private boolean destroyDest = true;
+
+    public ServerImpl(Bus bus,
+                      Endpoint endpoint,
+                      DestinationFactory destinationFactory,
+                      BindingFactory bindingFactory) throws BusException, IOException {
+        this.endpoint = endpoint;
+        this.bus = bus;
+        this.bindingFactory = bindingFactory;
+
+        initDestination(destinationFactory);
+    }
+
+    private void initDestination(DestinationFactory destinationFactory) throws BusException, IOException {
+        EndpointInfo ei = endpoint.getEndpointInfo();
+
+        //Treat local transport as a special case, transports loaded by transportId can be replaced
+        //by local transport when the publishing address is a local transport protocol.
+        //Of course its not an ideal situation here to use a hard-coded prefix. To be refactored.
+        if (destinationFactory == null) {
+            if (ei.getAddress() != null && ei.getAddress().indexOf("local://") != -1) {
+                destinationFactory = bus.getExtension(DestinationFactoryManager.class)
+                    .getDestinationFactoryForUri(ei.getAddress());
+            }
+
+            if (destinationFactory == null) {
+                destinationFactory = bus.getExtension(DestinationFactoryManager.class)
+                    .getDestinationFactory(ei.getTransportId());
+            }
+        }
+
+        destination = destinationFactory.getDestination(ei, bus);
+        String wantFilter = ei.getAddress();
+        
+        if (wantFilter != null && wantFilter.startsWith("jms")) {
+            RegexLoggingFilter filter = new RegexLoggingFilter();
+            filter.setPattern("jms(.*?)password=+([^ ]+)");
+            filter.setGroup(2);
+            wantFilter = filter.filter(wantFilter).toString();
+        }
+        LOG.info("Setting the server's publish address to be " + wantFilter);
+        serverRegistry = bus.getExtension(ServerRegistry.class);
+
+        mep = new ManagedEndpoint(bus, endpoint, this);
+
+        slcMgr = bus.getExtension(ServerLifeCycleManager.class);
+        if (slcMgr != null) {
+            slcMgr.registerListener(mep);
+        }
+
+        iMgr = bus.getExtension(InstrumentationManager.class);
+        if (iMgr != null) {
+            try {
+                iMgr.register(mep);
+            } catch (JMException jmex) {
+                LOG.log(Level.WARNING, "Registering ManagedEndpoint failed.", jmex);
+            }
+        }
+    }
+
+    public Destination getDestination() {
+        return destination;
+    }
+
+    public void setDestination(Destination destination) {
+        this.destination = destination;
+    }
+
+    public void start() {
+        if (!stopped) {
+            return;
+        }
+        LOG.fine("Server is starting.");
+        
+        try {
+            bindingFactory.addListener(destination, endpoint);
+        } catch (RuntimeException e) {
+            if (e.getMessage().contains("endpoint already registered on address")) {
+                //this destination is used by another endpoint with same endpoint address
+                //so shouldn't be destroyed by this server
+                this.destroyDest = false;
+            }
+            throw e;
+        }
+
+        // register the active server to run
+        if (null != serverRegistry) {
+            LOG.fine("register the server to serverRegistry ");
+            serverRegistry.register(this);
+        }
+        if (slcMgr == null) {
+            slcMgr = bus.getExtension(ServerLifeCycleManager.class);
+            if (slcMgr != null && mep != null) {
+                slcMgr.registerListener(mep);
+            }
+        }
+        if (slcMgr != null) {
+            slcMgr.startServer(this);
+        }
+        stopped = false;
+    }
+
+    public boolean isStopped() {
+        return stopped;
+    }
+    public boolean isStarted() {
+        return !stopped;
+    }
+
+    public void stop() {
+        if (stopped) {
+            return;
+        }
+
+        LOG.fine("Server is stopping.");
+
+        for (Closeable c : endpoint.getCleanupHooks()) {
+            try {
+                c.close();
+            } catch (IOException e) {
+                //ignore
+            }
+        }
+        if (slcMgr != null) {
+            slcMgr.stopServer(this);
+        }
+
+        MessageObserver mo = getDestination().getMessageObserver();
+        if (mo instanceof MultipleEndpointObserver) {
+            ((MultipleEndpointObserver)mo).getEndpoints().remove(endpoint);
+            if (((MultipleEndpointObserver)mo).getEndpoints().isEmpty()) {
+                getDestination().setMessageObserver(null);
+            }
+        } else {
+            getDestination().setMessageObserver(null);
+        }
+        stopped = true;
+    }
+
+    public void destroy() {
+        stop();
+        if (this.destroyDest) {
+            //we should shutdown the destination here
+            getDestination().shutdown();
+        }
+
+        if (null != serverRegistry) {
+            LOG.fine("unregister the server to serverRegistry ");
+            serverRegistry.unregister(this);
+        }
+
+        if (iMgr != null) {
+            try {
+                iMgr.unregister(mep);
+            } catch (JMException jmex) {
+                LOG.log(Level.WARNING, "Unregistering ManagedEndpoint failed.", jmex);
+            }
+            iMgr = null;
+        }
+
+    }
+
+    public Endpoint getEndpoint() {
+        return endpoint;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/feature/FastInfosetFeature.java b/transform/src/patch/java/org/apache/cxf/feature/FastInfosetFeature.java
new file mode 100644
index 0000000..daa4bd3
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/feature/FastInfosetFeature.java
@@ -0,0 +1,110 @@
+/**
+ * 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.cxf.feature;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.interceptor.FIStaxInInterceptor;
+import org.apache.cxf.interceptor.FIStaxOutInterceptor;
+import org.apache.cxf.interceptor.InterceptorProvider;
+
+
+/**
+ * <pre>
+ * <![CDATA[
+    <jaxws:endpoint ...>
+      <jaxws:features>
+       <bean class="org.apache.cxf.feature.FastInfosetFeature"/>
+      </jaxws:features>
+    </jaxws:endpoint>
+  ]]>
+  </pre>
+ */
+@NoJSR250Annotations
+public class FastInfosetFeature extends DelegatingFeature<FastInfosetFeature.Portable> {
+    public FastInfosetFeature() {
+        super(new Portable());
+    }
+
+    public void setForce(boolean b) {
+        delegate.setForce(b);
+    }
+
+    public boolean getForce() {
+        return delegate.getForce();
+    }
+
+    public static class Portable implements AbstractPortableFeature {
+        boolean force;
+        private Integer serializerAttributeValueMapMemoryLimit;
+        private Integer serializerMinAttributeValueSize;
+        private Integer serializerMaxAttributeValueSize;
+        private Integer serializerCharacterContentChunkMapMemoryLimit;
+        private Integer serializerMinCharacterContentChunkSize;
+        private Integer serializerMaxCharacterContentChunkSize;
+
+        @Override
+        public void doInitializeProvider(InterceptorProvider provider, Bus bus) {
+
+            FIStaxInInterceptor in = new FIStaxInInterceptor();
+
+            FIStaxOutInterceptor out = new FIStaxOutInterceptor(force);
+            if (serializerAttributeValueMapMemoryLimit != null && serializerAttributeValueMapMemoryLimit > 0) {
+                out.setSerializerAttributeValueMapMemoryLimit(serializerAttributeValueMapMemoryLimit);
+            }
+            if (serializerMinAttributeValueSize != null && serializerMinAttributeValueSize > 0) {
+                out.setSerializerMinAttributeValueSize(serializerMinAttributeValueSize);
+            }
+            if (serializerMaxAttributeValueSize != null && serializerMaxAttributeValueSize > 0) {
+                out.setSerializerMaxAttributeValueSize(serializerMaxAttributeValueSize);
+            }
+            if (serializerCharacterContentChunkMapMemoryLimit != null
+                    && serializerCharacterContentChunkMapMemoryLimit > 0) {
+                out.setSerializerCharacterContentChunkMapMemoryLimit(
+                        serializerCharacterContentChunkMapMemoryLimit);
+            }
+            if (serializerMinCharacterContentChunkSize != null && serializerMinCharacterContentChunkSize > 0) {
+                out.setSerializerMinCharacterContentChunkSize(serializerMinCharacterContentChunkSize);
+            }
+            if (serializerMaxCharacterContentChunkSize != null && serializerMaxCharacterContentChunkSize > 0) {
+                out.setSerializerMaxCharacterContentChunkSize(serializerMaxCharacterContentChunkSize);
+            }
+
+            provider.getInInterceptors().add(in);
+            provider.getInFaultInterceptors().add(in);
+            provider.getOutInterceptors().add(out);
+            provider.getOutFaultInterceptors().add(out);
+        }
+
+        /**
+         * Set if FastInfoset is always used without negotiation
+         * @param b
+         */
+        public void setForce(boolean b) {
+            force = b;
+        }
+
+        /**
+         * Retrieve the value set with {@link #setForce(boolean)}.
+         */
+        public boolean getForce() {
+            return force;
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/feature/WrappedFeature.java b/transform/src/patch/java/org/apache/cxf/feature/WrappedFeature.java
new file mode 100644
index 0000000..2236a38
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/feature/WrappedFeature.java
@@ -0,0 +1,61 @@
+/**
+ * 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.cxf.feature;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.interceptor.InterceptorProvider;
+
+/**
+ * A Feature is something that is able to customize a Server, Client, or Bus, typically
+ * adding capabilities. For instance, there may be a LoggingFeature which configures
+ * one of the above to log each of their messages.
+ * <p>
+ * By default the initialize methods all delegate to initializeProvider(InterceptorProvider).
+ * If you're simply adding interceptors to a Server, Client, or Bus, this allows you to add
+ * them easily.
+ */
+public class WrappedFeature extends AbstractFeature {
+    final Feature wrapped;
+    public WrappedFeature(Feature f) {
+        wrapped = f;
+    }
+
+    @Override
+    public void initialize(Server server, Bus bus) {
+        wrapped.initialize(server, bus);
+    }
+
+    @Override
+    public void initialize(Client client, Bus bus) {
+        wrapped.initialize(client, bus);
+    }
+
+    @Override
+    public void initialize(InterceptorProvider interceptorProvider, Bus bus) {
+        wrapped.initialize(interceptorProvider, bus);
+    }
+
+    @Override
+    public void initialize(Bus bus) {
+        wrapped.initialize(bus);
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/feature/transform/XSLTOutInterceptor.java b/transform/src/patch/java/org/apache/cxf/feature/transform/XSLTOutInterceptor.java
new file mode 100644
index 0000000..53605cc
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/feature/transform/XSLTOutInterceptor.java
@@ -0,0 +1,210 @@
+/**
+ * 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.cxf.feature.transform;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.logging.Logger;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Templates;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.interceptor.StaxOutInterceptor;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.io.CachedOutputStreamCallback;
+import org.apache.cxf.io.CachedWriter;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.staxutils.DelegatingXMLStreamWriter;
+import org.apache.cxf.staxutils.StaxUtils;
+
+/** Class provides XSLT transformation of outgoing message.
+ * Actually it breaks streaming (can be fixed in further versions when XSLT engine supports XML stream)
+ */
+public class XSLTOutInterceptor extends AbstractXSLTInterceptor {
+    private static final Logger LOG = LogUtils.getL7dLogger(XSLTOutInterceptor.class);
+
+    public XSLTOutInterceptor(String xsltPath) {
+        super(Phase.PRE_STREAM, StaxOutInterceptor.class, null, xsltPath);
+    }
+
+    public XSLTOutInterceptor(String phase, Class<?> before, Class<?> after, String xsltPath) {
+        super(phase, before, after, xsltPath);
+    }
+
+    @Override
+    public void handleMessage(Message message) {
+        if (checkContextProperty(message)) {
+            return;
+        }
+
+        // 1. Try to get and transform XMLStreamWriter message content
+        XMLStreamWriter xWriter = message.getContent(XMLStreamWriter.class);
+        if (xWriter != null) {
+            transformXWriter(message, xWriter);
+        } else {
+            // 2. Try to get and transform OutputStream message content
+            OutputStream out = message.getContent(OutputStream.class);
+            if (out != null) {
+                transformOS(message, out);
+            } else {
+                // 3. Try to get and transform Writer message content (actually used for JMS TextMessage)
+                Writer writer = message.getContent(Writer.class);
+                if (writer != null) {
+                    transformWriter(message, writer);
+                }
+            }
+        }
+    }
+
+    protected void transformXWriter(Message message, XMLStreamWriter xWriter) {
+        CachedWriter writer = new CachedWriter();
+        XMLStreamWriter delegate = StaxUtils.createXMLStreamWriter(writer);
+        XSLTStreamWriter wrapper = new XSLTStreamWriter(getXSLTTemplate(), writer, delegate, xWriter);
+        message.setContent(XMLStreamWriter.class, wrapper);
+        message.put(AbstractOutDatabindingInterceptor.DISABLE_OUTPUTSTREAM_OPTIMIZATION,
+                    Boolean.TRUE);
+    }
+
+    protected void transformOS(Message message, OutputStream out) {
+        CachedOutputStream wrapper = new CachedOutputStream();
+        CachedOutputStreamCallback callback = new XSLTCachedOutputStreamCallback(getXSLTTemplate(), out);
+        wrapper.registerCallback(callback);
+        message.setContent(OutputStream.class, wrapper);
+    }
+
+    protected void transformWriter(Message message, Writer writer) {
+        XSLTCachedWriter wrapper = new XSLTCachedWriter(getXSLTTemplate(), writer);
+        message.setContent(Writer.class, wrapper);
+    }
+
+
+    public static class XSLTStreamWriter extends DelegatingXMLStreamWriter {
+        private final Templates xsltTemplate;
+        private final CachedWriter cachedWriter;
+        private final XMLStreamWriter origXWriter;
+
+        public XSLTStreamWriter(Templates xsltTemplate, CachedWriter cachedWriter,
+                                XMLStreamWriter delegateXWriter, XMLStreamWriter origXWriter) {
+            super(delegateXWriter);
+            this.xsltTemplate = xsltTemplate;
+            this.cachedWriter = cachedWriter;
+            this.origXWriter = origXWriter;
+        }
+
+        @Override
+        public void close() {
+            Reader transformedReader = null;
+            try {
+                super.flush();
+                transformedReader = XSLTUtils.transform(xsltTemplate, cachedWriter.getReader());
+                StaxUtils.copy(new StreamSource(transformedReader), origXWriter);
+            } catch (XMLStreamException e) {
+                throw new Fault("STAX_COPY", LOG, e, e.getMessage());
+            } catch (IOException e) {
+                throw new Fault("GET_CACHED_INPUT_STREAM", LOG, e, e.getMessage());
+            } finally {
+                try {
+                    if (transformedReader != null) {
+                        transformedReader.close();
+                    }
+                    cachedWriter.close();
+                    StaxUtils.close(origXWriter);
+                    super.close();
+                } catch (Exception e) {
+                    LOG.warning("Cannot close stream after transformation: " + e.getMessage());
+                }
+            }
+        }
+    }
+
+    public static class XSLTCachedOutputStreamCallback implements CachedOutputStreamCallback {
+        private final Templates xsltTemplate;
+        private final OutputStream origStream;
+
+        public XSLTCachedOutputStreamCallback(Templates xsltTemplate, OutputStream origStream) {
+            this.xsltTemplate = xsltTemplate;
+            this.origStream = origStream;
+        }
+
+        @Override
+        public void onFlush(CachedOutputStream wrapper) {
+        }
+
+        @Override
+        public void onClose(CachedOutputStream wrapper) {
+            InputStream transformedStream;
+            Exception exceptionOnClose = null;
+            try {
+                transformedStream = XSLTUtils.transform(xsltTemplate, wrapper.getInputStream());
+                IOUtils.copyAndCloseInput(transformedStream, origStream);
+            } catch (IOException e) {
+                throw new Fault("STREAM_COPY", LOG, e, e.getMessage());
+            } finally {
+                try {
+                    origStream.close();
+                } catch (Exception e) {
+                    exceptionOnClose = e;
+                }
+            }
+            
+            if (exceptionOnClose == null) {
+                return;
+            }
+            throw new Fault(exceptionOnClose);
+        }
+    }
+
+    public static class XSLTCachedWriter extends CachedWriter {
+        private final Templates xsltTemplate;
+        private final Writer origWriter;
+
+        public XSLTCachedWriter(Templates xsltTemplate, Writer origWriter) {
+            this.xsltTemplate = xsltTemplate;
+            this.origWriter = origWriter;
+        }
+
+        @Override
+        protected void doClose() {
+            try {
+                final Reader transformedReader = XSLTUtils.transform(xsltTemplate, getReader());
+                IOUtils.copyAndCloseInput(transformedReader, origWriter, IOUtils.DEFAULT_BUFFER_SIZE);
+            } catch (IOException e) {
+                throw new Fault("READER_COPY", LOG, e, e.getMessage());
+            } finally {
+                try {
+                    origWriter.close();
+                } catch (IOException e) {
+                    LOG.warning("Cannot close stream after transformation: " + e.getMessage());
+                }
+            }
+        }
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/headers/Header.java b/transform/src/patch/java/org/apache/cxf/headers/Header.java
new file mode 100644
index 0000000..f933c14
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/headers/Header.java
@@ -0,0 +1,78 @@
+/**
+ * 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.cxf.headers;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.databinding.DataBinding;
+
+public class Header {
+    public enum Direction  {
+        DIRECTION_IN,
+        DIRECTION_OUT,
+        DIRECTION_INOUT
+    }
+
+    public static final String HEADER_LIST = Header.class.getName() + ".list";
+
+
+    private DataBinding dataBinding;
+    private QName name;
+    private Object object;
+
+    private Direction direction = Header.Direction.DIRECTION_OUT;
+
+    public Header(QName q, Object o) {
+        this(q, o, null);
+    }
+
+    public Header(QName q, Object o, DataBinding b) {
+        object = o;
+        name = q;
+        dataBinding = b;
+    }
+
+    public DataBinding getDataBinding() {
+        return dataBinding;
+    }
+    public void setDataBinding(DataBinding dataBinding) {
+        this.dataBinding = dataBinding;
+    }
+    public QName getName() {
+        return name;
+    }
+    public void setName(QName name) {
+        this.name = name;
+    }
+    public Object getObject() {
+        return object;
+    }
+    public void setObject(Object object) {
+        this.object = object;
+    }
+
+    public void setDirection(Direction hdrDirection) {
+        this.direction = hdrDirection;
+    }
+
+    public Direction getDirection() {
+        return direction;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/helpers/DOMUtils.java b/transform/src/patch/java/org/apache/cxf/helpers/DOMUtils.java
new file mode 100644
index 0000000..37bde67
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/helpers/DOMUtils.java
@@ -0,0 +1,895 @@
+/**
+ * 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.cxf.helpers;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ReflectionUtil;
+import org.apache.cxf.common.util.StringUtils;
+
+/**
+ * Few simple utils to read DOM. This is originally from the Jakarta Commons Modeler.
+ */
+public final class DOMUtils {
+    private static boolean isJre9SAAJ;
+    private static final Map<ClassLoader, DocumentBuilder> DOCUMENT_BUILDERS
+        = Collections.synchronizedMap(new WeakHashMap<ClassLoader, DocumentBuilder>());
+    private static final String XMLNAMESPACE = "xmlns";
+    private static volatile Document emptyDocument;
+
+    private static final ClassValue<Method> GET_DOM_ELEMENTS_METHODS = new ClassValue<Method>() {
+        @Override
+        protected Method computeValue(Class<?> type) {
+            try {
+                return ReflectionUtil.getMethod(type, "getDomElement");
+            } catch (NoSuchMethodException e) {
+                //best effort to try, do nothing if NoSuchMethodException
+                return null;
+            }
+        }
+    };
+    private static final ClassValue<Field> GET_DOCUMENT_FRAGMENT_FIELDS = new ClassValue<Field>() {
+        @Override
+        protected Field computeValue(Class<?> type) {
+            return ReflectionUtil.getDeclaredField(type, "documentFragment");
+        }
+
+    };
+
+    static {
+        try {
+            Method[] methods = DOMUtils.class.getClassLoader().
+                loadClass("com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl").getMethods();
+            for (Method method : methods) {
+                if ("register".equals(method.getName())) {
+                    //this is the 1.4+ SAAJ impl
+                    setJava9SAAJ(true);
+                    break;
+                }
+            }
+        } catch (ClassNotFoundException cnfe) {
+            LogUtils.getL7dLogger(DOMUtils.class).finest(
+                "can't load class com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl");
+
+            try {
+                Method[] methods = DOMUtils.class.getClassLoader().
+                    loadClass("com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl").getMethods();
+                for (Method method : methods) {
+                    if ("register".equals(method.getName())) {
+                        //this is the SAAJ impl in JDK9
+                        setJava9SAAJ(true);
+                        break;
+                    }
+                }
+            } catch (ClassNotFoundException cnfe1) {
+                LogUtils.getL7dLogger(DOMUtils.class).finest(
+                    "can't load class com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl");
+            }
+        } catch (Throwable throwable) {
+            LogUtils.getL7dLogger(DOMUtils.class).finest(
+                "Other JDK vendor");
+        }
+    }
+
+    private DOMUtils() {
+    }
+
+    private static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
+        ClassLoader loader = getContextClassLoader();
+        if (loader == null) {
+            loader = getClassLoader(DOMUtils.class);
+        }
+        if (loader == null) {
+            return createDocumentBuilder();
+        }
+        DocumentBuilder factory = DOCUMENT_BUILDERS.get(loader);
+        if (factory == null) {
+            factory = createDocumentBuilder();
+            DOCUMENT_BUILDERS.put(loader, factory);
+        }
+        return factory;
+    }
+
+    private static DocumentBuilder createDocumentBuilder() throws ParserConfigurationException {
+        DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
+        f.setNamespaceAware(true);
+        f.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+        return f.newDocumentBuilder();
+    }
+
+    private static ClassLoader getContextClassLoader() {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return Thread.currentThread().getContextClassLoader();
+                }
+            });
+        }
+        return Thread.currentThread().getContextClassLoader();
+    }
+
+    private static ClassLoader getClassLoader(final Class<?> clazz) {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return clazz.getClassLoader();
+                }
+            });
+        }
+        return clazz.getClassLoader();
+    }
+
+    /**
+     * Creates a new Document object
+     * @throws ParserConfigurationException
+     */
+    public static Document newDocument() {
+        return createDocument();
+    }
+    public static Document createDocument() {
+        try {
+            return getDocumentBuilder().newDocument();
+        } catch (ParserConfigurationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static synchronized Document createEmptyDocument() {
+        if (emptyDocument == null) {
+            emptyDocument = createDocument();
+
+            // uncomment this to see if anything is actually setting anything into the empty doc
+            /*
+            final Document doc  = createDocument();
+            emptyDocument = (Document)org.apache.cxf.common.util.ProxyHelper.getProxy(
+                DOMUtils.class.getClassLoader(),
+                new Class<?>[] {Document.class},
+                new java.lang.reflect.InvocationHandler() {
+                    @Override
+                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+                        if (method.getName().contains("create")) {
+                            return method.invoke(doc, args);
+                        }
+                        throw new IllegalStateException("Cannot modify factory document");
+                    }
+                });
+            */
+        }
+        return emptyDocument;
+    }
+    /**
+     * Returns a static Document that should always be "empty".  It's useful as a factory for
+     * for creating Elements and other nodes that will be traversed later and don't need to
+     * be attached into a document
+     * @return an empty document
+     */
+    public static Document getEmptyDocument() {
+        Document doc = emptyDocument;
+        if (doc == null) {
+            doc = createEmptyDocument();
+        }
+        return doc;
+    }
+
+
+    /**
+     * This function is much like getAttribute, but returns null, not "", for a nonexistent attribute.
+     *
+     * @param e
+     * @param attributeName
+     */
+    public static String getAttributeValueEmptyNull(Element e, String attributeName) {
+        Attr node = e.getAttributeNode(attributeName);
+        if (node == null) {
+            return null;
+        }
+        return node.getValue();
+    }
+
+    /**
+     * Get the text content of a node and all it's children or null if there is no text
+     */
+    public static String getAllContent(Node n) {
+        StringBuilder b = new StringBuilder();
+        getAllContent(n, b);
+        return b.toString();
+    }
+    private static void getAllContent(Node n, StringBuilder b) {
+        Node nd = n.getFirstChild();
+        while (nd != null) {
+            if (nd instanceof Text && !(nd instanceof Comment)) {
+                b.append(((Text)nd).getData());
+            } else {
+                getAllContent(nd, b);
+            }
+            nd = nd.getNextSibling();
+        }
+    }
+    /**
+     * Get the trimmed text content of a node or null if there is no text
+     */
+    public static String getContent(Node n) {
+        String s = getRawContent(n);
+        if (s != null) {
+            s = s.trim();
+        }
+        return s;
+    }
+
+    /**
+     * Get the raw text content of a node or null if there is no text
+     */
+    public static String getRawContent(Node n) {
+        if (n == null) {
+            return null;
+        }
+        StringBuilder b = null;
+        String s = null;
+        Node n1 = n.getFirstChild();
+        while (n1 != null) {
+            if (n1.getNodeType() == Node.TEXT_NODE || n1.getNodeType() == Node.CDATA_SECTION_NODE) {
+                if (b != null) {
+                    b.append(((Text)n1).getNodeValue());
+                } else if (s == null) {
+                    s = ((Text)n1).getNodeValue();
+                } else {
+                    b = new StringBuilder(s).append(((Text)n1).getNodeValue());
+                    s = null;
+                }
+            }
+            n1 = n1.getNextSibling();
+        }
+        if (b != null) {
+            return b.toString();
+        }
+        return s;
+    }
+
+    /**
+     * Get the first element child.
+     *
+     * @param parent lookup direct childs
+     * @param name name of the element. If null return the first element.
+     */
+    public static Node getChild(Node parent, String name) {
+        if (parent == null) {
+            return null;
+        }
+
+        Node first = parent.getFirstChild();
+        if (first == null) {
+            return null;
+        }
+
+        for (Node node = first; node != null; node = node.getNextSibling()) {
+            
+            if (node.getNodeType() != Node.ELEMENT_NODE) {
+                continue;
+            }
+            if (name != null && name.equals(node.getNodeName())) {
+                return node;
+            }
+            if (name == null) {
+                return node;
+            }
+        }
+        return null;
+    }
+
+
+    public static boolean hasAttribute(Element element, String value) {
+        NamedNodeMap attributes = element.getAttributes();
+        for (int i = 0; i < attributes.getLength(); i++) {
+            Node node = attributes.item(i);
+            if (value.equals(node.getNodeValue())) {
+                return true;
+            }
+        }
+        return false;
+    }
+    public static String getAttribute(Node element, String attName) {
+        NamedNodeMap attrs = element.getAttributes();
+        if (attrs == null) {
+            return null;
+        }
+        Node attN = attrs.getNamedItem(attName);
+        if (attN == null) {
+            return null;
+        }
+        return attN.getNodeValue();
+    }
+
+    public static String getAttribute(Element element, QName attName) {
+        Attr attr;
+        if (StringUtils.isEmpty(attName.getNamespaceURI())) {
+            attr = element.getAttributeNode(attName.getLocalPart());
+        } else {
+            attr = element.getAttributeNodeNS(attName.getNamespaceURI(), attName.getLocalPart());
+        }
+        return attr == null ? null : attr.getValue();
+    }
+
+    public static void setAttribute(Node node, String attName, String val) {
+        NamedNodeMap attributes = node.getAttributes();
+        Node attNode = node.getOwnerDocument().createAttributeNS(null, attName);
+        attNode.setNodeValue(val);
+        attributes.setNamedItem(attNode);
+    }
+
+    public static void removeAttribute(Node node, String attName) {
+        NamedNodeMap attributes = node.getAttributes();
+        attributes.removeNamedItem(attName);
+    }
+
+    /**
+     * Set or replace the text value
+     */
+    public static void setText(Node node, String val) {
+        Node chld = DOMUtils.getChild(node, Node.TEXT_NODE);
+        if (chld == null) {
+            Node textN = node.getOwnerDocument().createTextNode(val);
+            node.appendChild(textN);
+            return;
+        }
+        // change the value
+        chld.setNodeValue(val);
+    }
+
+    /**
+     * Find the first direct child with a given attribute.
+     *
+     * @param parent
+     * @param elemName name of the element, or null for any
+     * @param attName attribute we're looking for
+     * @param attVal attribute value or null if we just want any
+     */
+    public static Element findChildWithAtt(Node parent, String elemName, String attName, String attVal) {
+
+        Element child = (Element)getChild(parent, Node.ELEMENT_NODE);
+        if (attVal == null) {
+            while (child != null && (elemName == null || elemName.equals(child.getNodeName()))
+                   && DOMUtils.getAttribute(child, attName) != null) {
+                child = (Element)getNext(child, elemName, Node.ELEMENT_NODE);
+            }
+        } else {
+            while (child != null && (elemName == null || elemName.equals(child.getNodeName()))
+                   && !attVal.equals(DOMUtils.getAttribute(child, attName))) {
+                child = (Element)getNext(child, elemName, Node.ELEMENT_NODE);
+            }
+        }
+        return child;
+    }
+
+    /**
+     * Get the first child's content ( ie it's included TEXT node ).
+     */
+    public static String getChildContent(Node parent, String name) {
+        Node first = parent.getFirstChild();
+        if (first == null) {
+            return null;
+        }
+        for (Node node = first; node != null; node = node.getNextSibling()) {
+          
+            if (name.equals(node.getNodeName())) {
+                return getRawContent(node);
+            }
+        }
+        return null;
+    }
+
+    public static QName getElementQName(Element el) {
+        return new QName(el.getNamespaceURI(), el.getLocalName());
+    }
+
+    /**
+     * Creates a QName object based on the qualified name
+     * and using the Node as a base to lookup the namespace
+     * for the prefix
+     * @param qualifiedName
+     * @param node
+     */
+    public static QName createQName(String qualifiedName, Node node) {
+        if (qualifiedName == null) {
+            return null;
+        }
+
+        int index = qualifiedName.indexOf(':');
+
+        if (index == -1) {
+            return new QName(qualifiedName);
+        }
+
+        String prefix = qualifiedName.substring(0, index);
+        String localName = qualifiedName.substring(index + 1);
+        String ns = node.lookupNamespaceURI(prefix);
+
+        if (ns == null) {
+            throw new RuntimeException("Invalid QName in mapping: " + qualifiedName);
+        }
+
+        return new QName(ns, localName, prefix);
+    }
+
+    public static QName convertStringToQName(String expandedQName) {
+        return convertStringToQName(expandedQName, "");
+    }
+
+    public static QName convertStringToQName(String expandedQName, String prefix) {
+        int ind1 = expandedQName.indexOf('{');
+        if (ind1 != 0) {
+            return new QName(expandedQName);
+        }
+
+        int ind2 = expandedQName.indexOf('}');
+        if (ind2 <= ind1 + 1 || ind2 >= expandedQName.length() - 1) {
+            return null;
+        }
+        String ns = expandedQName.substring(ind1 + 1, ind2);
+        String localName = expandedQName.substring(ind2 + 1);
+        return new QName(ns, localName, prefix);
+    }
+    public static Set<QName> convertStringsToQNames(List<String> expandedQNames) {
+        Set<QName> dropElements = Collections.emptySet();
+        if (expandedQNames != null) {
+            dropElements = new LinkedHashSet<>(expandedQNames.size());
+            for (String val : expandedQNames) {
+                dropElements.add(convertStringToQName(val));
+            }
+        }
+        return dropElements;
+    }
+
+
+    /**
+     * Get the first direct child with a given type
+     */
+    public static Element getFirstElement(Node parent) {
+        Node n = parent.getFirstChild();
+        while (n != null && Node.ELEMENT_NODE != n.getNodeType()) {
+            n = n.getNextSibling();
+        }
+        if (n == null) {
+            return null;
+        }
+        return (Element)n;
+    }
+
+    public static Element getNextElement(Element el) {
+        Node nd = el.getNextSibling();
+        while (nd != null) {
+            if (nd.getNodeType() == Node.ELEMENT_NODE) {
+                return (Element)nd;
+            }
+            nd = nd.getNextSibling();
+        }
+        return null;
+    }
+
+    /**
+     * Return the first element child with the specified qualified name.
+     *
+     * @param parent
+     * @param q
+     */
+    public static Element getFirstChildWithName(Element parent, QName q) {
+        String ns = q.getNamespaceURI();
+        String lp = q.getLocalPart();
+        return getFirstChildWithName(parent, ns, lp);
+    }
+
+    /**
+     * Return the first element child with the specified qualified name.
+     *
+     * @param parent
+     * @param ns
+     * @param lp
+     */
+    public static Element getFirstChildWithName(Element parent, String ns, String lp) {
+        for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) {
+            if (n instanceof Element) {
+                Element e = (Element)n;
+                String ens = (e.getNamespaceURI() == null) ? "" : e.getNamespaceURI();
+                if (ns.equals(ens) && lp.equals(e.getLocalName())) {
+                    return e;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return child elements with specified name.
+     *
+     * @param parent
+     * @param ns
+     * @param localName
+     */
+    public static List<Element> getChildrenWithName(Element parent, String ns, String localName) {
+        List<Element> r = new ArrayList<>();
+        for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) {
+            if (n instanceof Element) {
+                Element e = (Element)n;
+                String eNs = (e.getNamespaceURI() == null) ? "" : e.getNamespaceURI();
+                if (ns.equals(eNs) && localName.equals(e.getLocalName())) {
+                    r.add(e);
+                }
+            }
+        }
+        return r;
+    }
+
+    /**
+     * Returns all child elements with specified namespace.
+     *
+     * @param parent the element to search under
+     * @param ns the namespace to find elements in
+     * @return all child elements with specified namespace
+     */
+    public static List<Element> getChildrenWithNamespace(Element parent, String ns) {
+        List<Element> r = new ArrayList<>();
+        for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) {
+            if (n instanceof Element) {
+                Element e = (Element)n;
+                String eNs = (e.getNamespaceURI() == null) ? "" : e.getNamespaceURI();
+                if (ns.equals(eNs)) {
+                    r.add(e);
+                }
+            }
+        }
+        return r;
+    }
+
+    /**
+     * Get the first child of the specified type.
+     *
+     * @param parent
+     * @param type
+     */
+    public static Node getChild(Node parent, int type) {
+        Node n = parent.getFirstChild();
+        while (n != null && type != n.getNodeType()) {
+            n = n.getNextSibling();
+        }
+        if (n == null) {
+            return null;
+        }
+        return n;
+    }
+
+    /**
+     * Get the next sibling with the same name and type
+     */
+    public static Node getNext(Node current) {
+        String name = current.getNodeName();
+        int type = current.getNodeType();
+        return getNext(current, name, type);
+    }
+
+    /**
+     * Return the next sibling with a given name and type
+     */
+    public static Node getNext(Node current, String name, int type) {
+        Node first = current.getNextSibling();
+        if (first == null) {
+            return null;
+        }
+
+        for (Node node = first; node != null; node = node.getNextSibling()) {
+
+            if (type >= 0 && node.getNodeType() != type) {
+                continue;
+            }
+
+            if (name == null) {
+                return node;
+            }
+            if (name.equals(node.getNodeName())) {
+                return node;
+            }
+        }
+        return null;
+    }
+
+    public static class NullResolver implements EntityResolver {
+        public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
+            return new InputSource(new StringReader(""));
+        }
+    }
+
+    public static String getPrefixRecursive(Element el, String ns) {
+        String prefix = getPrefix(el, ns);
+        if (prefix == null && el.getParentNode() instanceof Element) {
+            prefix = getPrefixRecursive((Element)el.getParentNode(), ns);
+        }
+        return prefix;
+    }
+
+    public static String getPrefix(Element el, String ns) {
+        NamedNodeMap atts = el.getAttributes();
+        for (int i = 0; i < atts.getLength(); i++) {
+            Node node = atts.item(i);
+            String name = node.getNodeName();
+            if (ns.equals(node.getNodeValue())
+                && (name != null && (XMLNAMESPACE.equals(name) || name.startsWith(XMLNAMESPACE + ":")))) {
+                return node.getLocalName();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get all prefixes defined, up to the root, for a namespace URI.
+     *
+     * @param element
+     * @param namespaceUri
+     * @param prefixes
+     */
+    public static void getPrefixesRecursive(Element element, String namespaceUri, List<String> prefixes) {
+        getPrefixes(element, namespaceUri, prefixes);
+        Node parent = element.getParentNode();
+        if (parent instanceof Element) {
+            getPrefixesRecursive((Element)parent, namespaceUri, prefixes);
+        }
+    }
+
+    /**
+     * Get all prefixes defined on this element for the specified namespace.
+     *
+     * @param element
+     * @param namespaceUri
+     * @param prefixes
+     */
+    public static void getPrefixes(Element element, String namespaceUri, List<String> prefixes) {
+        NamedNodeMap atts = element.getAttributes();
+        for (int i = 0; i < atts.getLength(); i++) {
+            Node node = atts.item(i);
+            String name = node.getNodeName();
+            if (namespaceUri.equals(node.getNodeValue())
+                && (name != null && (XMLNAMESPACE.equals(name) || name.startsWith(XMLNAMESPACE + ":")))) {
+                prefixes.add(node.getPrefix());
+            }
+        }
+    }
+
+    public static String createNamespace(Element el, String ns) {
+        String p = "ns1";
+        int i = 1;
+        while (getPrefix(el, ns) != null) {
+            p = "ns" + i;
+            i++;
+        }
+        addNamespacePrefix(el, ns, p);
+        return p;
+    }
+
+    /**
+     * Starting from a node, find the namespace declaration for a prefix. for a matching namespace
+     * declaration.
+     *
+     * @param node search up from here to search for namespace definitions
+     * @param searchPrefix the prefix we are searching for
+     * @return the namespace if found.
+     */
+    public static String getNamespace(Node node, String searchPrefix) {
+
+        Element el;
+        while (!(node instanceof Element)) {
+            node = node.getParentNode();
+        }
+        el = (Element)node;
+
+        NamedNodeMap atts = el.getAttributes();
+        for (int i = 0; i < atts.getLength(); i++) {
+            Node currentAttribute = atts.item(i);
+            String currentLocalName = currentAttribute.getLocalName();
+            String currentPrefix = currentAttribute.getPrefix();
+            if (searchPrefix.equals(currentLocalName) && XMLNAMESPACE.equals(currentPrefix)) {
+                return currentAttribute.getNodeValue();
+            } else if (StringUtils.isEmpty(searchPrefix) && XMLNAMESPACE.equals(currentLocalName)
+                       && StringUtils.isEmpty(currentPrefix)) {
+                return currentAttribute.getNodeValue();
+            }
+        }
+
+        Node parent = el.getParentNode();
+        if (parent instanceof Element) {
+            return getNamespace(parent, searchPrefix);
+        }
+
+        return null;
+    }
+
+    public static List<Element> findAllElementsByTagNameNS(Element elem, String nameSpaceURI,
+                                                           String localName) {
+        List<Element> ret = new LinkedList<>();
+        findAllElementsByTagNameNS(elem, nameSpaceURI, localName, ret);
+        return ret;
+    }
+
+    /**
+     * Try to get the DOM Node from the SAAJ Node with JAVA9 afterwards
+     * @param node The original node we need check
+     * @return The DOM node
+     */
+    public static Node getDomElement(Node node) {
+        if (node != null && isJava9SAAJ()) {
+            //java9plus hack
+            Method method = GET_DOM_ELEMENTS_METHODS.get(node.getClass());
+            if (method != null) {
+                try {
+                    return (Node)ReflectionUtil.setAccessible(method).invoke(node);
+                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+        return node;
+    }
+
+    /**
+     * Try to get the DOM DocumentFragment from the SAAJ DocumentFragment with JAVA9 afterwards
+     * @param fragment The original documentFragment we need to check
+     * @return The DOM DocumentFragment
+     */
+    public static DocumentFragment getDomDocumentFragment(DocumentFragment fragment) {
+        if (fragment != null && isJava9SAAJ()) {
+            //java9 plus hack
+            Field f = GET_DOCUMENT_FRAGMENT_FIELDS.get(fragment.getClass());
+            if (f != null) {
+                return ReflectionUtil.accessDeclaredField(f, fragment, DocumentFragment.class);
+            }
+        }
+        return fragment;
+    }
+
+    private static void findAllElementsByTagNameNS(Element el, String nameSpaceURI, String localName,
+                                                   List<Element> elementList) {
+
+        if (el.getNamespaceURI() != null && localName.equals(el.getLocalName())
+            && nameSpaceURI.contains(el.getNamespaceURI())) {
+            elementList.add(el);
+        }
+        Element elem = getFirstElement(el);
+        while (elem != null) {
+            findAllElementsByTagNameNS(elem, nameSpaceURI, localName, elementList);
+            elem = getNextElement(elem);
+        }
+    }
+
+    public static List<Element> findAllElementsByTagName(Element elem, String tagName) {
+        List<Element> ret = new LinkedList<>();
+        findAllElementsByTagName(elem, tagName, ret);
+        return ret;
+    }
+
+    private static void findAllElementsByTagName(Element el, String tagName, List<Element> elementList) {
+
+        if (tagName.equals(el.getTagName())) {
+            elementList.add(el);
+        }
+        Element elem = getFirstElement(el);
+        while (elem != null) {
+            findAllElementsByTagName(elem, tagName, elementList);
+            elem = getNextElement(elem);
+        }
+    }
+    public static boolean hasElementWithName(Element el, String nameSpaceURI, String localName) {
+        if (el.getNamespaceURI() != null && localName.equals(el.getLocalName())
+            && nameSpaceURI.contains(el.getNamespaceURI())) {
+            return true;
+        }
+        Element elem = getFirstElement(el);
+        while (elem != null) {
+            if (hasElementWithName(elem, nameSpaceURI, localName)) {
+                return true;
+            }
+            elem = getNextElement(elem);
+        }
+        return false;
+    }
+    public static boolean hasElementInNS(Element el, String namespace) {
+
+        if (namespace.equals(el.getNamespaceURI())) {
+            return true;
+        }
+        Element elem = getFirstElement(el);
+        while (elem != null) {
+            if (hasElementInNS(elem, namespace)) {
+                return true;
+            }
+            elem = getNextElement(elem);
+        }
+        return false;
+    }
+    /**
+     * Set a namespace/prefix on an element if it is not set already. First off, it searches for the element
+     * for the prefix associated with the specified namespace. If the prefix isn't null, then this is
+     * returned. Otherwise, it creates a new attribute using the namespace/prefix passed as parameters.
+     *
+     * @param element
+     * @param namespace
+     * @param prefix
+     * @return the prefix associated with the set namespace
+     */
+    public static String setNamespace(Element element, String namespace, String prefix) {
+        String pre = getPrefixRecursive(element, namespace);
+        if (pre != null) {
+            return pre;
+        }
+        element.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + prefix, namespace);
+        return prefix;
+    }
+
+    /**
+     * Add a namespace prefix definition to an element.
+     *
+     * @param element
+     * @param namespaceUri
+     * @param prefix
+     */
+    public static void addNamespacePrefix(Element element, String namespaceUri, String prefix) {
+        element.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + prefix, namespaceUri);
+    }
+
+    public static boolean isJava9SAAJ() {
+        return isJre9SAAJ;
+    }
+
+    private static void setJava9SAAJ(boolean isJava9SAAJ) {
+        DOMUtils.isJre9SAAJ = isJava9SAAJ;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/helpers/IOUtils.java b/transform/src/patch/java/org/apache/cxf/helpers/IOUtils.java
new file mode 100644
index 0000000..74af28d
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/helpers/IOUtils.java
@@ -0,0 +1,428 @@
+/**
+ * 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.cxf.helpers;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PushbackInputStream;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+
+import org.apache.cxf.io.CopyingOutputStream;
+import org.apache.cxf.io.Transferable;
+
+public final class IOUtils {
+    public static final Charset UTF8_CHARSET = java.nio.charset.StandardCharsets.UTF_8;
+    public static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+
+    private IOUtils() {
+
+    }
+    
+    /**
+     * Checks if input stream is empty. If the standard InputStream means do not provide
+     * such details, the stream might be wrapped into PushbackInputStream and is going
+     * to be returned instead of original one.
+     * @param is input stream to check
+     * @return "null" if original input stream is empty, otherwise original stream or 
+     * original stream wrapped into PushbackInputStream.
+     * @throws IOException
+     */
+    public static InputStream nullOrNotEmptyStream(InputStream is) throws IOException {
+        if (isEmpty(is)) {
+            return null;
+        } else if (!(is instanceof PushbackInputStream)) {
+            final byte[] bytes = new byte[1];
+            
+            final PushbackInputStream pbStream = new PushbackInputStream(is);
+            boolean isEmpty = isEof(pbStream.read(bytes));
+            
+            if (!isEmpty) {
+                pbStream.unread(bytes);
+                return pbStream;
+            }
+            
+            return null;
+        }
+        
+        return is;
+    }
+
+    public static boolean isEmpty(InputStream is) throws IOException {
+        if (is == null) {
+            return true;
+        }
+        try {
+            // if available is 0 it does not mean it is empty
+            if (is.available() > 0) {
+                return false;
+            }
+        } catch (IOException ioe) {
+            //Do nothing
+        }
+        final byte[] bytes = new byte[1];
+        if (is.markSupported()) {
+            is.mark(1);
+            try {
+                return isEof(is.read(bytes));
+            } finally {
+                is.reset();
+            }
+        }
+        
+        if (!(is instanceof PushbackInputStream)) {
+            return false;
+        }
+        
+        // it may be an attachment stream
+        PushbackInputStream pbStream = (PushbackInputStream)is;
+        boolean isEmpty = isEof(pbStream.read(bytes));
+        if (!isEmpty) {
+            pbStream.unread(bytes);
+        }
+        
+        return isEmpty;
+    }
+    private static boolean isEof(int result) {
+        return result == -1;
+    }
+    /**
+     * Use this function instead of new String(byte[], String) to avoid surprises from
+     * non-standard default encodings.
+     * @param bytes
+     * @param charsetName
+     */
+    public static String newStringFromBytes(byte[] bytes, String charsetName) {
+        try {
+            return new String(bytes, charsetName);
+        } catch (UnsupportedEncodingException e) {
+            throw
+                new RuntimeException("Impossible failure: Charset.forName(\""
+                                     + charsetName + "\") returns invalid name.");
+
+        }
+    }
+
+
+    /**
+     * Use this function instead of new String(byte[]) to avoid surprises from non-standard default encodings.
+     * @param bytes
+     */
+    public static String newStringFromBytes(byte[] bytes) {
+        return newStringFromBytes(bytes, UTF8_CHARSET.name());
+    }
+
+    /**
+     * Use this function instead of new String(byte[], int, int, String)
+     * to avoid surprises from non-standard default encodings.
+     * @param bytes
+     * @param charsetName
+     * @param start
+     * @param length
+     */
+    public static String newStringFromBytes(byte[] bytes, String charsetName, int start, int length) {
+        try {
+            return new String(bytes, start, length, charsetName);
+        } catch (UnsupportedEncodingException e) {
+            throw
+                new RuntimeException("Impossible failure: Charset.forName(\""
+                                     + charsetName + "\") returns invalid name.");
+
+        }
+    }
+
+    /**
+     * Use this function instead of new String(byte[], int, int)
+     * to avoid surprises from non-standard default encodings.
+     * @param bytes
+     * @param start
+     * @param length
+     */
+    public static String newStringFromBytes(byte[] bytes, int start, int length) {
+        return newStringFromBytes(bytes, UTF8_CHARSET.name(), start, length);
+    }
+
+    public static int copy(final InputStream input, final OutputStream output)
+        throws IOException {
+        if (input == null) {
+            return 0;
+        }
+        if (output instanceof CopyingOutputStream) {
+            return ((CopyingOutputStream)output).copyFrom(input);
+        }
+        return copy(input, output, DEFAULT_BUFFER_SIZE);
+    }
+
+    public static int copyAndCloseInput(final InputStream input,
+            final OutputStream output) throws IOException {
+        try (InputStream in = input) {
+            return copy(in, output);
+        }
+    }
+
+    public static int copyAndCloseInput(final InputStream input,
+            final OutputStream output, int bufferSize) throws IOException {
+        try (InputStream in = input) {
+            return copy(in, output, bufferSize);
+        }
+    }
+
+    public static void copyAndCloseInput(final Reader input,
+                                        final Writer output) throws IOException {
+        try (Reader r = input) {
+            copy(r, output, DEFAULT_BUFFER_SIZE);
+        }
+    }
+
+    public static void copyAndCloseInput(final Reader input,
+            final Writer output, int bufferSize) throws IOException {
+        try (Reader r = input) {
+            copy(r, output, bufferSize);
+        }
+    }
+
+    public static int copy(final InputStream input, final OutputStream output,
+            int bufferSize) throws IOException {
+        int avail = input.available();
+        if (avail > 262144) {
+            avail = 262144;
+        }
+        if (avail > bufferSize) {
+            bufferSize = avail;
+        }
+        final byte[] buffer = new byte[bufferSize];
+        int n = input.read(buffer);
+        int total = 0;
+        while (-1 != n) {
+            if (n == 0) {
+                throw new IOException("0 bytes read in violation of InputStream.read(byte[])");
+            }
+            output.write(buffer, 0, n);
+            total += n;
+            n = input.read(buffer);
+        }
+        return total;
+    }
+
+    /**
+     * Copy at least the specified number of bytes from the input to the output
+     * or until the inputstream is finished.
+     * @param input
+     * @param output
+     * @param atLeast
+     * @throws IOException
+     */
+    public static void copyAtLeast(final InputStream input,
+                               final OutputStream output,
+                               int atLeast) throws IOException {
+        final byte[] buffer = new byte[4096];
+        int n = atLeast > buffer.length ? buffer.length : atLeast;
+        n = input.read(buffer, 0, n);
+        while (-1 != n) {
+            if (n == 0) {
+                throw new IOException("0 bytes read in violation of InputStream.read(byte[])");
+            }
+            output.write(buffer, 0, n);
+            atLeast -= n;
+            if (atLeast <= 0) {
+                return;
+            }
+            n = atLeast > buffer.length ? buffer.length : atLeast;
+            n = input.read(buffer, 0, n);
+        }
+    }
+
+    public static void copyAtLeast(final Reader input,
+                                   final Writer output,
+                                   int atLeast) throws IOException {
+        final char[] buffer = new char[4096];
+        int n = atLeast > buffer.length ? buffer.length : atLeast;
+        n = input.read(buffer, 0, n);
+        while (-1 != n) {
+            if (n == 0) {
+                throw new IOException("0 bytes read in violation of Reader.read(char[])");
+            }
+            output.write(buffer, 0, n);
+            atLeast -= n;
+            if (atLeast <= 0) {
+                return;
+            }
+            n = atLeast > buffer.length ? buffer.length : atLeast;
+            n = input.read(buffer, 0, n);
+        }
+    }
+
+
+    public static void copy(final Reader input, final Writer output,
+            final int bufferSize) throws IOException {
+        final char[] buffer = new char[bufferSize];
+        int n = input.read(buffer);
+        while (-1 != n) {
+            output.write(buffer, 0, n);
+            n = input.read(buffer);
+        }
+    }
+
+    public static void transferTo(InputStream inputStream, File destinationFile) throws IOException {
+        if (Transferable.class.isAssignableFrom(inputStream.getClass())) {
+            ((Transferable)inputStream).transferTo(destinationFile);
+        } else {
+            try (OutputStream out = Files.newOutputStream(destinationFile.toPath())) {
+                copyAndCloseInput(inputStream, out);
+            }
+        }
+    }
+
+
+    public static String toString(final InputStream input) throws IOException {
+        return toString(input, DEFAULT_BUFFER_SIZE);
+    }
+    public static String toString(final InputStream input, String charset) throws IOException {
+        return toString(input, DEFAULT_BUFFER_SIZE, charset);
+    }
+    public static String toString(final InputStream input, int bufferSize)
+        throws IOException {
+        return toString(input, bufferSize, null);
+    }
+    public static String toString(final InputStream input, int bufferSize, String charset)
+        throws IOException {
+
+
+        int avail = input.available();
+        if (avail > bufferSize) {
+            bufferSize = avail;
+        }
+        Reader reader = charset == null ? new InputStreamReader(input, UTF8_CHARSET)
+            : new InputStreamReader(input, charset);
+        return toString(reader, bufferSize);
+    }
+
+    public static String toString(final Reader input) throws IOException {
+        return toString(input, DEFAULT_BUFFER_SIZE);
+    }
+    public static String toString(final Reader input, int bufSize) throws IOException {
+
+        StringBuilder buf = new StringBuilder();
+        final char[] buffer = new char[bufSize];
+        try (Reader r = input) {
+            int n = r.read(buffer);
+            while (-1 != n) {
+                if (n == 0) {
+                    throw new IOException("0 bytes read in violation of InputStream.read(byte[])");
+                }
+                buf.append(buffer, 0, n);
+                n = r.read(buffer);
+            }
+            return buf.toString();
+        }
+    }
+
+    public static String readStringFromStream(InputStream in)
+        throws IOException {
+        return toString(in);
+    }
+
+    /**
+     * Load the InputStream into memory and return a ByteArrayInputStream that
+     * represents it. Closes the in stream.
+     *
+     * @param in
+     * @throws IOException
+     */
+    public static ByteArrayInputStream loadIntoBAIS(InputStream in)
+        throws IOException {
+        int i = in.available();
+        if (i < DEFAULT_BUFFER_SIZE) {
+            i = DEFAULT_BUFFER_SIZE;
+        }
+        LoadingByteArrayOutputStream bout = new LoadingByteArrayOutputStream(i);
+        copy(in, bout);
+        in.close();
+        return bout.createInputStream();
+    }
+
+    public static void consume(InputStream in) throws IOException {
+        int i = in.available();
+        if (i == 0) {
+            //if i is 0, then we MAY have already hit the end of the stream
+            //so try a read and return rather than allocate a buffer and such
+            int i2 = in.read();
+            if (i2 == -1) {
+                return;
+            }
+            //reading the byte may have caused a buffer to fill
+            i = in.available();
+        }
+        if (i < DEFAULT_BUFFER_SIZE) {
+            i = DEFAULT_BUFFER_SIZE;
+        }
+        if (i > 65536) {
+            i = 65536;
+        }
+        byte[] bytes = new byte[i];
+        while (in.read(bytes) != -1) {
+            //nothing - just discarding
+        }
+    }
+
+    /**
+     * Consumes at least the given number of bytes from the input stream
+     * @param input
+     * @param atLeast
+     * @throws IOException
+     */
+    public static void consume(final InputStream input,
+                               int atLeast) throws IOException {
+        final byte[] buffer = new byte[4096];
+        int n = atLeast > buffer.length ? buffer.length : atLeast;
+        n = input.read(buffer, 0, n);
+        while (-1 != n) {
+            if (n == 0) {
+                throw new IOException("0 bytes read in violation of InputStream.read(byte[])");
+            }
+            atLeast -= n;
+            if (atLeast <= 0) {
+                return;
+            }
+            n = atLeast > buffer.length ? buffer.length : atLeast;
+            n = input.read(buffer, 0, n);
+        }
+    }
+
+    public static byte[] readBytesFromStream(InputStream in) throws IOException {
+        int i = in.available();
+        if (i < DEFAULT_BUFFER_SIZE) {
+            i = DEFAULT_BUFFER_SIZE;
+        }
+        try (InputStream input = in; ByteArrayOutputStream bos = new ByteArrayOutputStream(i)) {
+            copy(input, bos);
+            return bos.toByteArray();
+        }
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/helpers/ServiceUtils.java b/transform/src/patch/java/org/apache/cxf/helpers/ServiceUtils.java
new file mode 100644
index 0000000..a39ee94
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/helpers/ServiceUtils.java
@@ -0,0 +1,214 @@
+/**
+ * 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.cxf.helpers;
+
+import java.util.StringTokenizer;
+
+import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.service.model.AbstractPropertiesHolder;
+import org.apache.cxf.service.model.BindingOperationInfo;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.service.model.OperationInfo;
+
+public final class ServiceUtils {
+
+    private ServiceUtils() {
+    }
+
+    /**
+     * A short cut method to be able to test for if Schema Validation should be enabled
+     * for IN or OUT without having to check BOTH and IN or OUT.
+     *
+     * @param message
+     * @param type
+     */
+    public static boolean isSchemaValidationEnabled(SchemaValidationType type, Message message) {
+        SchemaValidationType validationType = getSchemaValidationType(message);
+
+        boolean isRequestor = MessageUtils.isRequestor(message);
+        if (SchemaValidationType.REQUEST.equals(validationType)) {
+            if (isRequestor) {
+                validationType = SchemaValidationType.OUT;
+            } else {
+                validationType = SchemaValidationType.IN;
+            }
+        } else if (SchemaValidationType.RESPONSE.equals(validationType)) {
+            if (isRequestor) {
+                validationType = SchemaValidationType.IN;
+            } else {
+                validationType = SchemaValidationType.OUT;
+            }
+        }
+
+        return validationType.equals(type)
+            || ((SchemaValidationType.IN.equals(type) || SchemaValidationType.OUT.equals(type))
+                && SchemaValidationType.BOTH.equals(validationType));
+    }
+    /**
+     * A convenience method to check for schema validation config in the message context, and then in the service model.
+     * Does not modify the Message context (other than what is done in the getContextualProperty itself)
+     *
+     * @param message
+     */
+    public static SchemaValidationType getSchemaValidationType(Message message) {
+        SchemaValidationType validationType = getOverrideSchemaValidationType(message);
+        if (validationType == null) {
+            validationType = getSchemaValidationTypeFromModel(message);
+        }
+        if (validationType == null) {
+            Object obj = message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
+            if (obj != null) {
+                validationType = getSchemaValidationType(obj);
+            }
+        }
+        if (validationType == null) {
+            validationType = SchemaValidationType.NONE;
+        }
+
+        return validationType;
+    }
+
+    private static SchemaValidationType getOverrideSchemaValidationType(Message message) {
+        Object obj = message.get(Message.SCHEMA_VALIDATION_ENABLED);
+        if (obj == null && message.getExchange() != null) {
+            obj = message.getExchange().get(Message.SCHEMA_VALIDATION_ENABLED);
+        }
+        if (obj != null) {
+            // this method will transform the legacy enabled as well
+            return getSchemaValidationType(obj);
+        }
+        return null;
+    }
+
+    private static SchemaValidationType getSchemaValidationTypeFromModel(Message message) {
+        Exchange exchange = message.getExchange();
+        SchemaValidationType validationType = null;
+
+        if (exchange != null) {
+
+            BindingOperationInfo boi = exchange.getBindingOperationInfo();
+            if (boi != null) {
+                OperationInfo opInfo = boi.getOperationInfo();
+                if (opInfo != null) {
+                    validationType = getSchemaValidationTypeFromModel(opInfo);
+                }
+            }
+
+            if (validationType == null) {
+                Endpoint endpoint = exchange.getEndpoint();
+                if (endpoint != null) {
+                    EndpointInfo ep = endpoint.getEndpointInfo();
+                    if (ep != null) {
+                        validationType = getSchemaValidationTypeFromModel(ep);
+                    }
+                }
+            }
+        }
+
+        return validationType;
+    }
+
+    private static SchemaValidationType getSchemaValidationTypeFromModel(
+        AbstractPropertiesHolder properties) {
+        Object obj = properties.getProperty(Message.SCHEMA_VALIDATION_TYPE);
+        if (obj != null) {
+            return getSchemaValidationType(obj);
+        }
+        return null;
+    }
+
+    public static SchemaValidationType getSchemaValidationType(Object obj) {
+        if (obj instanceof SchemaValidationType) {
+            return (SchemaValidationType)obj;
+        } else if (obj != null) {
+            String value = obj.toString().toUpperCase(); // handle boolean values as well
+            if ("TRUE".equals(value)) {
+                return SchemaValidationType.BOTH;
+            } else if ("FALSE".equals(value)) {
+                return SchemaValidationType.NONE;
+            } else if (value.length() > 0) {
+                return SchemaValidationType.valueOf(value);
+            }
+        }
+
+        // fall through default value
+        return SchemaValidationType.NONE;
+    }
+
+    /**
+     * Generates a suitable service name from a given class. The returned name
+     * is the simple name of the class, i.e. without the package name.
+     *
+     * @param clazz the class.
+     * @return the name.
+     */
+    public static String makeServiceNameFromClassName(Class<?> clazz) {
+        String name = clazz.getName();
+        int last = name.lastIndexOf('.');
+        if (last != -1) {
+            name = name.substring(last + 1);
+        }
+
+        int inner = name.lastIndexOf('$');
+        if (inner != -1) {
+            name = name.substring(inner + 1);
+        }
+
+        return name;
+    }
+
+    /**
+     * Generates the name of a XML namespace from a given class name and
+     * protocol. The returned namespace will take the form
+     * <code>protocol://domain</code>, where <code>protocol</code> is the
+     * given protocol, and <code>domain</code> the inversed package name of
+     * the given class name. <p/> For instance, if the given class name is
+     * <code>org.codehaus.xfire.services.Echo</code>, and the protocol is
+     * <code>http</code>, the resulting namespace would be
+     * <code>http://services.xfire.codehaus.org</code>.
+     *
+     * @param className the class name
+     * @param protocol the protocol (eg. <code>http</code>)
+     * @return the namespace
+     */
+    public static String makeNamespaceFromClassName(String className, String protocol) {
+        int index = className.lastIndexOf('.');
+
+        if (index == -1) {
+            return protocol + "://" + "DefaultNamespace";
+        }
+
+        String packageName = className.substring(0, index);
+
+        StringTokenizer st = new StringTokenizer(packageName, ".");
+        String[] words = new String[st.countTokens()];
+
+        for (int i = words.length - 1; i >= 0; --i) {
+            words[i] = st.nextToken();
+        }
+
+        return protocol + "://" + String.join(".", words) + "/";
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/AbstractFaultChainInitiatorObserver.java b/transform/src/patch/java/org/apache/cxf/interceptor/AbstractFaultChainInitiatorObserver.java
new file mode 100644
index 0000000..70d5ae0
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/AbstractFaultChainInitiatorObserver.java
@@ -0,0 +1,142 @@
+/**
+ * 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.cxf.interceptor;
+
+import java.util.SortedSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.classloader.ClassLoaderUtils.ClassLoaderHolder;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.FaultMode;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.apache.cxf.service.model.BindingFaultInfo;
+import org.apache.cxf.transport.MessageObserver;
+
+public abstract class AbstractFaultChainInitiatorObserver implements MessageObserver {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(AbstractFaultChainInitiatorObserver.class);
+
+    private Bus bus;
+    private ClassLoader loader;
+
+    public AbstractFaultChainInitiatorObserver(Bus bus) {
+        this.bus = bus;
+        if (bus != null) {
+            loader = bus.getExtension(ClassLoader.class);
+        }
+    }
+
+    public void onMessage(Message message) {
+
+        assert null != message;
+
+        Bus origBus = BusFactory.getAndSetThreadDefaultBus(bus);
+        ClassLoaderHolder origLoader = null;
+        try {
+            if (loader != null) {
+                origLoader = ClassLoaderUtils.setThreadContextClassloader(loader);
+            }
+
+            Exchange exchange = message.getExchange();
+
+            Message faultMessage;
+
+            // now that we have switched over to the fault chain,
+            // prevent any further operations on the in/out message
+
+            if (isOutboundObserver()) {
+                Exception ex = message.getContent(Exception.class);
+                if (!(ex instanceof Fault)) {
+                    ex = new Fault(ex);
+                }
+                FaultMode mode = message.get(FaultMode.class);
+
+                faultMessage = exchange.getOutMessage();
+                if (null == faultMessage) {
+                    faultMessage = new MessageImpl();
+                    faultMessage.setExchange(exchange);
+                    faultMessage = exchange.getEndpoint().getBinding().createMessage(faultMessage);
+                }
+                faultMessage.setContent(Exception.class, ex);
+                if (null != mode) {
+                    faultMessage.put(FaultMode.class, mode);
+                }
+                //CXF-3981
+                if (message.get("javax.xml.ws.addressing.context.inbound") != null) {
+                    faultMessage.put("javax.xml.ws.addressing.context.inbound",
+                                     message.get("javax.xml.ws.addressing.context.inbound"));
+                }
+                exchange.setOutMessage(null);
+                exchange.setOutFaultMessage(faultMessage);
+                if (message.get(BindingFaultInfo.class) != null) {
+                    faultMessage.put(BindingFaultInfo.class, message.get(BindingFaultInfo.class));
+                }
+            } else {
+                faultMessage = message;
+                exchange.setInMessage(null);
+                exchange.setInFaultMessage(faultMessage);
+            }
+
+
+            // setup chain
+            PhaseInterceptorChain chain = new PhaseInterceptorChain(getPhases());
+            initializeInterceptors(faultMessage.getExchange(), chain);
+
+            faultMessage.setInterceptorChain(chain);
+            try {
+                chain.doIntercept(faultMessage);
+            } catch (RuntimeException exc) {
+                LOG.log(Level.SEVERE, "ERROR_DURING_ERROR_PROCESSING", exc);
+                throw exc;
+            } catch (Exception exc) {
+                LOG.log(Level.SEVERE, "ERROR_DURING_ERROR_PROCESSING", exc);
+                throw new RuntimeException(exc);
+            }
+        } finally {
+            if (origBus != bus) {
+                BusFactory.setThreadDefaultBus(origBus);
+            }
+            if (origLoader != null) {
+                origLoader.reset();
+            }
+        }
+    }
+
+    protected abstract boolean isOutboundObserver();
+
+    protected abstract SortedSet<Phase> getPhases();
+
+    protected void initializeInterceptors(Exchange ex, PhaseInterceptorChain chain) {
+
+    }
+
+    public Bus getBus() {
+        return bus;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/AbstractLoggingInterceptor.java b/transform/src/patch/java/org/apache/cxf/interceptor/AbstractLoggingInterceptor.java
new file mode 100644
index 0000000..5178453
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/AbstractLoggingInterceptor.java
@@ -0,0 +1,298 @@
+/**
+ * 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.cxf.interceptor;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.service.model.InterfaceInfo;
+import org.apache.cxf.staxutils.PrettyPrintXMLStreamWriter;
+import org.apache.cxf.staxutils.StaxUtils;
+
+/**
+ * A simple logging handler which outputs the bytes of the message to the
+ * Logger.
+ * @deprecated
+ */
+@Deprecated
+public abstract class AbstractLoggingInterceptor extends AbstractPhaseInterceptor<Message> {
+    public static final int DEFAULT_LIMIT = 48 * 1024;
+    protected static final String BINARY_CONTENT_MESSAGE = "--- Binary Content ---";
+    protected static final String MULTIPART_CONTENT_MESSAGE = "--- Multipart Content ---";
+    private static final String MULTIPART_CONTENT_MEDIA_TYPE = "multipart";
+    private static final String  LIVE_LOGGING_PROP = "org.apache.cxf.logging.enable";
+    private static final List<String> BINARY_CONTENT_MEDIA_TYPES = Arrays.asList(
+            "application/octet-stream", "application/pdf", "image/png", "image/jpeg", "image/gif");
+
+    protected int limit = DEFAULT_LIMIT;
+    protected long threshold = -1;
+    protected PrintWriter writer;
+    protected boolean prettyLogging;
+    private boolean showBinaryContent;
+    private boolean showMultipartContent = true;
+    private List<String> binaryContentMediaTypes = BINARY_CONTENT_MEDIA_TYPES;
+
+    public AbstractLoggingInterceptor(String phase) {
+        super(phase);
+    }
+    public AbstractLoggingInterceptor(String id, String phase) {
+        super(id, phase);
+    }
+
+    protected static boolean isLoggingDisabledNow(Message message) {
+        Object liveLoggingProp = message.getContextualProperty(LIVE_LOGGING_PROP);
+        return liveLoggingProp != null && PropertyUtils.isFalse(liveLoggingProp);
+    }
+
+    protected abstract Logger getLogger();
+
+    Logger getMessageLogger(Message message) {
+        if (isLoggingDisabledNow(message)) {
+            return null;
+        }
+        Endpoint ep = message.getExchange().getEndpoint();
+        if (ep == null || ep.getEndpointInfo() == null) {
+            return getLogger();
+        }
+        EndpointInfo endpoint = ep.getEndpointInfo();
+        if (endpoint.getService() == null) {
+            return getLogger();
+        }
+        Logger logger = endpoint.getProperty("MessageLogger", Logger.class);
+        if (logger == null) {
+            String serviceName = endpoint.getService().getName().getLocalPart();
+            InterfaceInfo iface = endpoint.getService().getInterface();
+            String portName = endpoint.getName().getLocalPart();
+            String portTypeName = iface.getName().getLocalPart();
+            String logName = "org.apache.cxf.services." + serviceName + "."
+                + portName + "." + portTypeName;
+            logger = LogUtils.getL7dLogger(this.getClass(), null, logName);
+            endpoint.setProperty("MessageLogger", logger);
+        }
+        return logger;
+    }
+
+    public void setOutputLocation(String s) {
+        if (s == null || "<logger>".equals(s)) {
+            writer = null;
+        } else if ("<stdout>".equals(s)) {
+            writer = new PrintWriter(System.out, true);
+        } else if ("<stderr>".equals(s)) {
+            writer = new PrintWriter(System.err, true);
+        } else {
+            try {
+                URI uri = new URI(s);
+                File file = new File(uri);
+                writer = new PrintWriter(new FileWriter(file, true), true);
+            } catch (Exception ex) {
+                getLogger().log(Level.WARNING, "Error configuring log location " + s, ex);
+            }
+        }
+    }
+
+    public void setPrintWriter(PrintWriter w) {
+        writer = w;
+    }
+
+    public PrintWriter getPrintWriter() {
+        return writer;
+    }
+
+    public void setLimit(int lim) {
+        limit = lim;
+    }
+
+    public int getLimit() {
+        return limit;
+    }
+
+    public void setPrettyLogging(boolean flag) {
+        prettyLogging = flag;
+    }
+
+    public boolean isPrettyLogging() {
+        return prettyLogging;
+    }
+
+    public void setInMemThreshold(long t) {
+        threshold = t;
+    }
+
+    public long getInMemThreshold() {
+        return threshold;
+    }
+
+    protected void writePayload(StringBuilder builder, CachedOutputStream cos,
+                                String encoding, String contentType, boolean truncated)
+        throws Exception {
+        // Just transform the XML message when the cos has content
+        if (!truncated && isPrettyLogging() && contentType != null && contentType.contains("xml")
+            && !contentType.toLowerCase().contains("multipart/related") && cos.size() > 0) {
+
+            StringWriter swriter = new StringWriter();
+            XMLStreamWriter xwriter = StaxUtils.createXMLStreamWriter(swriter);
+            xwriter = new PrettyPrintXMLStreamWriter(xwriter, 2);
+            try (InputStream in = cos.getInputStream()) {
+                InputStreamReader inputStreamReader = StringUtils.isEmpty(encoding)
+                    ? new InputStreamReader(in) : new InputStreamReader(in, encoding);
+                StaxUtils.copy(new StreamSource(inputStreamReader), xwriter);
+            } catch (XMLStreamException xse) {
+                //ignore
+            } finally {
+                try {
+                    xwriter.flush();
+                    xwriter.close();
+                } catch (XMLStreamException xse2) {
+                    //ignore
+                }
+            }
+
+            String result = swriter.toString();
+            if (result.length() < limit || limit == -1) {
+                builder.append(result);
+            } else {
+                builder.append(result.substring(0, limit));
+            }
+
+        } else {
+            if (StringUtils.isEmpty(encoding)) {
+                cos.writeCacheTo(builder, limit);
+            } else {
+                cos.writeCacheTo(builder, encoding, limit);
+            }
+        }
+    }
+    protected void writePayload(StringBuilder builder,
+                                StringWriter stringWriter,
+                                String contentType)
+        throws Exception {
+        if (isPrettyLogging()
+            && contentType != null
+            && contentType.contains("xml")
+            && stringWriter.getBuffer().length() > 0) {
+            try {
+                writePrettyPayload(builder, stringWriter, contentType);
+                return;
+            } catch (Exception ex) {
+                // log it as is
+            }
+        }
+        StringBuffer buffer = stringWriter.getBuffer();
+        if (buffer.length() > limit) {
+            builder.append(buffer.subSequence(0, limit));
+        } else {
+            builder.append(buffer);
+        }
+    }
+    protected void writePrettyPayload(StringBuilder builder,
+                                StringWriter stringWriter,
+                                String contentType)
+        throws Exception {
+        // Just transform the XML message when the cos has content
+
+        StringWriter swriter = new StringWriter();
+        XMLStreamWriter xwriter = StaxUtils.createXMLStreamWriter(swriter);
+        xwriter = new PrettyPrintXMLStreamWriter(xwriter, 2);
+        StaxUtils.copy(new StreamSource(new StringReader(stringWriter.getBuffer().toString())), xwriter);
+        xwriter.close();
+
+        String result = swriter.toString();
+        if (result.length() < limit || limit == -1) {
+            builder.append(swriter.toString());
+        } else {
+            builder.append(swriter.toString().substring(0, limit));
+        }
+    }
+
+
+    /**
+     * Transform the string before display. The implementation in this class
+     * does nothing. Override this method if you wish to change the contents of the
+     * logged message before it is delivered to the output.
+     * For example, you can use this to mask out sensitive information.
+     * @param originalLogString the raw log message.
+     * @return transformed data
+     */
+    protected String transform(String originalLogString) {
+        return originalLogString;
+    }
+
+    protected void log(Logger logger, String message) {
+        message = transform(message);
+        if (writer != null) {
+            writer.println(message);
+            // Flushing the writer to make sure the message is written
+            writer.flush();
+        } else if (logger.isLoggable(Level.INFO)) {
+            LogRecord lr = new LogRecord(Level.INFO, message);
+            lr.setSourceClassName(logger.getName());
+            lr.setSourceMethodName(null);
+            lr.setLoggerName(logger.getName());
+            logger.log(lr);
+        }
+    }
+    public void setShowBinaryContent(boolean showBinaryContent) {
+        this.showBinaryContent = showBinaryContent;
+    }
+    public boolean isShowBinaryContent() {
+        return showBinaryContent;
+    }
+    protected boolean isBinaryContent(String contentType) {
+        return contentType != null && binaryContentMediaTypes.contains(contentType);
+    }
+    public boolean isShowMultipartContent() {
+        return showMultipartContent;
+    }
+    public void setShowMultipartContent(boolean showMultipartContent) {
+        this.showMultipartContent = showMultipartContent;
+    }
+    protected boolean isMultipartContent(String contentType) {
+        return contentType != null && contentType.startsWith(MULTIPART_CONTENT_MEDIA_TYPE);
+    }
+    public List<String> getBinaryContentMediaTypes() {
+        return binaryContentMediaTypes;
+    }
+    public void setBinaryContentMediaTypes(List<String> binaryContentMediaTypes) {
+        this.binaryContentMediaTypes = binaryContentMediaTypes;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/AnnotationInterceptors.java b/transform/src/patch/java/org/apache/cxf/interceptor/AnnotationInterceptors.java
new file mode 100644
index 0000000..8cc757e
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/AnnotationInterceptors.java
@@ -0,0 +1,151 @@
+/**
+ * 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.cxf.interceptor;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.i18n.BundleUtils;
+import org.apache.cxf.feature.Feature;
+import org.apache.cxf.feature.Features;
+import org.apache.cxf.message.Message;
+
+public class AnnotationInterceptors {
+
+    private static final ResourceBundle BUNDLE = BundleUtils.getBundle(AnnotationInterceptors.class);
+
+    private Class<?>[] clazzes;
+
+    public AnnotationInterceptors(Class<?> ... clz) {
+        clazzes = clz;
+    }
+
+    private <T> List<T> getAnnotationObject(Class<? extends Annotation> annotationClazz, Class<T> type) {
+
+        for (Class<?> cls : clazzes) {
+            Annotation annotation = cls.getAnnotation(annotationClazz);
+            if (annotation != null) {
+                return initializeAnnotationObjects(annotation, type);
+            }
+        }
+        return null;
+    }
+
+    private <T> List<T> initializeAnnotationObjects(Annotation annotation,
+                                             Class<T> type) {
+        List<T> list = new ArrayList<>();
+        for (String cn : getAnnotationObjectNames(annotation)) {
+            list.add(initializeAnnotationObject(cn, type));
+        }
+        for (Class<? extends T> cn : getAnnotationObjectClasses(annotation, type)) {
+            list.add(initializeAnnotationObject(cn));
+        }
+        return list;
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> Class<? extends T>[] getAnnotationObjectClasses(Annotation ann, Class<T> type) { //NOPMD
+        if (ann instanceof InFaultInterceptors) {
+            return (Class<? extends T>[])((InFaultInterceptors)ann).classes();
+        } else if (ann instanceof InInterceptors) {
+            return (Class<? extends T>[])((InInterceptors)ann).classes();
+        } else if (ann instanceof OutFaultInterceptors) {
+            return (Class<? extends T>[])((OutFaultInterceptors)ann).classes();
+        } else if (ann instanceof OutInterceptors) {
+            return (Class<? extends T>[])((OutInterceptors)ann).classes();
+        } else if (ann instanceof Features) {
+            return (Class<? extends T>[])((Features)ann).classes();
+        }
+        throw new UnsupportedOperationException("Doesn't support the annotation: " + ann);
+    }
+
+    private String[] getAnnotationObjectNames(Annotation ann) {
+        if (ann instanceof InFaultInterceptors) {
+            return ((InFaultInterceptors)ann).interceptors();
+        } else if (ann instanceof InInterceptors) {
+            return ((InInterceptors)ann).interceptors();
+        } else if (ann instanceof OutFaultInterceptors) {
+            return ((OutFaultInterceptors)ann).interceptors();
+        } else if (ann instanceof OutInterceptors) {
+            return ((OutInterceptors)ann).interceptors();
+        } else if (ann instanceof Features) {
+            return ((Features)ann).features();
+        }
+
+        throw new UnsupportedOperationException("Doesn't support the annotation: " + ann);
+    }
+
+    private <T> T initializeAnnotationObject(String annObjectName, Class<T> type) {
+        try {
+            final Object object = ClassLoaderUtils.loadClass(annObjectName, this.getClass()).newInstance();
+            return type.cast(object);
+        } catch (Throwable e) {
+            throw new Fault(new org.apache.cxf.common.i18n.Message(
+                                            "COULD_NOT_CREATE_ANNOTATION_OBJECT",
+                                            BUNDLE, annObjectName), e);
+        }
+    }
+    private <T> T initializeAnnotationObject(Class<T> type) {
+        try {
+            return type.cast(type.newInstance());
+        } catch (Throwable e) {
+            throw new Fault(new org.apache.cxf.common.i18n.Message(
+                                            "COULD_NOT_CREATE_ANNOTATION_OBJECT",
+                                            BUNDLE, type.getName()), e);
+        }
+    }
+
+    private List<Interceptor<? extends Message>> getAnnotationInterceptorList(Class<? extends Annotation> t) {
+        @SuppressWarnings("rawtypes")
+        List<Interceptor> i = getAnnotationObject(t, Interceptor.class);
+        if (i == null) {
+            return null;
+        }
+        List<Interceptor<? extends Message>> m = new ArrayList<>();
+        for (Interceptor<?> i2 : i) {
+            m.add(i2);
+        }
+        return m;
+    }
+
+    public List<Interceptor<? extends Message>> getInFaultInterceptors() {
+        return getAnnotationInterceptorList(InFaultInterceptors.class);
+    }
+
+    public List<Interceptor<? extends Message>> getInInterceptors() {
+        return getAnnotationInterceptorList(InInterceptors.class);
+    }
+
+    public List<Interceptor<? extends Message>> getOutFaultInterceptors() {
+        return getAnnotationInterceptorList(OutFaultInterceptors.class);
+    }
+
+    public List<Interceptor<? extends Message>> getOutInterceptors() {
+        return getAnnotationInterceptorList(OutInterceptors.class);
+    }
+
+    public List<Feature> getFeatures() {
+        return getAnnotationObject(Features.class, Feature.class);
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/AttachmentInInterceptor.java b/transform/src/patch/java/org/apache/cxf/interceptor/AttachmentInInterceptor.java
new file mode 100644
index 0000000..0a56be1
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/AttachmentInInterceptor.java
@@ -0,0 +1,72 @@
+/**
+ * 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.cxf.interceptor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.cxf.attachment.AttachmentDeserializer;
+import org.apache.cxf.attachment.AttachmentUtil;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+
+public class AttachmentInInterceptor extends AbstractPhaseInterceptor<Message> {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(AttachmentInInterceptor.class);
+
+    private static final List<String> TYPES = Collections.singletonList("multipart/related");
+
+    public AttachmentInInterceptor() {
+        super(Phase.RECEIVE);
+    }
+
+    public void handleMessage(Message message) {
+        if (isGET(message)) {
+            LOG.fine("AttachmentInInterceptor skipped in HTTP GET method");
+            return;
+        }
+        if (message.getContent(InputStream.class) == null) {
+            return;
+        }
+
+        String contentType = (String) message.get(Message.CONTENT_TYPE);
+        if (AttachmentUtil.isTypeSupported(contentType, getSupportedTypes())) {
+            AttachmentDeserializer ad = new AttachmentDeserializer(message, getSupportedTypes());
+            try {
+                ad.initializeAttachments();
+            } catch (IOException e) {
+                throw new Fault(e);
+            }
+        }
+    }
+
+    @Override
+    public void handleFault(Message messageParam) {
+    }
+
+    protected List<String> getSupportedTypes() {
+        return TYPES;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/ClientOutFaultObserver.java b/transform/src/patch/java/org/apache/cxf/interceptor/ClientOutFaultObserver.java
new file mode 100644
index 0000000..341b3b0
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/ClientOutFaultObserver.java
@@ -0,0 +1,68 @@
+/**
+ * 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.cxf.interceptor;
+
+import java.util.Map;
+import java.util.SortedSet;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.endpoint.ClientCallback;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.phase.PhaseManager;
+
+public class ClientOutFaultObserver extends AbstractFaultChainInitiatorObserver {
+
+    public ClientOutFaultObserver(Bus bus) {
+        super(bus);
+    }
+
+    @Override
+    protected SortedSet<Phase> getPhases() {
+        return getBus().getExtension(PhaseManager.class).getOutPhases();
+    }
+
+    /**
+     * override the super class method
+     */
+    @Override
+    public void onMessage(Message m) {
+        if (m.get(Message.INBOUND_MESSAGE).equals(Boolean.TRUE)) {
+            //it's outbound fault observer so only take care of outbound fault
+            return;
+        }
+        Exception ex = m.getContent(Exception.class);
+        // remove callback so that it won't be invoked twice
+        ClientCallback callback = m.getExchange().remove(ClientCallback.class);
+
+        if (callback != null) {
+            Map<String, Object> resCtx = CastUtils.cast((Map<?, ?>) m.getExchange().getOutMessage().get(
+                    Message.INVOCATION_CONTEXT));
+            resCtx = CastUtils.cast((Map<?, ?>) resCtx.get(Client.RESPONSE_CONTEXT));
+            callback.handleException(resCtx, ex);
+        }
+    }
+
+    protected boolean isOutboundObserver() {
+        return true;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/InFaultChainInitiatorObserver.java b/transform/src/patch/java/org/apache/cxf/interceptor/InFaultChainInitiatorObserver.java
new file mode 100644
index 0000000..fd35182
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/InFaultChainInitiatorObserver.java
@@ -0,0 +1,84 @@
+/**
+ * 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.cxf.interceptor;
+
+import java.util.Collection;
+import java.util.SortedSet;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.apache.cxf.phase.PhaseManager;
+
+public class InFaultChainInitiatorObserver extends AbstractFaultChainInitiatorObserver {
+
+    public InFaultChainInitiatorObserver(Bus bus) {
+        super(bus);
+    }
+
+    @Override
+    protected void initializeInterceptors(Exchange ex, PhaseInterceptorChain chain) {
+        Endpoint e = ex.getEndpoint();
+        Client c = ex.get(Client.class);
+        InterceptorProvider ip = ex.get(InterceptorProvider.class);
+
+        chain.add(getBus().getInFaultInterceptors());
+        if (c != null) {
+            chain.add(c.getInFaultInterceptors());
+        } else if (ip != null) {
+            chain.add(ip.getInFaultInterceptors());
+        }
+        chain.add(e.getService().getInFaultInterceptors());
+        chain.add(e.getInFaultInterceptors());
+        chain.add(e.getBinding().getInFaultInterceptors());
+        if (e.getService().getDataBinding() instanceof InterceptorProvider) {
+            chain.add(((InterceptorProvider)e.getService().getDataBinding()).getInFaultInterceptors());
+        }
+
+        addToChain(chain, ex.getInFaultMessage());
+        addToChain(chain, ex.getOutMessage());
+    }
+    private void addToChain(PhaseInterceptorChain chain, Message m) {
+        Collection<InterceptorProvider> providers
+            = CastUtils.cast((Collection<?>)m.get(Message.INTERCEPTOR_PROVIDERS));
+        if (providers != null) {
+            for (InterceptorProvider p : providers) {
+                chain.add(p.getInFaultInterceptors());
+            }
+        }
+        Collection<Interceptor<? extends Message>> is
+            = CastUtils.cast((Collection<?>)m.get(Message.FAULT_IN_INTERCEPTORS));
+        if (is != null) {
+            chain.add(is);
+        }
+    }
+
+    protected SortedSet<Phase> getPhases() {
+        return getBus().getExtension(PhaseManager.class).getInPhases();
+    }
+
+    protected boolean isOutboundObserver() {
+        return false;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/InterceptorChain.java b/transform/src/patch/java/org/apache/cxf/interceptor/InterceptorChain.java
new file mode 100644
index 0000000..da5deba
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/InterceptorChain.java
@@ -0,0 +1,109 @@
+/**
+ * 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.cxf.interceptor;
+
+import java.util.Collection;
+import java.util.ListIterator;
+
+import org.apache.cxf.message.Message;
+import org.apache.cxf.transport.MessageObserver;
+
+/**
+ * Base interface for all interceptor chains.  An interceptor chain is an
+ * ordered list of interceptors associated with one portion of the message
+ * processing pipeline. Interceptor chains are defined for a client's request
+ * processing, response processing, and incoming SOAP fault processing. Interceptor
+ * chains are defined for a service's request processing, response processing, and
+ * outgoing SOAP fault processing.
+ */
+public interface InterceptorChain extends Iterable<Interceptor<? extends Message>> {
+
+    enum State {
+        PAUSED,
+        SUSPENDED,
+        EXECUTING,
+        COMPLETE,
+        ABORTED,
+    }
+
+    String STARTING_AFTER_INTERCEPTOR_ID = "starting_after_interceptor_id";
+    String STARTING_AT_INTERCEPTOR_ID = "starting_at_interceptor_id";
+
+    /**
+     * Adds a single interceptor to the interceptor chain.
+     *
+     * @param i the interceptor to add
+     */
+    void add(Interceptor<? extends Message> i);
+
+    /**
+     * Adds multiple interceptors to the interceptor chain.
+     * @param i the interceptors to add to the chain
+     */
+    void add(Collection<Interceptor<? extends Message>> i);
+
+    void remove(Interceptor<? extends Message> i);
+
+    boolean doIntercept(Message message);
+
+    boolean doInterceptStartingAfter(Message message, String startingAfterInterceptorID);
+
+    boolean doInterceptStartingAt(Message message, String startingAtInterceptorID);
+
+    /**
+     * Pauses the current chain.   When the stack unwinds, the chain will just
+     * return from the doIntercept method normally.
+     */
+    void pause();
+
+    /**
+     * Suspends the current chain.  When the stack unwinds, the chain back up
+     * the iterator by one (so on resume, the interceptor that called pause will
+     * be re-entered) and then throw a SuspendedInvocationException to the caller
+     */
+    void suspend();
+
+    /**
+     * Resumes the chain.  The chain will use the current thread to continue processing
+     * the last message that was passed into doIntercept
+     */
+    void resume();
+
+    /**
+     * If the chain is marked as paused, this will JUST mark the chain as
+     * in the EXECUTING phase.   This is useful if an interceptor pauses the chain,
+     * but then immediately decides it should not have done that.   It can unpause
+     * the chain and return normally and the normal processing will continue.
+     */
+    void unpause();
+
+
+    void reset();
+
+    State getState();
+
+    ListIterator<Interceptor<? extends Message>> getIterator();
+
+    MessageObserver getFaultObserver();
+
+    void setFaultObserver(MessageObserver i);
+
+    void abort();
+}
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/LoggingMessage.java b/transform/src/patch/java/org/apache/cxf/interceptor/LoggingMessage.java
new file mode 100644
index 0000000..661e3db
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/LoggingMessage.java
@@ -0,0 +1,133 @@
+/**
+ * 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.cxf.interceptor;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @deprecated use the logging module rt/features/logging instead
+ */
+@Deprecated
+public final class LoggingMessage {
+    public static final String ID_KEY = LoggingMessage.class.getName() + ".ID";
+    private static final AtomicInteger ID = new AtomicInteger();
+
+    private final String heading;
+    private final StringBuilder address;
+    private final StringBuilder contentType;
+    private final StringBuilder encoding;
+    private final StringBuilder httpMethod;
+    private final StringBuilder header;
+    private final StringBuilder message;
+    private final StringBuilder payload;
+    private final StringBuilder responseCode;
+    private final String id;
+
+
+    public LoggingMessage(String h, String i) {
+        heading = h;
+        id = i;
+
+        contentType = new StringBuilder();
+        address = new StringBuilder();
+        encoding = new StringBuilder();
+        httpMethod = new StringBuilder();
+        header = new StringBuilder();
+        message = new StringBuilder();
+        payload = new StringBuilder();
+        responseCode = new StringBuilder();
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public static String nextId() {
+        return Integer.toString(ID.incrementAndGet());
+    }
+
+
+    public StringBuilder getAddress() {
+        return address;
+    }
+
+    public StringBuilder getEncoding() {
+        return encoding;
+    }
+
+    public StringBuilder getHeader() {
+        return header;
+    }
+
+    public StringBuilder getHttpMethod() {
+        return httpMethod;
+    }
+
+    public StringBuilder getContentType() {
+        return contentType;
+    }
+
+    public StringBuilder getMessage() {
+        return message;
+    }
+
+    public StringBuilder getPayload() {
+        return payload;
+    }
+
+    public StringBuilder getResponseCode() {
+        return responseCode;
+    }
+
+    public String toString() {
+        StringBuilder buffer = new StringBuilder(128);
+        buffer.append(heading);
+        buffer.append("\nID: ").append(id);
+        if (address.length() > 0) {
+            buffer.append("\nAddress: ");
+            buffer.append(address);
+        }
+        if (responseCode.length() > 0) {
+            buffer.append("\nResponse-Code: ");
+            buffer.append(responseCode);
+        }
+        if (encoding.length() > 0) {
+            buffer.append("\nEncoding: ");
+            buffer.append(encoding);
+        }
+        if (httpMethod.length() > 0) {
+            buffer.append("\nHttp-Method: ");
+            buffer.append(httpMethod);
+        }
+        buffer.append("\nContent-Type: ");
+        buffer.append(contentType);
+        buffer.append("\nHeaders: ");
+        buffer.append(header);
+        if (message.length() > 0) {
+            buffer.append("\nMessages: ");
+            buffer.append(message);
+        }
+        if (payload.length() > 0) {
+            buffer.append("\nPayload: ");
+            buffer.append(payload);
+        }
+        buffer.append("\n--------------------------------------");
+        return buffer.toString();
+    }
+}
\ No newline at end of file
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/OneWayProcessorInterceptor.java b/transform/src/patch/java/org/apache/cxf/interceptor/OneWayProcessorInterceptor.java
new file mode 100644
index 0000000..b140601
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/OneWayProcessorInterceptor.java
@@ -0,0 +1,177 @@
+/**
+ * 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.cxf.interceptor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.io.DelegatingInputStream;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.transport.Conduit;
+import org.apache.cxf.workqueue.WorkQueueManager;
+
+
+/**
+ *
+ */
+public class OneWayProcessorInterceptor extends AbstractPhaseInterceptor<Message> {
+    public static final String USE_ORIGINAL_THREAD
+        = OneWayProcessorInterceptor.class.getName() + ".USE_ORIGINAL_THREAD";
+    private static final Logger LOG = LogUtils.getL7dLogger(OneWayProcessorInterceptor.class);
+
+    public OneWayProcessorInterceptor() {
+        super(Phase.PRE_LOGICAL);
+    }
+    public OneWayProcessorInterceptor(String phase) {
+        super(phase);
+    }
+    
+    @Override
+    public void handleFault(Message message) {
+        if (message.getExchange().isOneWay()
+            && !isRequestor(message)) {
+            //in a one way, if an exception is thrown, the stream needs to be closed
+            InputStream in = message.getContent(InputStream.class);
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    //ignore
+                }
+            }
+
+        }
+    }
+    public void handleMessage(Message message) {
+
+        if (message.getExchange().isOneWay()
+            && !isRequestor(message)
+            && message.get(OneWayProcessorInterceptor.class) == null
+            && message.getExchange().get(Executor.class) == null) {
+            //one way on server side, fork the rest of this chain onto the
+            //workqueue, call the Outgoing chain directly.
+
+            message.put(OneWayProcessorInterceptor.class, this);
+            final InterceptorChain chain = message.getInterceptorChain();
+
+            boolean robust =
+                MessageUtils.getContextualBoolean(message, Message.ROBUST_ONEWAY, false);
+
+            boolean useOriginalThread =
+                MessageUtils.getContextualBoolean(message, USE_ORIGINAL_THREAD, false);
+
+            if (!useOriginalThread && !robust) {
+                //need to suck in all the data from the input stream as
+                //the transport might discard any data on the stream when this
+                //thread unwinds or when the empty response is sent back
+                DelegatingInputStream in = message.getContent(DelegatingInputStream.class);
+                if (in != null) {
+                    in.cacheInput();
+                }
+            }
+
+            if (robust) {
+                // continue to invoke the chain
+                chain.pause();
+                chain.resume();
+                if (message.getContent(Exception.class) != null) {
+                    // CXF-5629 fault has been delivered alread in resume()
+                    return;
+                }
+            }
+
+            try {
+                Message partial = createMessage(message.getExchange());
+                partial.remove(Message.CONTENT_TYPE);
+                partial.setExchange(message.getExchange());
+                Conduit conduit = message.getExchange().getDestination()
+                    .getBackChannel(message);
+                if (conduit != null) {
+                    message.getExchange().setInMessage(null);
+                    //for a one-way, the back channel could be
+                    //null if it knows it cannot send anything.
+                    conduit.prepare(partial);
+                    conduit.close(partial);
+                    message.getExchange().setInMessage(message);
+                }
+            } catch (IOException e) {
+                //IGNORE
+            }
+
+            if (!useOriginalThread && !robust) {
+                chain.pause();
+                try {
+                    final Object lock = new Object();
+                    synchronized (lock) {
+                        message.getExchange().getBus().getExtension(WorkQueueManager.class)
+                            .getAutomaticWorkQueue().execute(new Runnable() {
+                                public void run() {
+                                    synchronized (lock) {
+                                        lock.notifyAll();
+                                    }
+                                    chain.resume();
+                                }
+                            });
+                        //wait a few milliseconds for the background thread to start processing
+                        //Mostly just to make an attempt at keeping the ordering of the
+                        //messages coming in from a client.  Not guaranteed though.
+                        lock.wait(20L);
+                    }
+                } catch (RejectedExecutionException e) {
+                    LOG.warning(
+                        "Executor queue is full, run the oneway invocation task in caller thread."
+                        + "  Users can specify a larger executor queue to avoid this.");
+                    // only block the thread if the prop is unset or set to false, otherwise let it go
+                    if (!MessageUtils.getContextualBoolean(message,
+                            "org.apache.cxf.oneway.rejected_execution_exception", false)) {
+                        //the executor queue is full, so run the task in the caller thread
+                        chain.unpause();
+                    }
+
+                } catch (InterruptedException e) {
+                    //ignore - likely a busy work queue so we'll just let the one-way go
+                }
+            }
+        }
+    }
+
+    private static Message createMessage(Exchange exchange) {
+        Endpoint ep = exchange.getEndpoint();
+        Message msg = null;
+        if (ep != null) {
+            msg = new MessageImpl();
+            msg.setExchange(exchange);
+            msg = ep.getBinding().createMessage(msg);
+        }
+        return msg;
+    }
+
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/OutFaultChainInitiatorObserver.java b/transform/src/patch/java/org/apache/cxf/interceptor/OutFaultChainInitiatorObserver.java
new file mode 100644
index 0000000..a00e403
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/OutFaultChainInitiatorObserver.java
@@ -0,0 +1,84 @@
+/**
+ * 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.cxf.interceptor;
+
+import java.util.Collection;
+import java.util.SortedSet;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.apache.cxf.phase.PhaseManager;
+
+public class OutFaultChainInitiatorObserver extends AbstractFaultChainInitiatorObserver {
+
+    public OutFaultChainInitiatorObserver(Bus bus) {
+        super(bus);
+    }
+
+    @Override
+    protected void initializeInterceptors(Exchange ex, PhaseInterceptorChain chain) {
+        Endpoint e = ex.getEndpoint();
+        Client c = ex.get(Client.class);
+
+        chain.add(getBus().getOutFaultInterceptors());
+        if (c != null) {
+            chain.add(c.getOutFaultInterceptors());
+        }
+        chain.add(e.getService().getOutFaultInterceptors());
+        chain.add(e.getOutFaultInterceptors());
+        chain.add(e.getBinding().getOutFaultInterceptors());
+        if (e.getService().getDataBinding() instanceof InterceptorProvider) {
+            chain.add(((InterceptorProvider)e.getService().getDataBinding()).getOutFaultInterceptors());
+        }
+
+        addToChain(chain, ex.getInMessage());
+        addToChain(chain, ex.getOutFaultMessage());
+    }
+    private void addToChain(PhaseInterceptorChain chain, Message m) {
+        Collection<InterceptorProvider> providers
+            = CastUtils.cast((Collection<?>)m.get(Message.INTERCEPTOR_PROVIDERS));
+        if (providers != null) {
+            for (InterceptorProvider p : providers) {
+                chain.add(p.getOutFaultInterceptors());
+            }
+        }
+        Collection<Interceptor<? extends Message>> is
+            = CastUtils.cast((Collection<?>)m.get(Message.FAULT_OUT_INTERCEPTORS));
+        if (is != null) {
+            chain.add(is);
+        }
+        if (m.getDestination() instanceof InterceptorProvider) {
+            chain.add(((InterceptorProvider)m.getDestination()).getOutFaultInterceptors());
+        }
+    }
+
+    protected SortedSet<Phase> getPhases() {
+        return getBus().getExtension(PhaseManager.class).getOutPhases();
+    }
+
+    protected boolean isOutboundObserver() {
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java b/transform/src/patch/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java
new file mode 100644
index 0000000..9b712f3
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java
@@ -0,0 +1,188 @@
+/**
+ * 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.cxf.interceptor.security;
+
+
+import java.lang.reflect.Method;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.security.GroupPrincipal;
+import org.apache.cxf.common.util.ReflectionUtil;
+import org.apache.cxf.security.LoginSecurityContext;
+
+/**
+ * SecurityContext which implements isUserInRole using the
+ * following approach : skip the first Subject principal, and then checks
+ * Groups the principal is a member of
+ */
+public class DefaultSecurityContext implements LoginSecurityContext {
+    private static final Logger LOG = LogUtils.getL7dLogger(DefaultSecurityContext.class);
+    private static Class<?> javaGroup; 
+    private static Class<?> karafGroup;
+    
+    private Principal p;
+    private Subject subject;
+
+    static {
+        try {
+            javaGroup = Class.forName("java.security.acl.Group");
+        } catch (Exception e) {
+            javaGroup = null;
+        }
+        try {
+            karafGroup = Class.forName("org.apache.karaf.jaas.boot.principal.Group");
+        } catch (Exception e) {
+            karafGroup = null;
+        }
+    }
+    
+    public DefaultSecurityContext(Subject subject) {
+        this.p = findPrincipal(null, subject);
+        this.subject = subject;
+    }
+
+    public DefaultSecurityContext(String principalName, Subject subject) {
+        this.p = findPrincipal(principalName, subject);
+        this.subject = subject;
+    }
+
+    public DefaultSecurityContext(Principal p, Subject subject) {
+        this.p = p;
+        this.subject = subject;
+        if (p == null) {
+            this.p = findPrincipal(null, subject);
+        }
+    }
+
+    private static Principal findPrincipal(String principalName, Subject subject) {
+        if (subject == null) {
+            return null;
+        }
+
+        for (Principal principal : subject.getPrincipals()) {
+            if (!isGroupPrincipal(principal)
+                && (principalName == null || principal.getName().equals(principalName))) {
+                return principal;
+            }
+        }
+
+        // No match for the principalName. Just return first non-Group Principal
+        if (principalName != null) {
+            for (Principal principal : subject.getPrincipals()) {
+                if (!isGroupPrincipal(principal)) {
+                    return principal;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public Principal getUserPrincipal() {
+        return p;
+    }
+
+    public boolean isUserInRole(String role) {
+        if (subject != null) {
+            for (Principal principal : subject.getPrincipals()) {
+                if (isGroupPrincipal(principal) 
+                    && checkGroup(principal, role)) {
+                    return true;
+                } else if (p != principal
+                           && role.equals(principal.getName())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+
+    protected boolean checkGroup(Principal principal, String role) {
+        if (principal.getName().equals(role)) {
+            return true;
+        }
+
+        Enumeration<? extends Principal> members;
+        try {
+            Method m = ReflectionUtil.getMethod(principal.getClass(), "members");
+            m.setAccessible(true);
+            @SuppressWarnings("unchecked")
+            Enumeration<? extends Principal> ms = (Enumeration<? extends Principal>)m.invoke(principal);
+            members = ms;
+        } catch (Exception e) {
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Unable to invoke memebers in " + principal.getName() + ":" + e.getMessage());
+            }
+            return false;
+        }
+        
+        while (members.hasMoreElements()) {
+            // this might be a plain role but could represent a group consisting of other groups/roles
+            Principal member = members.nextElement();
+            if (member.getName().equals(role)
+                || isGroupPrincipal(member) 
+                && checkGroup((GroupPrincipal)member, role)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    public Subject getSubject() {
+        return subject;
+    }
+
+    public Set<Principal> getUserRoles() {
+        Set<Principal> roles = new HashSet<>();
+        if (subject != null) {
+            for (Principal principal : subject.getPrincipals()) {
+                if (principal != p) {
+                    roles.add(principal);
+                }
+            }
+        }
+        return roles;
+    }
+    
+    
+    private static boolean instanceOfGroup(Object obj) { 
+        try {
+            return (javaGroup != null && javaGroup.isInstance(obj)) 
+                || (karafGroup != null && karafGroup.isInstance(obj));
+        } catch (Exception ex) {
+            return false;
+        }
+    }
+    
+    public static boolean isGroupPrincipal(Principal principal) {
+        return principal instanceof GroupPrincipal
+            || instanceOfGroup(principal);
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java b/transform/src/patch/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java
new file mode 100644
index 0000000..3363c20
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java
@@ -0,0 +1,233 @@
+/**
+ * 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.cxf.interceptor.security;
+
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.interceptor.InterceptorChain;
+import org.apache.cxf.interceptor.security.callback.CallbackHandlerProvider;
+import org.apache.cxf.interceptor.security.callback.CallbackHandlerProviderAuthPol;
+import org.apache.cxf.interceptor.security.callback.CallbackHandlerProviderUsernameToken;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.security.SecurityContext;
+
+public class JAASLoginInterceptor extends AbstractPhaseInterceptor<Message> {
+    public static final String ROLE_CLASSIFIER_PREFIX = "prefix";
+    public static final String ROLE_CLASSIFIER_CLASS_NAME = "classname";
+
+    private static final Logger LOG = LogUtils.getL7dLogger(JAASLoginInterceptor.class);
+
+    private String contextName = "";
+    private Configuration loginConfig;
+    private String roleClassifier;
+    private String roleClassifierType = ROLE_CLASSIFIER_PREFIX;
+    private boolean reportFault;
+    private boolean useDoAs = true;
+    private List<CallbackHandlerProvider> callbackHandlerProviders;
+    private boolean allowAnonymous = true;
+    private boolean allowNamedPrincipals;
+
+    public JAASLoginInterceptor() {
+        this(Phase.UNMARSHAL);
+    }
+
+    public JAASLoginInterceptor(String phase) {
+        super(phase);
+        this.callbackHandlerProviders = new ArrayList<>();
+        this.callbackHandlerProviders.add(new CallbackHandlerProviderAuthPol());
+        this.callbackHandlerProviders.add(new CallbackHandlerProviderUsernameToken());
+    }
+
+    public void setContextName(String name) {
+        contextName = name;
+    }
+
+    public String getContextName() {
+        return contextName;
+    }
+
+    /**
+     * @deprecated replaced by {@link #setRoleClassifier(String)}
+     * @param name
+     */
+    @Deprecated
+    public void setRolePrefix(String name) {
+        setRoleClassifier(name);
+    }
+
+    public void setRoleClassifier(String value) {
+        roleClassifier = value;
+    }
+
+    public String getRoleClassifier() {
+        return roleClassifier;
+    }
+
+    public void setRoleClassifierType(String value) {
+        if (!ROLE_CLASSIFIER_PREFIX.equals(value)
+            && !ROLE_CLASSIFIER_CLASS_NAME.equals(value)) {
+            throw new IllegalArgumentException("Unsupported role classifier");
+        }
+        roleClassifierType = value;
+    }
+
+    public String getRoleClassifierType() {
+        return roleClassifierType;
+    }
+
+    public void setReportFault(boolean reportFault) {
+        this.reportFault = reportFault;
+    }
+
+    public void setUseDoAs(boolean useDoAs) {
+        this.useDoAs = useDoAs;
+    }
+
+    private CallbackHandler getFirstCallbackHandler(Message message) {
+        for (CallbackHandlerProvider cbp : callbackHandlerProviders) {
+            CallbackHandler cbh = cbp.create(message);
+            if (cbh != null) {
+                return cbh;
+            }
+        }
+        return null;
+    }
+
+    public void handleMessage(final Message message) {
+        if (allowNamedPrincipals) {
+            SecurityContext sc = message.get(SecurityContext.class);
+            if (sc != null && sc.getUserPrincipal() != null
+                && sc.getUserPrincipal().getName() != null) {
+                return;
+            }
+        }
+
+        CallbackHandler handler = getFirstCallbackHandler(message);
+
+        if (handler == null && !allowAnonymous) {
+            throw new AuthenticationException("Authentication required but no authentication information was supplied");
+        }
+
+        try {
+            LoginContext ctx = new LoginContext(getContextName(), null, handler, loginConfig);
+            ctx.login();
+            Subject subject = ctx.getSubject();
+            String name = getUsername(handler);
+            message.put(SecurityContext.class, createSecurityContext(name, subject));
+
+            // Run the further chain in the context of this subject.
+            // This allows other code to retrieve the subject using pure JAAS
+            if (useDoAs) {
+                Subject.doAs(subject, new PrivilegedAction<Void>() {
+
+                    @Override
+                    public Void run() {
+                        InterceptorChain chain = message.getInterceptorChain();
+                        if (chain != null) {
+                            message.put("suspend.chain.on.current.interceptor", Boolean.TRUE);
+                            chain.doIntercept(message);
+                        }
+                        return null;
+                    }
+                });
+            }
+
+        } catch (LoginException ex) {
+            String errorMessage = "Authentication failed: " + ex.getMessage();
+            LOG.log(Level.FINE, errorMessage, ex);
+            if (reportFault) {
+                AuthenticationException aex = new AuthenticationException(errorMessage);
+                aex.initCause(ex);
+                throw aex;
+
+            }
+            throw new AuthenticationException("Authentication failed (details can be found in server log)");
+        }
+    }
+
+    private String getUsername(CallbackHandler handler) {
+        if (handler == null) {
+            return null;
+        }
+        try {
+            NameCallback usernameCallBack = new NameCallback("user");
+            handler.handle(new Callback[]{usernameCallBack });
+            return usernameCallBack.getName();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    protected CallbackHandler getCallbackHandler(String name, String password) {
+        return new NamePasswordCallbackHandler(name, password);
+    }
+
+    protected SecurityContext createSecurityContext(String name, Subject subject) {
+        if (getRoleClassifier() != null) {
+            return new RolePrefixSecurityContextImpl(subject, getRoleClassifier(),
+                                                     getRoleClassifierType());
+        }
+        return new DefaultSecurityContext(name, subject);
+    }
+
+    public Configuration getLoginConfig() {
+        return loginConfig;
+    }
+
+    public void setLoginConfig(Configuration loginConfig) {
+        this.loginConfig = loginConfig;
+    }
+
+    public List<CallbackHandlerProvider> getCallbackHandlerProviders() {
+        return callbackHandlerProviders;
+    }
+
+    public void setCallbackHandlerProviders(List<CallbackHandlerProvider> callbackHandlerProviders) {
+        this.callbackHandlerProviders.clear();
+        this.callbackHandlerProviders.addAll(callbackHandlerProviders);
+    }
+
+    public void addCallbackHandlerProviders(List<CallbackHandlerProvider> callbackHandlerProviders2) {
+        this.callbackHandlerProviders.addAll(callbackHandlerProviders2);
+    }
+
+    public void setAllowAnonymous(boolean allowAnonymous) {
+        this.allowAnonymous = allowAnonymous;
+    }
+
+    public void setAllowNamedPrincipals(boolean allowNamedPrincipals) {
+        this.allowNamedPrincipals = allowNamedPrincipals;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/internal/CXFAPINamespaceHandler.java b/transform/src/patch/java/org/apache/cxf/internal/CXFAPINamespaceHandler.java
new file mode 100644
index 0000000..e3d432d
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/internal/CXFAPINamespaceHandler.java
@@ -0,0 +1,127 @@
+/**
+ * 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.cxf.internal;
+
+import java.net.URL;
+import java.util.Set;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.apache.aries.blueprint.NamespaceHandler;
+import org.apache.aries.blueprint.Namespaces;
+import org.apache.aries.blueprint.ParserContext;
+import org.apache.aries.blueprint.mutable.MutableBeanMetadata;
+import org.apache.cxf.bus.blueprint.BusDefinitionParser;
+import org.apache.cxf.configuration.blueprint.SimpleBPBeanDefinitionParser;
+import org.apache.cxf.feature.FastInfosetFeature;
+import org.apache.cxf.workqueue.AutomaticWorkQueueImpl;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.Metadata;
+
+@Namespaces({"http://cxf.apache.org/blueprint/core",
+             "http://cxf.apache.org/configuration/beans",
+             "http://cxf.apache.org/configuration/parameterized-types",
+             "http://cxf.apache.org/configuration/security",
+             "http://schemas.xmlsoap.org/wsdl/",
+             "http://www.w3.org/2005/08/addressing",
+             "http://schemas.xmlsoap.org/ws/2004/08/addressing"})
+public class CXFAPINamespaceHandler implements NamespaceHandler {
+
+    public URL getSchemaLocation(String namespace) {
+        String location = null;
+
+        // when schema is being resolved for custom namespace elements, "namespace" is real namespace
+        // (from xmlns:prefix="<namespace>"
+        // but when namespace is <xsd:import>ed, aries/xerces uses systemID (schemaLocation)
+
+        if ("http://cxf.apache.org/configuration/beans".equals(namespace)
+                || "http://cxf.apache.org/schemas/configuration/cxf-beans.xsd".equals(namespace)) {
+            location = "schemas/configuration/cxf-beans.xsd";
+        } else if ("http://cxf.apache.org/configuration/parameterized-types".equals(namespace)
+                || "http://cxf.apache.org/schemas/configuration/parameterized-types.xsd".equals(namespace)) {
+            location = "schemas/configuration/parameterized-types.xsd";
+        } else if ("http://cxf.apache.org/configuration/security".equals(namespace)
+                || "http://cxf.apache.org/schemas/configuration/security.xsd".equals(namespace)) {
+            location = "schemas/configuration/security.xsd";
+        } else if ("http://schemas.xmlsoap.org/wsdl/".equals(namespace)
+                || "http://schemas.xmlsoap.org/wsdl/2003-02-11.xsd".equals(namespace)) {
+            location = "schemas/wsdl/wsdl.xsd";
+        } else if ("http://www.w3.org/2005/08/addressing".equals(namespace)
+                || "http://www.w3.org/2006/03/addressing/ws-addr.xsd".equals(namespace)) {
+            location = "schemas/wsdl/ws-addr.xsd";
+        } else if ("http://schemas.xmlsoap.org/ws/2004/08/addressing".equals(namespace)) {
+            location = "schemas/wsdl/addressing.xsd";
+        } else if ("http://cxf.apache.org/blueprint/core".equals(namespace)) {
+            location = "schemas/blueprint/core.xsd";
+        }
+        if (location != null) {
+            return getClass().getClassLoader().getResource(location);
+        }
+        return null;
+    }
+
+
+    @SuppressWarnings("deprecation")
+    public Metadata parse(Element element, ParserContext context) {
+        String s = element.getLocalName();
+        if ("bus".equals(s)) {
+            //parse bus
+            return new BusDefinitionParser().parse(element, context);
+        } else if ("logging".equals(s)) {
+            //logging feature
+            return new SimpleBPBeanDefinitionParser(org.apache.cxf.feature.LoggingFeature.class)
+                .parse(element, context);
+        } else if ("fastinfoset".equals(s)) {
+            //fastinfosetfeature
+            return new SimpleBPBeanDefinitionParser(FastInfosetFeature.class).parse(element, context);
+        } else if ("workqueue".equals(s)) {
+            return new SimpleBPBeanDefinitionParser(AutomaticWorkQueueImpl.class) {
+                
+                @Override
+                public String getId(Element element, ParserContext context) {
+                    String id = element.hasAttribute("id") ? element.getAttribute("id") : null;
+                    if (id == null) {
+                        id = "cxf.workqueue.";
+                        id += element.hasAttribute("name") ? element.getAttribute("name") : "def";
+                    }
+                    return id;
+                }
+
+                @Override
+                protected void processNameAttribute(Element element, ParserContext ctx,
+                                                    MutableBeanMetadata bean, String val) {
+                    bean.addProperty("name", createValue(ctx, val));
+                }
+            } .parse(element, context);
+        }
+        return null;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public Set<Class> getManagedClasses() {
+        //probably should have the various stuff in cxf-api in here?
+        return null;
+    }
+    public ComponentMetadata decorate(Node node, ComponentMetadata component, ParserContext context) {
+        return null;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/io/CacheAndWriteOutputStream.java b/transform/src/patch/java/org/apache/cxf/io/CacheAndWriteOutputStream.java
new file mode 100644
index 0000000..d89edb9
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/io/CacheAndWriteOutputStream.java
@@ -0,0 +1,96 @@
+/**
+ * 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.cxf.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * This outputstream implementation will both write to the outputstream
+ * that is specified and cache the data at the same time. This allows us
+ * to go back and retransmit the data at a later time if necessary.
+ *
+ */
+public class CacheAndWriteOutputStream extends CachedOutputStream {
+    OutputStream flowThroughStream;
+    long count;
+    long limit = Long.MAX_VALUE;
+    private boolean isClosed;
+
+    public CacheAndWriteOutputStream(OutputStream stream) {
+        super();
+        if (stream == null) {
+            throw new IllegalArgumentException("Stream may not be null");
+        }
+        flowThroughStream = stream;
+    }
+
+    public void setCacheLimit(long l) {
+        limit = l;
+    }
+
+    public void closeFlowthroughStream() throws IOException {
+        postClose();
+    }
+
+    protected void postClose() throws IOException {
+        if (!isClosed) {
+            flowThroughStream.flush();
+            flowThroughStream.close();
+            isClosed = true;
+        }
+    }
+
+    public OutputStream getFlowThroughStream() {
+        return flowThroughStream;
+    }
+    
+    @Override
+    protected void onWrite() throws IOException {
+        // does nothing
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        flowThroughStream.write(b);
+        if (count <= limit) {
+            super.write(b);
+        }
+        count++;
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        flowThroughStream.write(b, off, len);
+        if (count <= limit) {
+            super.write(b, off, len);
+        }
+        count += len;
+    }
+
+    @Override
+    public void write(byte[] b) throws IOException {
+        flowThroughStream.write(b);
+        if (count <= limit) {
+            super.write(b);
+        }
+        count += b.length;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/io/CachedWriter.java b/transform/src/patch/java/org/apache/cxf/io/CachedWriter.java
new file mode 100644
index 0000000..0178563
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/io/CachedWriter.java
@@ -0,0 +1,665 @@
+/**
+ * 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.cxf.io;
+
+import java.io.BufferedOutputStream;
+import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.crypto.CipherInputStream;
+import javax.crypto.CipherOutputStream;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.util.SystemPropertyAction;
+import org.apache.cxf.helpers.FileUtils;
+import org.apache.cxf.helpers.IOUtils;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+public class CachedWriter extends Writer {
+    private static final File DEFAULT_TEMP_DIR;
+    private static int defaultThreshold;
+    private static long defaultMaxSize;
+    private static String defaultCipherTransformation;
+
+    static {
+
+        String s = SystemPropertyAction.getPropertyOrNull(CachedConstants.OUTPUT_DIRECTORY_SYS_PROP);
+        if (s == null) {
+            // lookup the deprecated property
+            s = SystemPropertyAction.getPropertyOrNull("org.apache.cxf.io.CachedWriter.OutputDirectory");
+        }
+        if (s != null) {
+            File f = new File(s);
+            if (f.exists() && f.isDirectory()) {
+                DEFAULT_TEMP_DIR = f;
+            } else {
+                DEFAULT_TEMP_DIR = null;
+            }
+        } else {
+            DEFAULT_TEMP_DIR = null;
+        }
+
+        setDefaultThreshold(-1);
+        setDefaultMaxSize(-1);
+        setDefaultCipherTransformation(null);
+    }
+
+    protected boolean outputLocked;
+    protected Writer currentStream;
+
+    private boolean cosClosed;
+    private long threshold = defaultThreshold;
+    private long maxSize = defaultMaxSize;
+    private File outputDir = DEFAULT_TEMP_DIR;
+    private String cipherTransformation = defaultCipherTransformation;
+
+    private long totalLength;
+
+    private boolean inmem;
+
+    private boolean tempFileFailed;
+    private File tempFile;
+    private boolean allowDeleteOfFile = true;
+    private CipherPair ciphers;
+
+    private List<CachedWriterCallback> callbacks;
+
+    private List<Object> streamList = new ArrayList<>();
+
+
+    static class LoadingCharArrayWriter extends CharArrayWriter {
+        LoadingCharArrayWriter() {
+            super(1024);
+        }
+        public char[] rawCharArray() {
+            return super.buf;
+        }
+    }
+
+
+    public CachedWriter() {
+        this(defaultThreshold);
+
+        inmem = true;
+    }
+
+    public CachedWriter(long threshold) {
+        this.threshold = threshold;
+        currentStream = new LoadingCharArrayWriter();
+        inmem = true;
+        readBusProperties();
+    }
+
+    private void readBusProperties() {
+        Bus b = BusFactory.getThreadDefaultBus(false);
+        if (b != null) {
+            String v = getBusProperty(b, CachedConstants.THRESHOLD_BUS_PROP, null);
+            if (v != null && threshold == defaultThreshold) {
+                threshold = Integer.parseInt(v);
+            }
+            v = getBusProperty(b, CachedConstants.MAX_SIZE_BUS_PROP, null);
+            if (v != null) {
+                maxSize = Integer.parseInt(v);
+            }
+            v = getBusProperty(b, CachedConstants.CIPHER_TRANSFORMATION_BUS_PROP, null);
+            if (v != null) {
+                cipherTransformation = v;
+            }
+            v = getBusProperty(b, CachedConstants.OUTPUT_DIRECTORY_BUS_PROP, null);
+            if (v != null) {
+                File f = new File(v);
+                if (f.exists() && f.isDirectory()) {
+                    outputDir = f;
+                }
+            }
+        }
+    }
+
+    private static String getBusProperty(Bus b, String key, String dflt) {
+        String v = (String)b.getProperty(key);
+        return v != null ? v : dflt;
+    }
+
+    public void holdTempFile() {
+        allowDeleteOfFile = false;
+    }
+    public void releaseTempFileHold() {
+        allowDeleteOfFile = true;
+    }
+
+    public void registerCallback(CachedWriterCallback cb) {
+        if (null == callbacks) {
+            callbacks = new ArrayList<>();
+        }
+        callbacks.add(cb);
+    }
+
+    public void deregisterCallback(CachedWriterCallback cb) {
+        if (null != callbacks) {
+            callbacks.remove(cb);
+        }
+    }
+
+    public List<CachedWriterCallback> getCallbacks() {
+        return callbacks == null ? null : Collections.unmodifiableList(callbacks);
+    }
+
+    /**
+     * Perform any actions required on stream flush (freeze headers, reset
+     * output stream ... etc.)
+     */
+    protected void doFlush() throws IOException {
+
+    }
+
+    public void flush() throws IOException {
+        if (!cosClosed) {
+            currentStream.flush();
+        }
+
+        if (null != callbacks) {
+            for (CachedWriterCallback cb : callbacks) {
+                cb.onFlush(this);
+            }
+        }
+        doFlush();
+    }
+
+    /**
+     * Perform any actions required on stream closure (handle response etc.)
+     */
+    protected void doClose() throws IOException {
+
+    }
+
+    /**
+     * Perform any actions required after stream closure (close the other related stream etc.)
+     */
+    protected void postClose() throws IOException {
+
+    }
+
+    /**
+     * Locks the output stream to prevent additional writes, but maintains
+     * a pointer to it so an InputStream can be obtained
+     * @throws IOException
+     */
+    public void lockOutputStream() throws IOException {
+        if (outputLocked) {
+            return;
+        }
+        currentStream.flush();
+        outputLocked = true;
+        if (null != callbacks) {
+            for (CachedWriterCallback cb : callbacks) {
+                cb.onClose(this);
+            }
+        }
+        doClose();
+        streamList.remove(currentStream);
+    }
+
+    public void close() throws IOException {
+        if (!cosClosed) {
+            currentStream.flush();
+        }
+        outputLocked = true;
+        if (null != callbacks) {
+            for (CachedWriterCallback cb : callbacks) {
+                cb.onClose(this);
+            }
+        }
+        doClose();
+        currentStream.close();
+        maybeDeleteTempFile(currentStream);
+        if (ciphers != null) {
+            ciphers.clean();
+        }
+        postClose();
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof CachedWriter) {
+            return currentStream.equals(((CachedWriter)obj).currentStream);
+        }
+        return currentStream.equals(obj);
+    }
+
+    /**
+     * Replace the original stream with the new one, optionally copying the content of the old one
+     * into the new one.
+     * When with Attachment, needs to replace the xml writer stream with the stream used by
+     * AttachmentSerializer or copy the cached output stream to the "real"
+     * output stream, i.e. onto the wire.
+     *
+     * @param out the new output stream
+     * @param copyOldContent flag indicating if the old content should be copied
+     * @throws IOException
+     */
+    public void resetOut(Writer out, boolean copyOldContent) throws IOException {
+        if (out == null) {
+            out = new LoadingCharArrayWriter();
+        }
+
+        if (currentStream instanceof CachedWriter) {
+            CachedWriter ac = (CachedWriter) currentStream;
+            Reader in = ac.getReader();
+            IOUtils.copyAndCloseInput(in, out);
+        } else {
+            if (inmem) {
+                if (currentStream instanceof LoadingCharArrayWriter) {
+                    LoadingCharArrayWriter byteOut = (LoadingCharArrayWriter) currentStream;
+                    if (copyOldContent && byteOut.size() > 0) {
+                        byteOut.writeTo(out);
+                    }
+                } else {
+                    throw new IOException("Unknown format of currentStream");
+                }
+            } else {
+                // read the file
+                currentStream.close();
+                if (copyOldContent) {
+                    InputStreamReader fin = createInputStreamReader(tempFile);
+                    IOUtils.copyAndCloseInput(fin, out);
+                }
+                streamList.remove(currentStream);
+                deleteTempFile();
+                inmem = true;
+            }
+        }
+        currentStream = out;
+        outputLocked = false;
+    }
+
+
+    public long size() {
+        return totalLength;
+    }
+
+    public char[] getChars() throws IOException {
+        flush();
+        if (inmem) {
+            if (currentStream instanceof LoadingCharArrayWriter) {
+                return ((LoadingCharArrayWriter)currentStream).toCharArray();
+            }
+            throw new IOException("Unknown format of currentStream");
+        }
+        // read the file
+        try (Reader fin = createInputStreamReader(tempFile)) {
+            CharArrayWriter out = new CharArrayWriter((int)tempFile.length());
+            char[] bytes = new char[1024];
+            int x = fin.read(bytes);
+            while (x != -1) {
+                out.write(bytes, 0, x);
+                x = fin.read(bytes);
+            }
+            return out.toCharArray();
+        }
+    }
+
+    public void writeCacheTo(Writer out) throws IOException {
+        flush();
+        if (inmem) {
+            if (currentStream instanceof LoadingCharArrayWriter) {
+                ((LoadingCharArrayWriter)currentStream).writeTo(out);
+            } else {
+                throw new IOException("Unknown format of currentStream");
+            }
+        } else {
+            // read the file
+            try (Reader fin = createInputStreamReader(tempFile)) {
+                char[] bytes = new char[1024];
+                int x = fin.read(bytes);
+                while (x != -1) {
+                    out.write(bytes, 0, x);
+                    x = fin.read(bytes);
+                }
+            }
+        }
+    }
+
+    public void writeCacheTo(StringBuilder out, long limit) throws IOException {
+        flush();
+        if (totalLength < limit
+            || limit == -1) {
+            writeCacheTo(out);
+            return;
+        }
+
+        long count = 0;
+        if (inmem) {
+            if (currentStream instanceof LoadingCharArrayWriter) {
+                LoadingCharArrayWriter s = (LoadingCharArrayWriter)currentStream;
+                out.append(s.rawCharArray(), 0, (int)limit);
+            } else {
+                throw new IOException("Unknown format of currentStream");
+            }
+        } else {
+            // read the file
+            try (Reader fin = createInputStreamReader(tempFile)) {
+                char[] bytes = new char[1024];
+                long x = fin.read(bytes);
+                while (x != -1) {
+                    if ((count + x) > limit) {
+                        x = limit - count;
+                    }
+                    out.append(bytes, 0, (int)x);
+                    count += x;
+
+                    if (count >= limit) {
+                        x = -1;
+                    } else {
+                        x = fin.read(bytes);
+                    }
+                }
+            }
+        }
+    }
+
+    public void writeCacheTo(StringBuilder out) throws IOException {
+        flush();
+        if (inmem) {
+            if (currentStream instanceof LoadingCharArrayWriter) {
+                LoadingCharArrayWriter lcaw = (LoadingCharArrayWriter)currentStream;
+                out.append(lcaw.rawCharArray(), 0, lcaw.size());
+            } else {
+                throw new IOException("Unknown format of currentStream");
+            }
+        } else {
+            // read the file
+            try (Reader r = createInputStreamReader(tempFile)) {
+                char[] chars = new char[1024];
+                int x = r.read(chars);
+                while (x != -1) {
+                    out.append(chars, 0, x);
+                    x = r.read(chars);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @return the underlying output stream
+     */
+    public Writer getOut() {
+        return currentStream;
+    }
+
+    public int hashCode() {
+        return currentStream.hashCode();
+    }
+
+    public String toString() {
+        StringBuilder builder = new StringBuilder().append('[')
+            .append(CachedWriter.class.getName())
+            .append(" Content: ");
+        try {
+            writeCacheTo(builder);
+        } catch (IOException e) {
+            //ignore
+        }
+        return builder.append(']').toString();
+    }
+
+    protected void onWrite() throws IOException {
+
+    }
+
+    private void enforceLimits() throws IOException {
+        if (maxSize > 0 && totalLength > maxSize) {
+            throw new CacheSizeExceededException();
+        }
+        if (inmem && totalLength > threshold && currentStream instanceof LoadingCharArrayWriter) {
+            createFileOutputStream();
+        }
+    }
+
+
+    public void write(char[] cbuf, int off, int len) throws IOException {
+        if (!outputLocked) {
+            onWrite();
+            this.totalLength += len;
+            enforceLimits();
+            currentStream.write(cbuf, off, len);
+        }
+    }
+
+    private void createFileOutputStream() throws IOException {
+        if (tempFileFailed) {
+            return;
+        }
+        LoadingCharArrayWriter bout = (LoadingCharArrayWriter)currentStream;
+        try {
+            if (outputDir == null) {
+                tempFile = FileUtils.createTempFile("cos", "tmp");
+            } else {
+                tempFile = FileUtils.createTempFile("cos", "tmp", outputDir, false);
+            }
+            currentStream = createOutputStreamWriter(tempFile);
+            bout.writeTo(currentStream);
+            inmem = false;
+            streamList.add(currentStream);
+        } catch (Exception ex) {
+            //Could be IOException or SecurityException or other issues.
+            //Don't care what, just keep it in memory.
+            tempFileFailed = true;
+            if (currentStream != bout) {
+                currentStream.close();
+            }
+            deleteTempFile();
+            inmem = true;
+            currentStream = bout;
+        }
+    }
+
+    public File getTempFile() {
+        return tempFile != null && tempFile.exists() ? tempFile : null;
+    }
+
+    public Reader getReader() throws IOException {
+        flush();
+        if (inmem) {
+            if (currentStream instanceof LoadingCharArrayWriter) {
+                LoadingCharArrayWriter lcaw = (LoadingCharArrayWriter)currentStream;
+                return new CharArrayReader(lcaw.rawCharArray(), 0, lcaw.size());
+            }
+            return null;
+        }
+        try {
+            InputStream fileInputStream = new FileInputStream(tempFile) {
+                boolean closed;
+                
+                @Override
+                public void close() throws IOException {
+                    if (!closed) {
+                        super.close();
+                        maybeDeleteTempFile(this);
+                    }
+                    closed = true;
+                }
+            };
+            streamList.add(fileInputStream);
+            if (cipherTransformation != null) {
+                fileInputStream = new CipherInputStream(fileInputStream, ciphers.getDecryptor()) {
+                    boolean closed;
+                    
+                    @Override
+                    public void close() throws IOException {
+                        if (!closed) {
+                            super.close();
+                            closed = true;
+                        }
+                    }
+                };
+            }
+            return new InputStreamReader(fileInputStream, StandardCharsets.UTF_8);
+        } catch (FileNotFoundException e) {
+            throw new IOException("Cached file was deleted, " + e.toString());
+        }
+    }
+
+    private synchronized void deleteTempFile() {
+        if (tempFile != null) {
+            File file = tempFile;
+            tempFile = null;
+            FileUtils.delete(file);
+        }
+    }
+    private void maybeDeleteTempFile(Object stream) {
+        streamList.remove(stream);
+        if (!inmem && tempFile != null && streamList.isEmpty() && allowDeleteOfFile) {
+            if (currentStream != null) {
+                try {
+                    currentStream.close();
+                    postClose();
+                } catch (Exception e) {
+                    //ignore
+                }
+            }
+            deleteTempFile();
+            currentStream = new LoadingCharArrayWriter();
+            inmem = true;
+        }
+    }
+
+    public void setOutputDir(File outputDir) throws IOException {
+        this.outputDir = outputDir;
+    }
+    public void setThreshold(long threshold) {
+        this.threshold = threshold;
+    }
+
+    public void setMaxSize(long maxSize) {
+        this.maxSize = maxSize;
+    }
+
+    public void setCipherTransformation(String cipherTransformation) {
+        this.cipherTransformation = cipherTransformation;
+    }
+
+    public static void setDefaultMaxSize(long l) {
+        if (l == -1) {
+            String s = System.getProperty(CachedConstants.MAX_SIZE_SYS_PROP);
+            if (s == null) {
+                // lookup the deprecated property
+                s = System.getProperty("org.apache.cxf.io.CachedWriter.MaxSize", "-1");
+            }
+            l = Long.parseLong(s);
+        }
+        defaultMaxSize = l;
+    }
+
+    public static void setDefaultThreshold(int i) {
+        if (i == -1) {
+            i = SystemPropertyAction.getInteger(CachedConstants.THRESHOLD_SYS_PROP, -1);
+            if (i == -1) {
+                // lookup the deprecated property
+                i = SystemPropertyAction.getInteger("org.apache.cxf.io.CachedWriter.Threshold", -1);
+            }
+            if (i <= 0) {
+                i = 64 * 1024;
+            }
+        }
+        defaultThreshold = i;
+
+    }
+
+    public static void setDefaultCipherTransformation(String n) {
+        if (n == null) {
+            n = SystemPropertyAction.getPropertyOrNull(CachedConstants.CIPHER_TRANSFORMATION_SYS_PROP);
+        }
+        defaultCipherTransformation = n;
+    }
+
+    private OutputStreamWriter createOutputStreamWriter(File file) throws IOException {
+        OutputStream out = new BufferedOutputStream(Files.newOutputStream(file.toPath()));
+        if (cipherTransformation != null) {
+            try {
+                if (ciphers == null) {
+                    ciphers = new CipherPair(cipherTransformation);
+                }
+            } catch (GeneralSecurityException e) {
+                out.close();
+                throw new IOException(e.getMessage(), e);
+            }
+            out = new CipherOutputStream(out, ciphers.getEncryptor()) {
+                
+                @Override
+                public void close() throws IOException {
+                    if (!cosClosed) {
+                        super.close();
+                        cosClosed = true;
+                    }
+                }
+            };
+        }
+        return new OutputStreamWriter(out, UTF_8) {
+            
+            @Override
+            public void close() throws IOException {
+                if (!cosClosed) {
+                    super.close();
+                    cosClosed = true;
+                }
+            }
+        };
+    }
+
+    private InputStreamReader createInputStreamReader(File file) throws IOException {
+        InputStream in = Files.newInputStream(file.toPath());
+        if (cipherTransformation != null) {
+            in = new CipherInputStream(in, ciphers.getDecryptor()) {
+                boolean closed;
+                
+                @Override
+                public void close() throws IOException {
+                    if (!closed) {
+                        super.close();
+                        closed = true;
+                    }
+                }
+            };
+        }
+        return new InputStreamReader(in, UTF_8);
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/io/ReaderInputStream.java b/transform/src/patch/java/org/apache/cxf/io/ReaderInputStream.java
new file mode 100644
index 0000000..e95ed88
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/io/ReaderInputStream.java
@@ -0,0 +1,294 @@
+/**
+ * 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.cxf.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * {@link InputStream} implementation that reads a character stream from a {@link Reader}
+ * and transforms it to a byte stream using a specified charset encoding. The stream
+ * is transformed using a {@link CharsetEncoder} object, guaranteeing that all charset
+ * encodings supported by the JRE are handled correctly. In particular for charsets such as
+ * UTF-16, the implementation ensures that one and only one byte order marker
+ * is produced.
+ * <p>
+ * Since in general it is not possible to predict the number of characters to be read from the
+ * {@link Reader} to satisfy a read request on the {@link ReaderInputStream}, all reads from
+ * the {@link Reader} are buffered. There is therefore no well defined correlation
+ * between the current position of the {@link Reader} and that of the {@link ReaderInputStream}.
+ * This also implies that in general there is no need to wrap the underlying {@link Reader}
+ * in a {@link java.io.BufferedReader}.
+ * <p>
+ * {@link ReaderInputStream} implements the inverse transformation of {@link java.io.InputStreamReader};
+ * in the following example, reading from <tt>in2</tt> would return the same byte
+ * sequence as reading from <tt>in</tt> (provided that the initial byte sequence is legal
+ * with respect to the charset encoding):
+ * <pre>
+ * InputStream in = ...
+ * Charset cs = ...
+ * InputStreamReader reader = new InputStreamReader(in, cs);
+ * ReaderInputStream in2 = new ReaderInputStream(reader, cs);</pre>
+ * {@link ReaderInputStream} implements the same transformation as {@link java.io.OutputStreamWriter},
+ * except that the control flow is reversed: both classes transform a character stream
+ * into a byte stream, but {@link java.io.OutputStreamWriter} pushes data to the underlying stream,
+ * while {@link ReaderInputStream} pulls it from the underlying stream.
+ * <p>
+ * Note that while there are use cases where there is no alternative to using
+ * this class, very often the need to use this class is an indication of a flaw
+ * in the design of the code. This class is typically used in situations where an existing
+ * API only accepts an {@link InputStream}, but where the most natural way to produce the data
+ * is as a character stream, i.e. by providing a {@link Reader} instance. An example of a situation
+ * where this problem may appear is when implementing the {@link javax.activation.DataSource}
+ * interface from the Java Activation Framework.
+ * <p>
+ * Given the fact that the {@link Reader} class doesn't provide any way to predict whether the next
+ * read operation will block or not, it is not possible to provide a meaningful
+ * implementation of the {@link InputStream#available()} method. A call to this method
+ * will always return 0. Also, this class doesn't support {@link InputStream#mark(int)}.
+ * <p>
+ * Instances of {@link ReaderInputStream} are not thread safe.
+ *
+ * @since 2.0
+ */
+public class ReaderInputStream extends InputStream {
+    private static final int DEFAULT_BUFFER_SIZE = 1024;
+
+    private final Reader reader;
+    private final CharsetEncoder encoder;
+
+    /**
+     * CharBuffer used as input for the decoder. It should be reasonably
+     * large as we read data from the underlying Reader into this buffer.
+     */
+    private final CharBuffer encoderIn;
+
+    /**
+     * ByteBuffer used as output for the decoder. This buffer can be small
+     * as it is only used to transfer data from the decoder to the
+     * buffer provided by the caller.
+     */
+    private final ByteBuffer encoderOut;
+
+    private CoderResult lastCoderResult;
+    private boolean endOfInput;
+
+    /**
+     * Construct a new {@link ReaderInputStream}.
+     *
+     * @param reader the target {@link Reader}
+     * @param encoder the charset encoder
+     * @since 2.1
+     */
+    public ReaderInputStream(Reader reader, CharsetEncoder encoder) {
+        this(reader, encoder, DEFAULT_BUFFER_SIZE);
+    }
+
+    /**
+     * Construct a new {@link ReaderInputStream}.
+     *
+     * @param reader the target {@link Reader}
+     * @param encoder the charset encoder
+     * @param bufferSize the size of the input buffer in number of characters
+     * @since 2.1
+     */
+    public ReaderInputStream(Reader reader, CharsetEncoder encoder, int bufferSize) {
+        this.reader = reader;
+        this.encoder = encoder;
+        this.encoderIn = CharBuffer.allocate(bufferSize);
+        encoderIn.flip();
+        this.encoderOut = ByteBuffer.allocate(128);
+        encoderOut.flip();
+    }
+
+    /**
+     * Construct a new {@link ReaderInputStream}.
+     *
+     * @param reader the target {@link Reader}
+     * @param charset the charset encoding
+     * @param bufferSize the size of the input buffer in number of characters
+     */
+    public ReaderInputStream(Reader reader, Charset charset, int bufferSize) {
+        this(reader,
+             charset.newEncoder()
+                    .onMalformedInput(CodingErrorAction.REPLACE)
+                    .onUnmappableCharacter(CodingErrorAction.REPLACE),
+             bufferSize);
+    }
+
+    /**
+     * Construct a new {@link ReaderInputStream} with a default input buffer size of
+     * 1024 characters.
+     *
+     * @param reader the target {@link Reader}
+     * @param charset the charset encoding
+     */
+    public ReaderInputStream(Reader reader, Charset charset) {
+        this(reader, charset, DEFAULT_BUFFER_SIZE);
+    }
+
+    /**
+     * Construct a new {@link ReaderInputStream}.
+     *
+     * @param reader the target {@link Reader}
+     * @param charsetName the name of the charset encoding
+     * @param bufferSize the size of the input buffer in number of characters
+     */
+    public ReaderInputStream(Reader reader, String charsetName, int bufferSize) {
+        this(reader, Charset.forName(charsetName), bufferSize);
+    }
+
+    /**
+     * Construct a new {@link ReaderInputStream} with a default input buffer size of
+     * 1024 characters.
+     *
+     * @param reader the target {@link Reader}
+     * @param charsetName the name of the charset encoding
+     */
+    public ReaderInputStream(Reader reader, String charsetName) {
+        this(reader, charsetName, DEFAULT_BUFFER_SIZE);
+    }
+
+    /**
+     * Construct a new {@link ReaderInputStream} that uses the default character encoding
+     * with a default input buffer size of 1024 characters.
+     *
+     * @param reader the target {@link Reader}
+     */
+    public ReaderInputStream(Reader reader) {
+        this(reader, Charset.defaultCharset());
+    }
+
+    /**
+     * Fills the internal char buffer from the reader.
+     *
+     * @throws IOException
+     *             If an I/O error occurs
+     */
+    private void fillBuffer() throws IOException {
+        if (!endOfInput && (lastCoderResult == null || lastCoderResult.isUnderflow())) {
+            encoderIn.compact();
+            int position = encoderIn.position();
+            // We don't use Reader#read(CharBuffer) here because it is more efficient
+            // to write directly to the underlying char array (the default implementation
+            // copies data to a temporary char array).
+            int c = reader.read(encoderIn.array(), position, encoderIn.remaining());
+            if (c == -1) {
+                endOfInput = true;
+            } else {
+                encoderIn.position(position + c);
+            }
+            encoderIn.flip();
+        }
+        encoderOut.compact();
+        lastCoderResult = encoder.encode(encoderIn, encoderOut, endOfInput);
+        encoderOut.flip();
+    }
+
+    /**
+     * Read the specified number of bytes into an array.
+     *
+     * @param b the byte array to read into
+     * @param off the offset to start reading bytes into
+     * @param len the number of bytes to read
+     * @return the number of bytes read or <code>-1</code>
+     *         if the end of the stream has been reached
+     * @throws IOException if an I/O error occurs
+     */
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        if (b == null) {
+            throw new NullPointerException("Byte array must not be null");
+        }
+        if (len < 0 || off < 0 || (off + len) > b.length) {
+            throw new IndexOutOfBoundsException("Array Size=" + b.length
+                    + ", offset=" + off + ", length=" + len);
+        }
+        int read = 0;
+        if (len == 0) {
+            return 0; // Always return 0 if len == 0
+        }
+        while (len > 0) {
+            if (encoderOut.hasRemaining()) {
+                int c = Math.min(encoderOut.remaining(), len);
+                encoderOut.get(b, off, c);
+                off += c;
+                len -= c;
+                read += c;
+            } else {
+                fillBuffer();
+                if (endOfInput && !encoderOut.hasRemaining()) {
+                    break;
+                }
+            }
+        }
+        return read == 0 && endOfInput ? -1 : read;
+    }
+
+    /**
+     * Read the specified number of bytes into an array.
+     *
+     * @param b the byte array to read into
+     * @return the number of bytes read or <code>-1</code>
+     *         if the end of the stream has been reached
+     * @throws IOException if an I/O error occurs
+     */
+    @Override
+    public int read(byte[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    /**
+     * Read a single byte.
+     *
+     * @return either the byte read or <code>-1</code> if the end of the stream
+     *         has been reached
+     * @throws IOException if an I/O error occurs
+     */
+    @Override
+    public int read() throws IOException {
+        for (;;) {
+            if (encoderOut.hasRemaining()) {
+                return encoderOut.get() & 0xFF;
+            } else {
+                fillBuffer();
+                if (endOfInput && !encoderOut.hasRemaining()) {
+                    return -1;
+                }
+            }
+        }
+    }
+
+    /**
+     * Close the stream. This method will cause the underlying {@link Reader}
+     * to be closed.
+     * @throws IOException if an I/O error occurs
+     */
+    @Override
+    public void close() throws IOException {
+        reader.close();
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/io/WriteOnCloseOutputStream.java b/transform/src/patch/java/org/apache/cxf/io/WriteOnCloseOutputStream.java
new file mode 100644
index 0000000..17f4579
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/io/WriteOnCloseOutputStream.java
@@ -0,0 +1,46 @@
+/**
+ * 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.cxf.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * This outputstream implementation will cache the message until close()
+ * is called, at which point it will write the message to the OutputStream
+ * supplied via the constructor.
+ */
+public class WriteOnCloseOutputStream extends CachedOutputStream {
+
+    OutputStream flowThroughStream;
+
+    public WriteOnCloseOutputStream(OutputStream stream) {
+        super();
+        flowThroughStream = stream;
+    }
+
+
+    @Override
+    protected void doClose() throws IOException {
+        resetOut(flowThroughStream, true);
+        flowThroughStream.flush();
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/JAXRSInvoker.java b/transform/src/patch/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
new file mode 100644
index 0000000..163ff78
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
@@ -0,0 +1,460 @@
+/**
+ * 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.cxf.jaxrs;
+
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Collections;
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.CompletionStage;
+import java.util.logging.Logger;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.ResourceContext;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.classloader.ClassLoaderUtils.ClassLoaderHolder;
+import org.apache.cxf.common.i18n.BundleUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ClassHelper;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.interceptor.InterceptorChain.State;
+import org.apache.cxf.jaxrs.impl.AsyncResponseImpl;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.impl.ResourceContextImpl;
+import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.OperationResourceInfo;
+import org.apache.cxf.jaxrs.model.ProviderInfo;
+import org.apache.cxf.jaxrs.model.URITemplate;
+import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageContentsList;
+import org.apache.cxf.service.invoker.AbstractInvoker;
+
+public class JAXRSInvoker extends AbstractInvoker {
+    private static final Logger LOG = LogUtils.getL7dLogger(JAXRSInvoker.class);
+    private static final ResourceBundle BUNDLE = BundleUtils.getBundle(JAXRSInvoker.class);
+    private static final String SERVICE_LOADER_AS_CONTEXT = "org.apache.cxf.serviceloader-context";
+    private static final String SERVICE_OBJECT_SCOPE = "org.apache.cxf.service.scope";
+    private static final String REQUEST_SCOPE = "request";
+    private static final String LAST_SERVICE_OBJECT = "org.apache.cxf.service.object.last";
+    private static final String PROXY_INVOCATION_ERROR_FRAGMENT
+        = "object is not an instance of declaring class";
+
+    public JAXRSInvoker() {
+    }
+
+    public Object invoke(Exchange exchange, Object request) {
+        MessageContentsList responseList = checkExchangeForResponse(exchange);
+        if (responseList != null) {
+            return responseList;
+        }
+        AsyncResponse asyncResp = exchange.get(AsyncResponse.class);
+        if (asyncResp != null) {
+            AsyncResponseImpl asyncImpl = (AsyncResponseImpl)asyncResp;
+            asyncImpl.prepareContinuation();
+            try {
+                asyncImpl.handleTimeout();
+                return handleAsyncResponse(exchange, asyncImpl);
+            } catch (Throwable t) {
+                return handleAsyncFault(exchange, asyncImpl, t);
+            }
+        }
+
+        ResourceProvider provider = getResourceProvider(exchange);
+        Object rootInstance = null;
+        Message inMessage = exchange.getInMessage();
+        try {
+            rootInstance = getServiceObject(exchange);
+            Object serviceObject = getActualServiceObject(exchange, rootInstance);
+
+            return invoke(exchange, request, serviceObject);
+        } catch (WebApplicationException ex) {
+            responseList = checkExchangeForResponse(exchange);
+            if (responseList != null) {
+                return responseList;
+            }
+            return handleFault(ex, inMessage);
+        } finally {
+            boolean suspended = isSuspended(exchange);
+            if (suspended || exchange.isOneWay() || inMessage.get(Message.THREAD_CONTEXT_SWITCHED) != null) {
+                ServerProviderFactory.clearThreadLocalProxies(inMessage);
+            }
+            if (suspended || isServiceObjectRequestScope(inMessage)) {
+                persistRoots(exchange, rootInstance, provider);
+            } else {
+                provider.releaseInstance(inMessage, rootInstance);
+            }
+        }
+    }
+
+    private boolean isSuspended(Exchange exchange) {
+        return exchange.getInMessage().getInterceptorChain().getState() == State.SUSPENDED;
+    }
+
+    private Object handleAsyncResponse(Exchange exchange, AsyncResponseImpl ar) {
+        Object asyncObj = ar.getResponseObject();
+        if (asyncObj instanceof Throwable) {
+            final Throwable throwable = (Throwable)asyncObj;
+            Throwable cause = throwable;
+
+            if (throwable instanceof CompletionException) {
+                cause = throwable.getCause();
+            }
+
+            return handleAsyncFault(exchange, ar, (cause != null) ? cause : throwable);
+        }
+        setResponseContentTypeIfNeeded(exchange.getInMessage(), asyncObj);
+        return new MessageContentsList(asyncObj);
+    }
+
+    private Object handleAsyncFault(Exchange exchange, AsyncResponseImpl ar, Throwable t) {
+        try {
+            return handleFault(new Fault(t), exchange.getInMessage(), null, null);
+        } catch (Fault ex) {
+            ar.setUnmappedThrowable(ex.getCause() == null ? ex : ex.getCause());
+            if (isSuspended(exchange)) {
+                ar.reset();
+                exchange.getInMessage().getInterceptorChain().unpause();
+            }
+            return new MessageContentsList(Response.serverError().build());
+        }
+    }
+
+    private void persistRoots(Exchange exchange, Object rootInstance, Object provider) {
+        exchange.put(JAXRSUtils.ROOT_INSTANCE, rootInstance);
+        exchange.put(JAXRSUtils.ROOT_PROVIDER, provider);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Object invoke(Exchange exchange, Object request, Object resourceObject) {
+
+        final OperationResourceInfo ori = exchange.get(OperationResourceInfo.class);
+        final ClassResourceInfo cri = ori.getClassResourceInfo();
+        final Message inMessage = exchange.getInMessage();
+        final ServerProviderFactory providerFactory = ServerProviderFactory.getInstance(inMessage);
+        cri.injectContexts(resourceObject, ori, inMessage);
+
+        if (cri.isRoot()) {
+            ProviderInfo<Application> appProvider = providerFactory.getApplicationProvider();
+            if (appProvider != null) {
+                InjectionUtils.injectContexts(appProvider.getProvider(),
+                                              appProvider,
+                                              inMessage);
+            }
+        }
+
+
+        Method methodToInvoke = getMethodToInvoke(cri, ori, resourceObject);
+
+        List<Object> params = null;
+        if (request instanceof List) {
+            params = CastUtils.cast((List<?>)request);
+        } else if (request != null) {
+            params = new MessageContentsList(request);
+        }
+
+        Object result = null;
+        ClassLoaderHolder contextLoader = null;
+        AsyncResponseImpl asyncResponse = null;
+        try {
+            if (setServiceLoaderAsContextLoader(inMessage)) {
+                contextLoader = ClassLoaderUtils
+                    .setThreadContextClassloader(resourceObject.getClass().getClassLoader());
+            }
+            if (!ori.isSubResourceLocator()) {
+                asyncResponse = (AsyncResponseImpl)inMessage.get(AsyncResponse.class);
+            }
+            result = invoke(exchange, resourceObject, methodToInvoke, params);
+            if (asyncResponse == null && !ori.isSubResourceLocator()) {
+                asyncResponse = checkFutureResponse(inMessage, checkResultObject(result));
+            }
+            if (asyncResponse != null) {
+                if (!asyncResponse.suspendContinuationIfNeeded()) {
+                    result = handleAsyncResponse(exchange, asyncResponse);
+                } else {
+                    providerFactory.clearThreadLocalProxies();
+                }
+            }
+        } catch (Fault ex) {
+            Object faultResponse;
+            if (asyncResponse != null) {
+                faultResponse = handleAsyncFault(exchange, asyncResponse,
+                                                 ex.getCause() == null ? ex : ex.getCause());
+            } else {
+                faultResponse = handleFault(ex, inMessage, cri, methodToInvoke);
+            }
+            return faultResponse;
+        } finally {
+            exchange.put(LAST_SERVICE_OBJECT, resourceObject);
+            if (contextLoader != null) {
+                contextLoader.reset();
+            }
+        }
+        ClassResourceInfo subCri = null;
+        if (ori.isSubResourceLocator()) {
+            try {
+                MultivaluedMap<String, String> values = getTemplateValues(inMessage);
+                String subResourcePath = values.getFirst(URITemplate.FINAL_MATCH_GROUP);
+                String httpMethod = (String)inMessage.get(Message.HTTP_REQUEST_METHOD);
+                String contentType = (String)inMessage.get(Message.CONTENT_TYPE);
+                if (contentType == null) {
+                    contentType = "*/*";
+                }
+                List<MediaType> acceptContentType =
+                    (List<MediaType>)exchange.get(Message.ACCEPT_CONTENT_TYPE);
+
+                result = checkSubResultObject(result, subResourcePath);
+
+                final Class<?> subResponseType;
+                if (result.getClass() == Class.class) {
+                    ResourceContext rc = new ResourceContextImpl(inMessage, ori);
+                    result = rc.getResource((Class<?>)result);
+                    subResponseType = InjectionUtils.getActualType(methodToInvoke.getGenericReturnType());
+                } else {
+                    subResponseType = methodToInvoke.getReturnType();
+                }
+                
+                subCri = cri.getSubResource(subResponseType,
+                    ClassHelper.getRealClass(exchange.getBus(), result), result);
+                if (subCri == null) {
+                    org.apache.cxf.common.i18n.Message errorM =
+                        new org.apache.cxf.common.i18n.Message("NO_SUBRESOURCE_FOUND",
+                                                               BUNDLE,
+                                                               subResourcePath);
+                    LOG.severe(errorM.toString());
+                    throw ExceptionUtils.toNotFoundException(null, null);
+                }
+
+                OperationResourceInfo subOri = JAXRSUtils.findTargetMethod(
+                                                         Collections.singletonMap(subCri, values),
+                                                         inMessage,
+                                                         httpMethod,
+                                                         values,
+                                                         contentType,
+                                                         acceptContentType);
+                exchange.put(OperationResourceInfo.class, subOri);
+                inMessage.put(URITemplate.TEMPLATE_PARAMETERS, values);
+                inMessage.put(URITemplate.URI_TEMPLATE, JAXRSUtils.getUriTemplate(inMessage, subCri, ori, subOri));
+
+                if (!subOri.isSubResourceLocator()
+                    && JAXRSUtils.runContainerRequestFilters(providerFactory,
+                                                             inMessage,
+                                                             false,
+                                                             subOri.getNameBindings())) {
+                    return new MessageContentsList(exchange.get(Response.class));
+                }
+
+                // work out request parameters for the sub-resource class. Here we
+                // presume InputStream has not been consumed yet by the root resource class.
+                List<Object> newParams = JAXRSUtils.processParameters(subOri, values, inMessage);
+                inMessage.setContent(List.class, newParams);
+
+                return this.invoke(exchange, newParams, result);
+            } catch (IOException ex) {
+                Response resp = JAXRSUtils.convertFaultToResponse(ex, inMessage);
+                if (resp == null) {
+                    resp = JAXRSUtils.convertFaultToResponse(ex, inMessage);
+                }
+                return new MessageContentsList(resp);
+            } catch (WebApplicationException ex) {
+                Response excResponse;
+                if (JAXRSUtils.noResourceMethodForOptions(ex.getResponse(),
+                        (String)inMessage.get(Message.HTTP_REQUEST_METHOD))) {
+                    excResponse = JAXRSUtils.createResponse(Collections.singletonList(subCri),
+                                                            null, null, 200, true);
+                } else {
+                    excResponse = JAXRSUtils.convertFaultToResponse(ex, inMessage);
+                }
+                return new MessageContentsList(excResponse);
+            }
+        }
+        setResponseContentTypeIfNeeded(inMessage, result);
+        return result;
+    }
+
+    protected AsyncResponseImpl checkFutureResponse(Message inMessage, Object result) {
+        if (result instanceof CompletionStage) {
+            final CompletionStage<?> stage = (CompletionStage<?>)result;
+            final AsyncResponseImpl asyncResponse = new AsyncResponseImpl(inMessage);
+            stage.whenComplete((v, t) -> {
+                if (t instanceof CancellationException) {
+                    asyncResponse.cancel();
+                } else {
+                    asyncResponse.resume(v != null ? v : t);
+                }
+            });
+            return asyncResponse;
+        }
+        return null;
+    }
+
+    protected Method getMethodToInvoke(ClassResourceInfo cri, OperationResourceInfo ori, Object resourceObject) {
+        Method resourceMethod = cri.getMethodDispatcher().getMethod(ori);
+
+        Method methodToInvoke;
+        if (Proxy.class.isInstance(resourceObject)) {
+            methodToInvoke = cri.getMethodDispatcher().getProxyMethod(resourceMethod);
+            if (methodToInvoke == null) {
+                methodToInvoke = InjectionUtils.checkProxy(resourceMethod, resourceObject);
+                cri.getMethodDispatcher().addProxyMethod(resourceMethod, methodToInvoke);
+            }
+        } else {
+            methodToInvoke = resourceMethod;
+        }
+        return methodToInvoke;
+    }
+
+    private MessageContentsList checkExchangeForResponse(Exchange exchange) {
+        Response r = exchange.get(Response.class);
+        if (r != null) {
+            JAXRSUtils.setMessageContentType(exchange.getInMessage(), r);
+            return new MessageContentsList(r);
+        }
+        return null;
+    }
+
+    private void setResponseContentTypeIfNeeded(Message inMessage, Object response) {
+        if (response instanceof Response) {
+            JAXRSUtils.setMessageContentType(inMessage, (Response)response);
+        }
+    }
+    private Object handleFault(Throwable ex, Message inMessage) {
+        return handleFault(new Fault(ex), inMessage, null, null);
+    }
+    private Object handleFault(Fault ex, Message inMessage,
+                               ClassResourceInfo cri, Method methodToInvoke) {
+        String errorMessage = ex.getMessage();
+        if (errorMessage != null && cri != null
+            && errorMessage.contains(PROXY_INVOCATION_ERROR_FRAGMENT)) {
+            org.apache.cxf.common.i18n.Message errorM =
+                new org.apache.cxf.common.i18n.Message("PROXY_INVOCATION_FAILURE",
+                                                       BUNDLE,
+                                                       methodToInvoke,
+                                                       cri.getServiceClass().getName());
+            LOG.severe(errorM.toString());
+        }
+        Response excResponse =
+            JAXRSUtils.convertFaultToResponse(ex.getCause() == null ? ex : ex.getCause(), inMessage);
+        if (excResponse == null) {
+            inMessage.getExchange().put(Message.PROPOGATE_EXCEPTION,
+                                        ExceptionUtils.propogateException(inMessage));
+            throw ex;
+        }
+        return new MessageContentsList(excResponse);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected MultivaluedMap<String, String> getTemplateValues(Message msg) {
+        MultivaluedMap<String, String> values = new MetadataMap<>();
+        MultivaluedMap<String, String> oldValues =
+            (MultivaluedMap<String, String>)msg.get(URITemplate.TEMPLATE_PARAMETERS);
+        if (oldValues != null) {
+            values.putAll(oldValues);
+        }
+        return values;
+    }
+
+    private boolean setServiceLoaderAsContextLoader(Message inMessage) {
+        Object en = inMessage.getContextualProperty(SERVICE_LOADER_AS_CONTEXT);
+        return Boolean.TRUE.equals(en) || "true".equals(en);
+    }
+
+    private boolean isServiceObjectRequestScope(Message inMessage) {
+        Object scope = inMessage.getContextualProperty(SERVICE_OBJECT_SCOPE);
+        return REQUEST_SCOPE.equals(scope);
+    }
+
+    private ResourceProvider getResourceProvider(Exchange exchange) {
+        Object provider = exchange.remove(JAXRSUtils.ROOT_PROVIDER);
+        if (provider == null) {
+            OperationResourceInfo ori = exchange.get(OperationResourceInfo.class);
+            ClassResourceInfo cri = ori.getClassResourceInfo();
+            return cri.getResourceProvider();
+        }
+        return (ResourceProvider)provider;
+    }
+
+    public Object getServiceObject(Exchange exchange) {
+
+        Object root = exchange.remove(JAXRSUtils.ROOT_INSTANCE);
+        if (root != null) {
+            return root;
+        }
+
+        OperationResourceInfo ori = exchange.get(OperationResourceInfo.class);
+        ClassResourceInfo cri = ori.getClassResourceInfo();
+
+        return cri.getResourceProvider().getInstance(exchange.getInMessage());
+    }
+
+    protected Object getActualServiceObject(Exchange exchange, Object rootInstance) {
+
+        Object last = exchange.get(LAST_SERVICE_OBJECT);
+        return last !=  null ? last : rootInstance;
+    }
+
+
+
+    private static Object checkResultObject(Object result) {
+
+        if (result != null) {
+            if (result instanceof MessageContentsList) {
+                result = ((MessageContentsList)result).get(0);
+            } else if (result instanceof List) {
+                result = ((List<?>)result).get(0);
+            } else if (result.getClass().isArray()) {
+                result = ((Object[])result)[0];
+            }
+        }
+        return result;
+    }
+    private static Object checkSubResultObject(Object result, String subResourcePath) {
+        result = checkResultObject(result);
+        if (result == null) {
+            org.apache.cxf.common.i18n.Message errorM =
+                new org.apache.cxf.common.i18n.Message("NULL_SUBRESOURCE",
+                                                       BUNDLE,
+                                                       subResourcePath);
+            LOG.info(errorM.toString());
+            throw ExceptionUtils.toNotFoundException(null, null);
+        }
+
+        return result;
+    }
+
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java b/transform/src/patch/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java
new file mode 100644
index 0000000..7871226
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java
@@ -0,0 +1,467 @@
+/**
+ * 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.cxf.jaxrs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.Application;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.classloader.ClassLoaderUtils.ClassLoaderHolder;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.endpoint.ServerImpl;
+import org.apache.cxf.feature.Feature;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.jaxrs.ext.ResourceComparator;
+import org.apache.cxf.jaxrs.impl.RequestPreprocessor;
+import org.apache.cxf.jaxrs.lifecycle.PerRequestResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.jaxrs.model.ApplicationInfo;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.service.factory.FactoryBeanListener;
+import org.apache.cxf.service.factory.ServiceConstructionException;
+import org.apache.cxf.service.invoker.Invoker;
+
+
+/**
+ * Bean to help easily create Server endpoints for JAX-RS. Example:
+ * <pre>
+ * JAXRSServerFactoryBean sf = JAXRSServerFactoryBean();
+ * sf.setResourceClasses(Book.class);
+ * sf.setBindingId(JAXRSBindingFactory.JAXRS_BINDING_ID);
+ * sf.setAddress("http://localhost:9080/");
+ * Server myServer = sf.create();
+ * </pre>
+ * This will start a server for you and register it with the ServerManager.  Note
+ * you should explicitly close the {@link org.apache.cxf.endpoint.Server} created
+ * when finished with it:
+ * <pre>
+ * myServer.close();
+ * myServer.destroy(); // closes first if close() not previously called
+ * </pre>
+ */
+public class JAXRSServerFactoryBean extends AbstractJAXRSFactoryBean {
+
+    protected Map<Class<?>, ResourceProvider> resourceProviders = new HashMap<>();
+
+    private Server server;
+    private boolean start = true;
+    private Map<Object, Object> languageMappings;
+    private Map<Object, Object> extensionMappings;
+    private ResourceComparator rc;
+    private ApplicationInfo appProvider;
+    private String documentLocation;
+
+    public JAXRSServerFactoryBean() {
+        this(new JAXRSServiceFactoryBean());
+    }
+
+    public JAXRSServerFactoryBean(JAXRSServiceFactoryBean sf) {
+        super(sf);
+    }
+
+    /**
+     * Saves the reference to the JAX-RS {@link Application}
+     * @param app
+     */
+    public void setApplication(Application app) {
+        setApplicationInfo(new ApplicationInfo(app, getBus()));
+    }
+
+    public void setApplicationInfo(ApplicationInfo provider) {
+        appProvider = provider;
+        Set<String> appNameBindings = AnnotationUtils.getNameBindings(bus, provider.getProvider().getClass());
+        for (ClassResourceInfo cri : getServiceFactory().getClassResourceInfo()) {
+            Set<String> clsNameBindings = new LinkedHashSet<>(appNameBindings);
+            clsNameBindings.addAll(AnnotationUtils.getNameBindings(bus, cri.getServiceClass()));
+            cri.setNameBindings(clsNameBindings);
+        }
+    }
+
+    /**
+     * Resource comparator which may be used to customize the way
+     * a root resource or resource method is selected
+     * @param rcomp comparator
+     */
+    public void setResourceComparator(ResourceComparator rcomp) {
+        rc = rcomp;
+    }
+
+    /**
+     * By default the subresources are resolved dynamically, mainly due to
+     * the JAX-RS specification allowing Objects being returned from the subresource
+     * locators. Setting this property to true enables the runtime to do the
+     * early resolution.
+     *
+     * @param enableStatic enabling the static resolution if set to true
+     */
+    public void setStaticSubresourceResolution(boolean enableStatic) {
+        serviceFactory.setEnableStaticResolution(enableStatic);
+    }
+
+
+    /**
+     * Creates the JAX-RS Server instance
+     * @return the server
+     */
+    public void init() {
+        if (server == null) {
+            create();
+        }
+    }
+
+    /**
+     * Creates the JAX-RS Server instance
+     * @return the server
+     */
+    public Server create() {
+        ClassLoaderHolder origLoader = null;
+        try {
+            Bus bus = getBus();
+            ClassLoader loader = bus.getExtension(ClassLoader.class);
+            if (loader != null) {
+                origLoader = ClassLoaderUtils.setThreadContextClassloader(loader);
+            }
+            serviceFactory.setBus(bus);
+            checkResources(true);
+            if (serviceFactory.getService() == null) {
+                serviceFactory.create();
+            }
+
+            Endpoint ep = createEndpoint();
+
+            getServiceFactory().sendEvent(FactoryBeanListener.Event.PRE_SERVER_CREATE,
+                                          server);
+
+            server = new ServerImpl(getBus(),
+                                    ep,
+                                    getDestinationFactory(),
+                                    getBindingFactory());
+
+            Invoker invoker = serviceFactory.getInvoker();
+            if (invoker == null) {
+                ep.getService().setInvoker(createInvoker());
+            } else {
+                ep.getService().setInvoker(invoker);
+            }
+
+            ServerProviderFactory factory = setupFactory(ep);
+            
+            ep.put(Application.class.getName(), appProvider);
+            factory.setRequestPreprocessor(
+                new RequestPreprocessor(languageMappings, extensionMappings));
+            ep.put(Bus.class.getName(), getBus());
+            if (documentLocation != null) {
+                ep.put(JAXRSUtils.DOC_LOCATION, documentLocation);
+            }
+            if (rc != null) {
+                ep.put("org.apache.cxf.jaxrs.comparator", rc);
+            }
+            checkPrivateEndpoint(ep);
+
+            applyBusFeatures(getBus());
+            applyFeatures();
+
+            updateClassResourceProviders(ep);
+            injectContexts(factory, (ApplicationInfo)ep.get(Application.class.getName()));
+            factory.applyDynamicFeatures(getServiceFactory().getClassResourceInfo());
+            
+            
+            getServiceFactory().sendEvent(FactoryBeanListener.Event.SERVER_CREATED,
+                                          server,
+                                          null,
+                                          null);
+
+
+            if (start) {
+                try {
+                    server.start();
+                } catch (RuntimeException re) {
+                    if (!(re instanceof ServiceConstructionException 
+                        && re.getMessage().startsWith("There is an endpoint already running on"))) {
+                        //avoid destroying another server on the same endpoint url
+                        server.destroy(); // prevent resource leak if server really started by itself
+                        
+                    }
+                    throw re;
+                }
+            }
+        } catch (Exception e) {
+            throw new ServiceConstructionException(e);
+        } finally {
+            if (origLoader != null) {
+                origLoader.reset();
+            }
+        }
+
+        return server;
+    }
+
+    public Server getServer() {
+        return server;
+    }
+
+    protected ServerProviderFactory setupFactory(Endpoint ep) {
+        ServerProviderFactory factory = ServerProviderFactory.createInstance(getBus());
+        setBeanInfo(factory);
+        factory.setApplicationProvider(appProvider);
+        super.setupFactory(factory, ep);
+        return factory;
+    }
+
+    protected void setBeanInfo(ServerProviderFactory factory) {
+        List<ClassResourceInfo> cris = serviceFactory.getClassResourceInfo();
+        for (ClassResourceInfo cri : cris) {
+            cri.initBeanParamInfo(factory);
+        }
+
+    }
+
+    protected void applyBusFeatures(final Bus bus) {
+        if (bus.getFeatures() != null) {
+            for (Feature feature : bus.getFeatures()) {
+                feature.initialize(server, bus);
+            }
+        }
+    }
+
+    protected void applyFeatures() {
+        if (getFeatures() != null) {
+            for (Feature feature : getFeatures()) {
+                feature.initialize(server, getBus());
+            }
+        }
+    }
+
+    protected Invoker createInvoker() {
+        return serviceFactory.createInvoker();
+    }
+
+    /**
+     * Sets the language mappings,
+     * example, 'en' is the key and 'en-gb' is the value.
+     *
+     * @param lMaps the language mappings
+     */
+    public void setLanguageMappings(Map<Object, Object> lMaps) {
+        languageMappings = lMaps;
+    }
+
+    /**
+     * Sets the extension mappings,
+     * example, 'xml' is the key and 'text/xml' is the value.
+     *
+     * @param extMaps the extension mappings
+     */
+    public void setExtensionMappings(Map<Object, Object> extMaps) {
+        extensionMappings = extMaps;
+    }
+
+    public List<Class<?>> getResourceClasses() {
+        return serviceFactory.getResourceClasses();
+    }
+
+    /**
+     * This method is used primarily by Spring handler processing
+     * the jaxrs:server/@serviceClass attribute. It delegates to
+     * setResourceClasses method accepting the array of Class parameters.
+     * @param clazz the service/resource class
+     */
+    public void setServiceClass(Class<?> clazz) {
+        serviceFactory.setResourceClasses(clazz);
+    }
+
+    /**
+     * Sets one or more root resource classes
+     * @param classes the list of resource classes
+     */
+    public void setResourceClasses(List<Class<?>> classes) {
+        serviceFactory.setResourceClasses(classes);
+    }
+
+    /**
+     * Sets one or more root resource classes
+     * @param classes the array of resource classes
+     */
+    public void setResourceClasses(Class<?>... classes) {
+        serviceFactory.setResourceClasses(classes);
+    }
+
+    /**
+     * Sets the resource beans. If this is set then the JAX-RS runtime
+     * will not be responsible for the life-cycle of resource classes.
+     *
+     * @param beans the array of resource instances
+     */
+    public void setServiceBeanObjects(Object... beans) {
+        setServiceBeans(Arrays.asList(beans));
+    }
+
+    /**
+     * Sets the single resource bean. If this is set then the JAX-RS runtime
+     * will not be responsible for the life-cycle of resource classes.
+     * Please avoid setting the resource class of this bean explicitly,
+     * the runtime will determine it itself.
+     *
+     * @param bean resource instance
+     */
+    public void setServiceBean(Object bean) {
+        setServiceBeans(Arrays.asList(bean));
+    }
+
+    /**
+     * Sets the resource beans. If this is set then the JAX-RS runtime
+     * will not be responsible for the life-cycle of resource classes.
+     *
+     * @param beans the list of resource instances
+     */
+    public void setServiceBeans(List<Object> beans) {
+        List<Object> newBeans = new ArrayList<>();
+        addToBeans(newBeans, beans);
+        serviceFactory.setResourceClassesFromBeans(newBeans);
+    }
+
+    /**
+     * Sets the provider managing the life-cycle of the given resource class
+     * <pre>
+     * Example:
+     *  setResourceProvider(BookStoreInterface.class, new SingletonResourceProvider(new BookStore()));
+     * </pre>
+     * @param c resource class
+     * @param rp resource provider
+     */
+    public void setResourceProvider(Class<?> c, ResourceProvider rp) {
+        resourceProviders.put(c, rp);
+    }
+
+    /**
+     * Sets the provider managing the life-cycle of the resource class
+     * <pre>
+     * Example:
+     *  setResourceProvider(new SingletonResourceProvider(new BookStore()));
+     * </pre>
+     * @param rp resource provider
+     */
+    public void setResourceProvider(ResourceProvider rp) {
+        setResourceProviders(CastUtils.cast(Collections.singletonList(rp), ResourceProvider.class));
+    }
+
+    /**
+     * Sets the list of providers managing the life-cycle of the resource classes
+     *
+     * @param rps resource providers
+     */
+    public void setResourceProviders(List<ResourceProvider> rps) {
+        for (ResourceProvider rp : rps) {
+            Class<?> c = rp.getResourceClass();
+            setServiceClass(c);
+            resourceProviders.put(c, rp);
+        }
+    }
+
+    /**
+     * Sets the custom Invoker which can be used to customize the way
+     * the default JAX-RS invoker calls on the service bean
+     * @param invoker
+     */
+    public void setInvoker(Invoker invoker) {
+        serviceFactory.setInvoker(invoker);
+    }
+
+    /**
+     * Determines whether Services are automatically started during the create() call.  Default is true.
+     * If false will need to call start() method on Server to activate it.
+     * @param start Whether (true) or not (false) to start the Server during Server creation.
+     */
+    public void setStart(boolean start) {
+        this.start = start;
+    }
+
+    protected void injectContexts(ServerProviderFactory factory, ApplicationInfo fallback) {
+        // Sometimes the application provider (ApplicationInfo) is injected through
+        // the endpoint, not JAXRSServerFactoryBean (like for example OpenApiFeature
+        // or Swagger2Feature do). As such, without consulting the endpoint, the injection
+        // may not work properly.
+        final ApplicationInfo appInfoProvider = (appProvider == null) ? fallback : appProvider;
+        final Application application = appInfoProvider == null ? null : appInfoProvider.getProvider();
+
+        for (ClassResourceInfo cri : serviceFactory.getClassResourceInfo()) {
+            if (cri.isSingleton()) {
+                InjectionUtils.injectContextProxiesAndApplication(cri,
+                                                    cri.getResourceProvider().getInstance(null),
+                                                    application,
+                                                    factory);
+            }
+        }
+        if (application != null) {
+            InjectionUtils.injectContextProxiesAndApplication(appInfoProvider,
+                                                              application, null, null);
+        }
+    }
+
+    protected void updateClassResourceProviders(Endpoint ep) {
+        for (ClassResourceInfo cri : serviceFactory.getClassResourceInfo()) {
+            if (cri.getResourceProvider() == null) {
+                ResourceProvider rp = resourceProviders.get(cri.getResourceClass());
+                if (rp != null) {
+                    cri.setResourceProvider(rp);
+                } else {
+                    setDefaultResourceProvider(cri);
+                }
+            }
+            if (cri.getResourceProvider() instanceof SingletonResourceProvider) {
+                ((SingletonResourceProvider)cri.getResourceProvider()).init(ep);
+            }
+        }
+    }
+
+    protected void setDefaultResourceProvider(ClassResourceInfo cri) {
+        cri.setResourceProvider(new PerRequestResourceProvider(cri.getResourceClass()));
+    }
+
+    /**
+     * Set the reference to the document (WADL, etc) describing the endpoint
+     * @param docLocation document location
+     */
+    public void setDocLocation(String docLocation) {
+        this.documentLocation = docLocation;
+    }
+
+    /**
+     * Get the reference to the document (WADL, etc) describing the endpoint
+     * @return document location
+     */
+    public String getDocLocation() {
+        return documentLocation;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/impl/EntityTagHeaderProvider.java b/transform/src/patch/java/org/apache/cxf/jaxrs/impl/EntityTagHeaderProvider.java
new file mode 100644
index 0000000..0deb1c3
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/impl/EntityTagHeaderProvider.java
@@ -0,0 +1,77 @@
+/**
+ * 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.cxf.jaxrs.impl;
+
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
+
+public class EntityTagHeaderProvider implements HeaderDelegate<EntityTag> {
+
+    private static final String WEAK_PREFIX = "W/";
+
+    public EntityTag fromString(String header) {
+
+
+        if (header == null) {
+            throw new IllegalArgumentException("ETag value can not be null");
+        }
+
+        if ("*".equals(header)) {
+            return new EntityTag("*");
+        }
+
+        String tag;
+        boolean weak = false;
+        int i = header.indexOf(WEAK_PREFIX);
+        if (i != -1) {
+            weak = true;
+            if (i + 2 < header.length()) {
+                tag = header.substring(i + 2);
+            } else {
+                return new EntityTag("", weak);
+            }
+        }  else {
+            tag = header;
+        }
+        if (tag.length() > 0 && !tag.startsWith("\"") && !tag.endsWith("\"")) {
+            return new EntityTag(tag, weak);
+        }
+        if (tag.length() < 2 || !tag.startsWith("\"") || !tag.endsWith("\"")) {
+            throw new IllegalArgumentException("Misformatted ETag : " + header);
+        }
+        tag = tag.length() == 2 ? "" : tag.substring(1, tag.length() - 1);
+        return new EntityTag(tag, weak);
+    }
+
+    public String toString(EntityTag tag) {
+        StringBuilder sb = new StringBuilder();
+        if (tag.isWeak()) {
+            sb.append(WEAK_PREFIX);
+        }
+        String tagValue = tag.getValue();
+        if (!tagValue.startsWith("\"")) {
+            sb.append('"').append(tagValue).append('"');
+        } else {
+            sb.append(tagValue);
+        }
+        return sb.toString();
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/impl/MediaTypeHeaderProvider.java b/transform/src/patch/java/org/apache/cxf/jaxrs/impl/MediaTypeHeaderProvider.java
new file mode 100644
index 0000000..a885a33
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/impl/MediaTypeHeaderProvider.java
@@ -0,0 +1,221 @@
+/**
+ * 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.cxf.jaxrs.impl;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.common.util.SystemPropertyAction;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+
+public class MediaTypeHeaderProvider implements HeaderDelegate<MediaType> {
+    private static final Logger LOG = LogUtils.getL7dLogger(MediaTypeHeaderProvider.class);
+    private static final String STRICT_MEDIA_TYPE_CHECK =
+        "org.apache.cxf.jaxrs.mediaTypeCheck.strict";
+    private static final Pattern COMPLEX_PARAMETERS =
+        Pattern.compile("(([\\w-]+=\"[^\"]*\")|([\\w-]+=[\\w-/\\+]+))");
+
+    private static Map<String, MediaType> map = new ConcurrentHashMap<>();
+    private static final int MAX_MT_CACHE_SIZE =
+        SystemPropertyAction.getInteger("org.apache.cxf.jaxrs.max_mediatype_cache_size", 200);
+
+    public MediaType fromString(String mType) {
+
+        return valueOf(mType);
+    }
+
+    public static MediaType valueOf(String mType) {
+        if (mType == null) {
+            throw new IllegalArgumentException("Media type value can not be null");
+        }
+
+        MediaType result = map.get(mType);
+        if (result == null) {
+            result = internalValueOf(mType);
+            final int size = map.size();
+            if (size >= MAX_MT_CACHE_SIZE) {
+                map.clear();
+            }
+            map.put(mType, result);
+        }
+        return result;
+    }
+
+    public static MediaType internalValueOf(String mType) {
+
+        int i = mType.indexOf('/');
+        if (i == -1) {
+            return handleMediaTypeWithoutSubtype(mType.trim());
+        } else if (i == 0) {
+            throw new IllegalArgumentException("Invalid media type string: " + mType);
+        }
+
+        int paramsStart = mType.indexOf(';', i + 1);
+        int end = paramsStart == -1  ? mType.length() : paramsStart;
+
+        String type = mType.substring(0, i).trim();
+        String subtype = mType.substring(i + 1, end).trim();
+        if (!isValid(type) || !isValid(subtype)) {
+            throw new IllegalArgumentException("Invalid media type string: " + mType);
+        }
+
+        Map<String, String> parameters = Collections.emptyMap();
+        if (paramsStart != -1) {
+
+            parameters = new LinkedHashMap<>();
+
+            String paramString = mType.substring(paramsStart + 1);
+            if (paramString.contains("\"")) {
+                Matcher m = COMPLEX_PARAMETERS.matcher(paramString);
+                while (m.find()) {
+                    String val = m.group().trim();
+                    addParameter(parameters, val);
+                }
+            } else {
+                StringTokenizer st = new StringTokenizer(paramString, ";");
+                while (st.hasMoreTokens()) {
+                    addParameter(parameters, st.nextToken());
+                }
+            }
+        }
+
+        return new MediaType(type.toLowerCase(),
+                             subtype.toLowerCase(),
+                             parameters);
+    }
+
+    private static void addParameter(Map<String, String> parameters, String token) {
+        int equalSign = token.indexOf('=');
+        if (equalSign == -1) {
+            throw new IllegalArgumentException("Wrong media type parameter, separator is missing");
+        }
+        parameters.put(token.substring(0, equalSign).trim().toLowerCase(),
+                       token.substring(equalSign + 1).trim());
+    }
+
+    public String toString(MediaType type) {
+        return typeToString(type);
+    }
+    public static String typeToString(MediaType type) {
+        return typeToString(type, null);
+    }
+    // Max number of parameters that may be ignored is 3, at least as known
+    // to the implementation
+    public static String typeToString(MediaType type, List<String> ignoreParams) {
+        if (type == null) {
+            throw new IllegalArgumentException("MediaType parameter is null");
+        }
+        StringBuilder sb = new StringBuilder();
+        sb.append(type.getType()).append('/').append(type.getSubtype());
+
+        Map<String, String> params = type.getParameters();
+        if (params != null) {
+            for (Map.Entry<String, String> entry : params.entrySet()) {
+                if (ignoreParams != null && ignoreParams.contains(entry.getKey())) {
+                    continue;
+                }
+                sb.append(';').append(entry.getKey()).append('=').append(entry.getValue());
+            }
+        }
+
+        return sb.toString();
+    }
+
+    private static MediaType handleMediaTypeWithoutSubtype(String mType) {
+        if (mType.startsWith(MediaType.MEDIA_TYPE_WILDCARD)) {
+            String mTypeNext = mType.length() == 1 ? "" : mType.substring(1).trim();
+            boolean mTypeNextEmpty = StringUtils.isEmpty(mTypeNext);
+            if (mTypeNextEmpty || mTypeNext.startsWith(";")) {
+                if (!mTypeNextEmpty) {
+                    Map<String, String> parameters = new LinkedHashMap<>();
+                    StringTokenizer st = new StringTokenizer(mType.substring(2).trim(), ";");
+                    while (st.hasMoreTokens()) {
+                        addParameter(parameters, st.nextToken());
+                    }
+                    return new MediaType(MediaType.MEDIA_TYPE_WILDCARD,
+                                         MediaType.MEDIA_TYPE_WILDCARD,
+                                         parameters);
+                }
+                return MediaType.WILDCARD_TYPE;
+
+            }
+        }
+        Message message = PhaseInterceptorChain.getCurrentMessage();
+        if (message != null
+            && !MessageUtils.getContextualBoolean(message, STRICT_MEDIA_TYPE_CHECK, false)) {
+            final MediaType mt;
+            if (mType.equals(MediaType.TEXT_PLAIN_TYPE.getType())) {
+                mt = MediaType.TEXT_PLAIN_TYPE;
+            } else if (mType.equals(MediaType.APPLICATION_XML_TYPE.getSubtype())) {
+                mt = MediaType.APPLICATION_XML_TYPE;
+            } else {
+                mt = MediaType.WILDCARD_TYPE;
+            }
+            LOG.fine("Converting a malformed media type '" + mType + "' to '" + typeToString(mt) + "'");
+            return mt;
+        }
+        throw new IllegalArgumentException("Media type separator is missing");
+    }
+
+    // Determines whether the type or subtype contains any of the tspecials characters defined at:
+    // https://tools.ietf.org/html/rfc2045#section-5.1
+    private static boolean isValid(String str) {
+        final int len = str.length();
+        if (len == 0) {
+            return false;
+        }
+        for (int i = 0; i < len; i++) {
+            switch (str.charAt(i)) {
+            case '/':
+            case '\\':
+            case '?':
+            case ':':
+            case '<':
+            case '>':
+            case ';':
+            case '(':
+            case ')':
+            case '@':
+            case ',':
+            case '[':
+            case ']':
+            case '=':
+                return false;
+            default:
+                continue;
+            }
+        }
+        return true;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/impl/RequestImpl.java b/transform/src/patch/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
new file mode 100644
index 0000000..5921f1a
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
@@ -0,0 +1,388 @@
+/**
+ * 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.cxf.jaxrs.impl;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.core.Variant;
+
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+
+/**
+ * TODO : deal with InvalidStateExceptions
+ *
+ */
+
+
+public class RequestImpl implements Request {
+    private final Message m;
+    private final HttpHeaders headers;
+
+    public RequestImpl(Message m) {
+        this.m = m;
+        this.headers = new HttpHeadersImpl(m);
+    }
+
+
+
+    public Variant selectVariant(List<Variant> vars) throws IllegalArgumentException {
+        if (vars == null || vars.isEmpty()) {
+            throw new IllegalArgumentException("List of Variants is either null or empty");
+        }
+        List<MediaType> acceptMediaTypes = headers.getAcceptableMediaTypes();
+        List<Locale> acceptLangs = headers.getAcceptableLanguages();
+        List<String> acceptEncs = parseAcceptEnc(
+            headers.getRequestHeaders().getFirst(HttpHeaders.ACCEPT_ENCODING));
+        List<Variant> requestVariants = sortAllCombinations(acceptMediaTypes, acceptLangs, acceptEncs);
+        List<Object> varyValues = new LinkedList<>();
+        for (Variant requestVar : requestVariants) {
+            for (Variant var : vars) {
+                MediaType mt = var.getMediaType();
+                Locale lang = var.getLanguage();
+                String enc = var.getEncoding();
+
+                boolean mtMatched = mt == null || requestVar.getMediaType().isCompatible(mt);
+                if (mtMatched) {
+                    handleVaryValues(varyValues, HttpHeaders.ACCEPT);
+                }
+
+                boolean langMatched = lang == null || isLanguageMatched(requestVar.getLanguage(), lang);
+                if (langMatched) {
+                    handleVaryValues(varyValues, HttpHeaders.ACCEPT_LANGUAGE);
+                }
+
+                boolean encMatched = acceptEncs.isEmpty() || enc == null 
+                    || isEncMatached(requestVar.getEncoding(), enc);
+                if (encMatched) {
+                    handleVaryValues(varyValues, HttpHeaders.ACCEPT_ENCODING);
+                }
+
+                if (mtMatched && encMatched && langMatched) {
+                    addVaryHeader(varyValues);
+                    return var;
+                }
+            }
+        }
+        return null;
+    }
+
+    private static List<Variant> sortAllCombinations(List<MediaType> mediaTypes,
+                                                     List<Locale> langs,
+                                                     List<String> encs) {
+        List<Variant> requestVars = new LinkedList<>();
+        for (MediaType mt : mediaTypes) {
+            for (Locale lang : langs) {
+                if (encs.isEmpty()) {
+                    requestVars.add(new Variant(mt, lang, null));
+                } else {
+                    for (String enc : encs) {
+                        requestVars.add(new Variant(mt, lang, enc));
+                    }
+                }
+            }
+        }
+        Collections.sort(requestVars, VariantComparator.INSTANCE);
+        return requestVars;
+    }
+
+
+    private static void handleVaryValues(List<Object> varyValues, String ...values) {
+        for (String v : values) {
+            if (v != null && !varyValues.contains(v)) {
+                varyValues.add(v);
+            }
+        }
+    }
+
+    private static void addVaryHeader(List<Object> varyValues) {
+        // at this point we still have no out-bound message so lets
+        // use HttpServletResponse. If needed we can save the header on the exchange
+        // and then copy it into the out-bound message's headers
+        Message message = PhaseInterceptorChain.getCurrentMessage();
+        if (message != null) {
+            Object httpResponse = message.get("HTTP.RESPONSE");
+            if (httpResponse != null) {
+                StringBuilder sb = new StringBuilder();
+                for (int i = 0; i < varyValues.size(); i++) {
+                    if (i > 0) {
+                        sb.append(',');
+                    }
+                    sb.append(varyValues.get(i).toString());
+                }
+                ((javax.servlet.http.HttpServletResponse)httpResponse)
+                    .setHeader(HttpHeaders.VARY, sb.toString());
+            }
+        }
+    }
+
+    private static boolean isLanguageMatched(Locale locale, Locale l) {
+
+        String language = locale.getLanguage();
+        return "*".equals(language) 
+            || language.equalsIgnoreCase(l.getLanguage());
+    }
+
+    private static boolean isEncMatached(String accepts, String enc) {
+        return accepts == null || "*".equals(accepts) || accepts.contains(enc);
+    }
+
+    private static List<String> parseAcceptEnc(String acceptEnc) {
+        if (StringUtils.isEmpty(acceptEnc)) {
+            return Collections.emptyList();
+        }
+        List<String> list = new LinkedList<>();
+        String[] values = acceptEnc.split(",");
+        for (String value : values) {
+            String[] pair = value.trim().split(";");
+            // ignore encoding qualifiers if any for now
+            list.add(pair[0]);
+        }
+        return list;
+    }
+
+    public ResponseBuilder evaluatePreconditions(EntityTag eTag) {
+        if (eTag == null) {
+            throw new IllegalArgumentException("ETag is null");
+        }
+        return evaluateAll(eTag, null);
+    }
+
+    private ResponseBuilder evaluateAll(EntityTag eTag, Date lastModified) {
+        // http://tools.ietf.org/search/draft-ietf-httpbis-p4-conditional-25#section-5
+        // Check If-Match. If it is not available proceed to checking If-Not-Modified-Since
+        // if it is available and the preconditions are not met - return, otherwise:
+        // Check If-Not-Match. If it is not available proceed to checking If-Modified-Since
+        // otherwise return the evaluation result
+
+        ResponseBuilder rb = evaluateIfMatch(eTag, lastModified);
+        if (rb == null) {
+            rb = evaluateIfNonMatch(eTag, lastModified);
+        }
+        return rb;
+    }
+
+    private ResponseBuilder evaluateIfMatch(EntityTag eTag, Date date) {
+        List<String> ifMatch = headers.getRequestHeader(HttpHeaders.IF_MATCH);
+
+        if (ifMatch == null || ifMatch.isEmpty()) {
+            return date == null ? null : evaluateIfNotModifiedSince(date);
+        }
+
+        try {
+            for (String value : ifMatch) {
+                if ("*".equals(value)) {
+                    return null;
+                }
+                EntityTag requestTag = EntityTag.valueOf(value);
+                // must be a strong comparison
+                if (!requestTag.isWeak() && !eTag.isWeak() && requestTag.equals(eTag)) {
+                    return null;
+                }
+            }
+        } catch (IllegalArgumentException ex) {
+            // ignore
+        }
+        return Response.status(Response.Status.PRECONDITION_FAILED).tag(eTag);
+    }
+
+    private ResponseBuilder evaluateIfNonMatch(EntityTag eTag, Date lastModified) {
+        List<String> ifNonMatch = headers.getRequestHeader(HttpHeaders.IF_NONE_MATCH);
+
+        if (ifNonMatch == null || ifNonMatch.isEmpty()) {
+            return lastModified == null ? null : evaluateIfModifiedSince(lastModified);
+        }
+
+        String method = getMethod();
+        boolean getOrHead = HttpMethod.GET.equals(method) || HttpMethod.HEAD.equals(method);
+        try {
+            for (String value : ifNonMatch) {
+                boolean result = "*".equals(value);
+                if (!result) {
+                    EntityTag requestTag = EntityTag.valueOf(value);
+                    result = getOrHead ? requestTag.equals(eTag)
+                        : !requestTag.isWeak() && !eTag.isWeak() && requestTag.equals(eTag);
+                }
+                if (result) {
+                    Response.Status status = getOrHead ? Response.Status.NOT_MODIFIED
+                        : Response.Status.PRECONDITION_FAILED;
+                    return Response.status(status).tag(eTag);
+                }
+            }
+        } catch (IllegalArgumentException ex) {
+            // ignore
+        }
+        return null;
+    }
+
+    public ResponseBuilder evaluatePreconditions(Date lastModified) {
+        if (lastModified == null) {
+            throw new IllegalArgumentException("Date is null");
+        }
+        ResponseBuilder rb = evaluateIfNotModifiedSince(lastModified);
+        if (rb == null) {
+            rb = evaluateIfModifiedSince(lastModified);
+        }
+        return rb;
+    }
+
+    private ResponseBuilder evaluateIfModifiedSince(Date lastModified) {
+        List<String> ifModifiedSince = headers.getRequestHeader(HttpHeaders.IF_MODIFIED_SINCE);
+
+        if (ifModifiedSince == null || ifModifiedSince.isEmpty()) {
+            return null;
+        }
+
+        SimpleDateFormat dateFormat = HttpUtils.getHttpDateFormat();
+
+        dateFormat.setLenient(false);
+        final Date dateSince;
+        try {
+            dateSince = dateFormat.parse(ifModifiedSince.get(0));
+        } catch (ParseException ex) {
+            // invalid header value, request should continue
+            return Response.status(Response.Status.PRECONDITION_FAILED);
+        }
+
+        if (dateSince.before(lastModified)) {
+            // request should continue
+            return null;
+        }
+
+        return Response.status(Response.Status.NOT_MODIFIED);
+    }
+
+    private ResponseBuilder evaluateIfNotModifiedSince(Date lastModified) {
+        List<String> ifNotModifiedSince = headers.getRequestHeader(HttpHeaders.IF_UNMODIFIED_SINCE);
+
+        if (ifNotModifiedSince == null || ifNotModifiedSince.isEmpty()) {
+            return null;
+        }
+
+        SimpleDateFormat dateFormat = HttpUtils.getHttpDateFormat();
+
+        dateFormat.setLenient(false);
+        final Date dateSince;
+        try {
+            dateSince = dateFormat.parse(ifNotModifiedSince.get(0));
+        } catch (ParseException ex) {
+            // invalid header value, request should continue
+            return Response.status(Response.Status.PRECONDITION_FAILED);
+        }
+
+        if (dateSince.before(lastModified)) {
+            return Response.status(Response.Status.PRECONDITION_FAILED);
+        }
+
+        return null;
+    }
+
+
+
+    public ResponseBuilder evaluatePreconditions(Date lastModified, EntityTag eTag) {
+        if (eTag == null || lastModified == null) {
+            throw new IllegalArgumentException("ETag or Date is null");
+        }
+        return evaluateAll(eTag, lastModified);
+    }
+
+    public String getMethod() {
+        return m.get(Message.HTTP_REQUEST_METHOD).toString();
+    }
+
+
+
+    public ResponseBuilder evaluatePreconditions() {
+        List<String> ifMatch = headers.getRequestHeader(HttpHeaders.IF_MATCH);
+        if (ifMatch != null) {
+            for (String value : ifMatch) {
+                if (!"*".equals(value)) {
+                    return Response.status(Response.Status.PRECONDITION_FAILED).tag(EntityTag.valueOf(value));
+                }
+            }
+        }
+        return null;
+    }
+
+    private static class VariantComparator implements Comparator<Variant> {
+
+        static final VariantComparator INSTANCE = new VariantComparator();
+
+        public int compare(Variant v1, Variant v2) {
+            int result = compareMediaTypes(v1.getMediaType(), v2.getMediaType());
+
+            if (result != 0) {
+                return result;
+            }
+
+            result = compareLanguages(v1.getLanguage(), v2.getLanguage());
+
+            if (result == 0) {
+                result = compareEncodings(v1.getEncoding(), v2.getEncoding());
+            }
+
+            return result;
+        }
+
+        private static int compareMediaTypes(MediaType mt1, MediaType mt2) {
+            if (mt1 != null && mt2 == null) {
+                return -1;
+            } else if (mt1 == null && mt2 != null) {
+                return 1;
+            }
+            return JAXRSUtils.compareMediaTypes(mt1, mt2);
+        }
+
+        private static int compareLanguages(Locale l1, Locale l2) {
+            if (l1 != null && l2 == null) {
+                return -1;
+            } else if (l1 == null && l2 != null) {
+                return 1;
+            }
+            return 0;
+        }
+
+        private static int compareEncodings(String enc1, String enc2) {
+            if (enc1 != null && enc2 == null) {
+                return -1;
+            } else if (enc1 == null && enc2 != null) {
+                return 1;
+            }
+            return 0;
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/impl/ResourceContextImpl.java b/transform/src/patch/java/org/apache/cxf/jaxrs/impl/ResourceContextImpl.java
new file mode 100644
index 0000000..ca1e629
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/impl/ResourceContextImpl.java
@@ -0,0 +1,67 @@
+/**
+ * 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.cxf.jaxrs.impl;
+
+import javax.ws.rs.container.ResourceContext;
+
+import org.apache.cxf.jaxrs.ext.ResourceContextProvider;
+import org.apache.cxf.jaxrs.lifecycle.PerRequestResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.OperationResourceInfo;
+import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
+import org.apache.cxf.message.Message;
+
+public class ResourceContextImpl implements ResourceContext {
+    private static final String CONTEXT_PROVIDER_PROP = "org.apache.cxf.jaxrs.resource.context.provider";
+    private final ClassResourceInfo cri;
+    private final Class<?> subClass;
+    private final Message m;
+    public ResourceContextImpl(Message m, OperationResourceInfo ori) {
+        this.m = m;
+        this.cri = ori.getClassResourceInfo();
+        this.subClass = ori.getMethodToInvoke().getReturnType();
+    }
+
+    @Override
+    public <T> T getResource(Class<T> cls) {
+        final ResourceProvider rp;
+
+        Object propValue = m.getContextualProperty(CONTEXT_PROVIDER_PROP);
+        if (propValue instanceof ResourceContextProvider) {
+            rp = ((ResourceContextProvider)propValue).getResourceProvider(cls);
+        } else {
+            rp = new PerRequestResourceProvider(cls);
+        }
+        T resource = cls.cast(rp.getInstance(m));
+        return doInitResource(cls, resource);
+    }
+
+    @Override
+    public <T> T initResource(T resource) {
+        return doInitResource(resource.getClass(), resource);
+    }
+
+    private <T> T doInitResource(Class<?> cls, T resource) {
+        ClassResourceInfo sub = cri.getSubResource(subClass, cls, resource, true, m);
+        sub.initBeanParamInfo(ServerProviderFactory.getInstance(m));
+        sub.injectContexts(resource, m.getExchange().get(OperationResourceInfo.class), m);
+        return resource;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalInvocationHandler.java b/transform/src/patch/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalInvocationHandler.java
new file mode 100644
index 0000000..bb27b5a
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalInvocationHandler.java
@@ -0,0 +1,53 @@
+/**
+ * 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.cxf.jaxrs.impl.tl;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+
+public class ThreadLocalInvocationHandler<T> extends AbstractThreadLocalProxy<T>
+    implements InvocationHandler {
+
+    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
+        final Object target;
+        if (m.getDeclaringClass() == ThreadLocalProxy.class) {
+            target = this;
+        } else {
+            target = get();
+            if (target == null) {
+                if (m.getName().endsWith("toString")) {
+                    return null;
+                }
+                Class<?> contextCls = m.getDeclaringClass();
+                throw new NullPointerException(
+                                               contextCls.getName()
+                                                   + " context class has not been injected."
+                                                   + " Check if ContextProvider supporting this class is registered");
+            }
+        }
+        try {
+            return m.invoke(target, args);
+        } catch (InvocationTargetException e) {
+            throw e.getCause();
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java b/transform/src/patch/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
new file mode 100644
index 0000000..3c9c5d8
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
@@ -0,0 +1,274 @@
+/**
+ * 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.cxf.jaxrs.interceptor;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+
+import org.apache.cxf.common.i18n.BundleUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.interceptor.OutgoingChainInterceptor;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.impl.RequestPreprocessor;
+import org.apache.cxf.jaxrs.impl.UriInfoImpl;
+import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.OperationResourceInfo;
+import org.apache.cxf.jaxrs.model.URITemplate;
+import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageContentsList;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+
+public class JAXRSInInterceptor extends AbstractPhaseInterceptor<Message> {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(JAXRSInInterceptor.class);
+    private static final ResourceBundle BUNDLE = BundleUtils.getBundle(JAXRSInInterceptor.class);
+    private static final String RESOURCE_METHOD = "org.apache.cxf.resource.method";
+    private static final String RESOURCE_OPERATION_NAME = "org.apache.cxf.resource.operation.name";
+
+    public JAXRSInInterceptor() {
+        super(Phase.UNMARSHAL);
+    }
+
+    public void handleMessage(Message message) {
+        final Exchange exchange = message.getExchange();
+
+        exchange.put(Message.REST_MESSAGE, Boolean.TRUE);
+        Response response = exchange.get(Response.class);
+        if (response == null) {
+            try {
+                processRequest(message, exchange);
+                if (exchange.isOneWay()) {
+                    ServerProviderFactory.getInstance(message).clearThreadLocalProxies();
+                }
+            } catch (Fault ex) {
+                convertExceptionToResponseIfPossible(ex.getCause(), message);
+            } catch (RuntimeException ex) {
+                convertExceptionToResponseIfPossible(ex, message);
+            } catch (IOException ex) {
+                convertExceptionToResponseIfPossible(ex, message);
+            }
+        }
+
+        response = exchange.get(Response.class);
+        if (response != null) {
+            createOutMessage(message, response);
+            message.getInterceptorChain().doInterceptStartingAt(message,
+                                                                OutgoingChainInterceptor.class.getName());
+        }
+    }
+
+    private void processRequest(Message message, Exchange exchange) throws IOException {
+
+        ServerProviderFactory providerFactory = ServerProviderFactory.getInstance(message);
+
+        RequestPreprocessor rp = providerFactory.getRequestPreprocessor();
+        if (rp != null) {
+            rp.preprocess(message, new UriInfoImpl(message, null));
+        }
+
+        // Global pre-match request filters
+        if (JAXRSUtils.runContainerRequestFilters(providerFactory, message, true, null)) {
+            return;
+        }
+        // HTTP method
+        String httpMethod = HttpUtils.getProtocolHeader(message, Message.HTTP_REQUEST_METHOD,
+                                                        HttpMethod.POST, true);
+
+        // Path to match
+        String rawPath = HttpUtils.getPathToMatch(message, true);
+
+        Map<String, List<String>> protocolHeaders = CastUtils.cast((Map<?, ?>)message.get(Message.PROTOCOL_HEADERS));
+
+        // Content-Type
+        String requestContentType = null;
+        List<String> ctHeaderValues = protocolHeaders.get(Message.CONTENT_TYPE);
+        if (ctHeaderValues != null && !ctHeaderValues.isEmpty()) {
+            requestContentType = ctHeaderValues.get(0);
+            message.put(Message.CONTENT_TYPE, requestContentType);
+        }
+        if (requestContentType == null) {
+            requestContentType = (String)message.get(Message.CONTENT_TYPE);
+
+            if (requestContentType == null) {
+                requestContentType = MediaType.WILDCARD;
+            }
+        }
+
+        // Accept
+        String acceptTypes = null;
+        List<String> acceptHeaderValues = protocolHeaders.get(Message.ACCEPT_CONTENT_TYPE);
+        if (acceptHeaderValues != null && !acceptHeaderValues.isEmpty()) {
+            acceptTypes = acceptHeaderValues.get(0);
+            message.put(Message.ACCEPT_CONTENT_TYPE, acceptTypes);
+        }
+
+        if (acceptTypes == null) {
+            acceptTypes = HttpUtils.getProtocolHeader(message, Message.ACCEPT_CONTENT_TYPE, null);
+            if (acceptTypes == null) {
+                acceptTypes = "*/*";
+                message.put(Message.ACCEPT_CONTENT_TYPE, acceptTypes);
+            }
+        }
+        final List<MediaType> acceptContentTypes;
+        try {
+            acceptContentTypes = JAXRSUtils.sortMediaTypes(acceptTypes, JAXRSUtils.MEDIA_TYPE_Q_PARAM);
+        } catch (IllegalArgumentException ex) {
+            throw ExceptionUtils.toNotAcceptableException(null, null);
+        }
+        exchange.put(Message.ACCEPT_CONTENT_TYPE, acceptContentTypes);
+
+        //1. Matching target resource class
+        List<ClassResourceInfo> resources = JAXRSUtils.getRootResources(message);
+        Map<ClassResourceInfo, MultivaluedMap<String, String>> matchedResources =
+            JAXRSUtils.selectResourceClass(resources, rawPath, message);
+        if (matchedResources == null) {
+            org.apache.cxf.common.i18n.Message errorMsg =
+                new org.apache.cxf.common.i18n.Message("NO_ROOT_EXC",
+                                                   BUNDLE,
+                                                   message.get(Message.REQUEST_URI),
+                                                   rawPath);
+            Level logLevel = JAXRSUtils.getExceptionLogLevel(message, NotFoundException.class);
+            LOG.log(logLevel == null ? Level.FINE : logLevel, errorMsg.toString());
+            Response resp = JAXRSUtils.createResponse(resources, message, errorMsg.toString(),
+                    Response.Status.NOT_FOUND.getStatusCode(), false);
+            throw ExceptionUtils.toNotFoundException(null, resp);
+        }
+
+        MultivaluedMap<String, String> matchedValues = new MetadataMap<>();
+
+        final OperationResourceInfo ori;
+
+        try {
+            ori = JAXRSUtils.findTargetMethod(matchedResources, message,
+                      httpMethod, matchedValues, requestContentType, acceptContentTypes, true, true);
+            setExchangeProperties(message, exchange, ori, matchedValues, resources.size());
+        } catch (WebApplicationException ex) {
+            if (JAXRSUtils.noResourceMethodForOptions(ex.getResponse(), httpMethod)) {
+                Response response = JAXRSUtils.createResponse(resources, null, null, 200, true);
+                exchange.put(Response.class, response);
+                return;
+            }
+            throw ex;
+        }
+
+
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Request path is: " + rawPath);
+            LOG.fine("Request HTTP method is: " + httpMethod);
+            LOG.fine("Request contentType is: " + requestContentType);
+            LOG.fine("Accept contentType is: " + acceptTypes);
+
+            LOG.fine("Found operation: " + ori.getMethodToInvoke().getName());
+        }
+
+        // Global and name-bound post-match request filters
+        if (!ori.isSubResourceLocator()
+            && JAXRSUtils.runContainerRequestFilters(providerFactory,
+                                                      message,
+                                                      false,
+                                                      ori.getNameBindings())) {
+            return;
+        }
+
+
+        //Process parameters
+        List<Object> params = JAXRSUtils.processParameters(ori, matchedValues, message);
+        message.setContent(List.class, params);
+    }
+
+    private void convertExceptionToResponseIfPossible(Throwable ex, Message message) {
+        Response excResponse = JAXRSUtils.convertFaultToResponse(ex, message);
+        if (excResponse == null) {
+            ServerProviderFactory.getInstance(message).clearThreadLocalProxies();
+            message.getExchange().put(Message.PROPOGATE_EXCEPTION,
+                                      ExceptionUtils.propogateException(message));
+            throw ex instanceof RuntimeException ? (RuntimeException)ex
+                : ExceptionUtils.toInternalServerErrorException(ex, null);
+        }
+        message.getExchange().put(Response.class, excResponse);
+        message.getExchange().put(Throwable.class, ex);
+    }
+
+    private void setExchangeProperties(Message message,
+                                       Exchange exchange,
+                                       OperationResourceInfo ori,
+                                       MultivaluedMap<String, String> values,
+                                       int numberOfResources) {
+        final ClassResourceInfo cri = ori.getClassResourceInfo();
+        exchange.put(OperationResourceInfo.class, ori);
+        exchange.put(JAXRSUtils.ROOT_RESOURCE_CLASS, cri);
+        message.put(RESOURCE_METHOD, ori.getMethodToInvoke());
+        message.put(URITemplate.TEMPLATE_PARAMETERS, values);
+        message.put(URITemplate.URI_TEMPLATE, JAXRSUtils.getUriTemplate(message, cri, ori));
+
+        String plainOperationName = ori.getMethodToInvoke().getName();
+        if (numberOfResources > 1) {
+            plainOperationName = cri.getServiceClass().getSimpleName() + "#" + plainOperationName;
+        }
+        exchange.put(RESOURCE_OPERATION_NAME, plainOperationName);
+
+        if (ori.isOneway()
+            || PropertyUtils.isTrue(HttpUtils.getProtocolHeader(message, Message.ONE_WAY_REQUEST, null))) {
+            exchange.setOneWay(true);
+        }
+        ResourceProvider rp = cri.getResourceProvider();
+        if (rp instanceof SingletonResourceProvider) {
+            //cri.isSingleton is not guaranteed to indicate we have a 'pure' singleton
+            exchange.put(Message.SERVICE_OBJECT, rp.getInstance(message));
+        }
+    }
+
+    private Message createOutMessage(Message inMessage, Response r) {
+        Endpoint e = inMessage.getExchange().getEndpoint();
+        Message mout = e.getBinding().createMessage();
+        mout.setContent(List.class, new MessageContentsList(r));
+        mout.setExchange(inMessage.getExchange());
+        mout.setInterceptorChain(
+             OutgoingChainInterceptor.getOutInterceptorChain(inMessage.getExchange()));
+        inMessage.getExchange().setOutMessage(mout);
+        if (r.getStatus() >= Response.Status.BAD_REQUEST.getStatusCode()) {
+            inMessage.getExchange().put("cxf.io.cacheinput", Boolean.FALSE);
+        }
+        return mout;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java b/transform/src/patch/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
new file mode 100644
index 0000000..ad75c0f
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
@@ -0,0 +1,498 @@
+/**
+ * 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.cxf.jaxrs.interceptor;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.WriterInterceptor;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.events.XMLEvent;
+
+import org.apache.cxf.common.i18n.BundleUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.jaxrs.impl.ResponseImpl;
+import org.apache.cxf.jaxrs.impl.WriterInterceptorMBW;
+import org.apache.cxf.jaxrs.model.OperationResourceInfo;
+import org.apache.cxf.jaxrs.provider.AbstractConfigurableProvider;
+import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageContentsList;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.staxutils.CachingXmlEventWriter;
+import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.cxf.transport.http.AbstractHTTPDestination;
+
+public class JAXRSOutInterceptor extends AbstractOutDatabindingInterceptor {
+    private static final Logger LOG = LogUtils.getL7dLogger(JAXRSOutInterceptor.class);
+    private static final ResourceBundle BUNDLE = BundleUtils.getBundle(JAXRSOutInterceptor.class);
+
+    public JAXRSOutInterceptor() {
+        super(Phase.MARSHAL);
+    }
+
+    public void handleMessage(Message message) {
+        ServerProviderFactory providerFactory = ServerProviderFactory.getInstance(message);
+        try {
+            processResponse(providerFactory, message);
+        } finally {
+            ServerProviderFactory.releaseRequestState(providerFactory, message);
+        }
+
+
+    }
+
+    @SuppressWarnings("resource") // Response shouldn't be closed here
+    private void processResponse(ServerProviderFactory providerFactory, Message message) {
+
+        if (isResponseAlreadyHandled(message)) {
+            return;
+        }
+        MessageContentsList objs = MessageContentsList.getContentsList(message);
+        if (objs == null || objs.isEmpty()) {
+            return;
+        }
+
+        Object responseObj = objs.get(0);
+
+        final Response response;
+        if (responseObj instanceof Response) {
+            response = (Response)responseObj;
+            if (response.getStatus() == 500
+                && message.getExchange().get(JAXRSUtils.EXCEPTION_FROM_MAPPER) != null) {
+                message.put(Message.RESPONSE_CODE, 500);
+                return;
+            }
+        } else {
+            int status = getStatus(message, responseObj != null ? 200 : 204);
+            response = JAXRSUtils.toResponseBuilder(status).entity(responseObj).build();
+        }
+
+        Exchange exchange = message.getExchange();
+        OperationResourceInfo ori = (OperationResourceInfo)exchange.get(OperationResourceInfo.class
+            .getName());
+
+        serializeMessage(providerFactory, message, response, ori, true);
+    }
+
+
+
+    private int getStatus(Message message, int defaultValue) {
+        Object customStatus = message.getExchange().get(Message.RESPONSE_CODE);
+        return customStatus == null ? defaultValue : (Integer)customStatus;
+    }
+
+    private void serializeMessage(ServerProviderFactory providerFactory,
+                                  Message message,
+                                  Response theResponse,
+                                  OperationResourceInfo ori,
+                                  boolean firstTry) {
+
+        ResponseImpl response = (ResponseImpl)JAXRSUtils.copyResponseIfNeeded(theResponse);
+
+        final Exchange exchange = message.getExchange();
+
+        boolean headResponse = response.getStatus() == 200 && firstTry
+            && ori != null && HttpMethod.HEAD.equals(ori.getHttpMethod());
+        Object entity = response.getActualEntity();
+        if (headResponse && entity != null) {
+            LOG.info(new org.apache.cxf.common.i18n.Message("HEAD_WITHOUT_ENTITY", BUNDLE).toString());
+            entity = null;
+        }
+
+
+        Method invoked = ori == null ? null : ori.getAnnotatedMethod() != null
+            ? ori.getAnnotatedMethod() : ori.getMethodToInvoke();
+
+        Annotation[] annotations;
+        Annotation[] staticAnns = ori != null ? ori.getOutAnnotations() : new Annotation[]{};
+        Annotation[] responseAnns = response.getEntityAnnotations();
+        if (responseAnns != null) {
+            annotations = new Annotation[staticAnns.length + responseAnns.length];
+            System.arraycopy(staticAnns, 0, annotations, 0, staticAnns.length);
+            System.arraycopy(responseAnns, 0, annotations, staticAnns.length, responseAnns.length);
+        } else {
+            annotations = staticAnns;
+        }
+
+        response.setStatus(getActualStatus(response.getStatus(), entity));
+        response.setEntity(entity, annotations);
+
+        // Prepare the headers
+        MultivaluedMap<String, Object> responseHeaders =
+            prepareResponseHeaders(message, response, entity, firstTry);
+
+        // Run the filters
+        try {
+            JAXRSUtils.runContainerResponseFilters(providerFactory, response, message, ori, invoked);
+        } catch (Throwable ex) {
+            handleWriteException(providerFactory, message, ex, firstTry);
+            return;
+        }
+
+        // Write the entity
+        entity = InjectionUtils.getEntity(response.getActualEntity());
+        setResponseStatus(message, getActualStatus(response.getStatus(), entity));
+        if (entity == null) {
+            if (!headResponse) {
+                responseHeaders.putSingle(HttpHeaders.CONTENT_LENGTH, "0");
+                if (MessageUtils.getContextualBoolean(message, "remove.content.type.for.empty.response", false)) {
+                    responseHeaders.remove(HttpHeaders.CONTENT_TYPE);
+                    message.remove(Message.CONTENT_TYPE);
+                }
+            }
+            HttpUtils.convertHeaderValuesToString(responseHeaders, true);
+            return;
+        }
+
+        Object ignoreWritersProp = exchange.get(JAXRSUtils.IGNORE_MESSAGE_WRITERS);
+        boolean ignoreWriters =
+            ignoreWritersProp != null && Boolean.valueOf(ignoreWritersProp.toString());
+        if (ignoreWriters) {
+            writeResponseToStream(message.getContent(OutputStream.class), entity);
+            return;
+        }
+
+        MediaType responseMediaType =
+            getResponseMediaType(responseHeaders.getFirst(HttpHeaders.CONTENT_TYPE));
+
+        Class<?> serviceCls = invoked != null ? ori.getClassResourceInfo().getServiceClass() : null;
+        Class<?> targetType = InjectionUtils.getRawResponseClass(entity);
+        Type genericType = InjectionUtils.getGenericResponseType(invoked, serviceCls,
+                                                                 response.getActualEntity(), targetType, exchange);
+        targetType = InjectionUtils.updateParamClassToTypeIfNeeded(targetType, genericType);
+        annotations = response.getEntityAnnotations();
+
+        List<WriterInterceptor> writers = providerFactory
+            .createMessageBodyWriterInterceptor(targetType, genericType, annotations, responseMediaType, message,
+                                                ori == null ? null : ori.getNameBindings());
+
+        OutputStream outOriginal = message.getContent(OutputStream.class);
+        if (writers == null || writers.isEmpty()) {
+            writeResponseErrorMessage(message, outOriginal, "NO_MSG_WRITER", targetType, responseMediaType);
+            return;
+        }
+        try {
+            boolean checkWriters = false;
+            if (responseMediaType.isWildcardSubtype()) {
+                Produces pM = AnnotationUtils.getMethodAnnotation(ori == null ? null : ori.getAnnotatedMethod(),
+                                                                              Produces.class);
+                Produces pC = AnnotationUtils.getClassAnnotation(serviceCls, Produces.class);
+                checkWriters = pM == null && pC == null;
+            }
+            responseMediaType = checkFinalContentType(responseMediaType, writers, checkWriters);
+        } catch (Throwable ex) {
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.log(Level.FINE, ex.getMessage(), ex);
+            }
+            handleWriteException(providerFactory, message, ex, firstTry);
+            return;
+        }
+        String finalResponseContentType = JAXRSUtils.mediaTypeToString(responseMediaType);
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Response content type is: " + finalResponseContentType);
+        }
+        responseHeaders.putSingle(HttpHeaders.CONTENT_TYPE, finalResponseContentType);
+        message.put(Message.CONTENT_TYPE, finalResponseContentType);
+
+        boolean enabled = checkBufferingMode(message, writers, firstTry);
+        try {
+
+            try {       // NOPMD
+                JAXRSUtils.writeMessageBody(writers,
+                        entity,
+                        targetType,
+                        genericType,
+                        annotations,
+                        responseMediaType,
+                        responseHeaders,
+                        message);
+
+                if (isResponseRedirected(message)) {
+                    return;
+                }
+                checkCachedStream(message, outOriginal, enabled);
+            } finally {
+                if (enabled) {
+                    OutputStream os = message.getContent(OutputStream.class);
+                    if (os != outOriginal && os instanceof CachedOutputStream) {
+                        os.close();
+                    }
+                    message.setContent(OutputStream.class, outOriginal);
+                    message.put(XMLStreamWriter.class.getName(), null);
+                }
+            }
+
+        } catch (Throwable ex) {
+            logWriteError(firstTry, targetType, responseMediaType);
+            handleWriteException(providerFactory, message, ex, firstTry);
+        }
+    }
+
+    private MultivaluedMap<String, Object> prepareResponseHeaders(Message message,
+                                                                  ResponseImpl response,
+                                                                  Object entity,
+                                                                  boolean firstTry) {
+        MultivaluedMap<String, Object> responseHeaders = response.getMetadata();
+        @SuppressWarnings("unchecked")
+        Map<String, List<Object>> userHeaders = (Map<String, List<Object>>)message.get(Message.PROTOCOL_HEADERS);
+        if (firstTry && userHeaders != null) {
+            responseHeaders.putAll(userHeaders);
+        }
+        if (entity != null) {
+            Object customContentType = responseHeaders.getFirst(HttpHeaders.CONTENT_TYPE);
+            if (customContentType == null) {
+                String initialResponseContentType = (String)message.get(Message.CONTENT_TYPE);
+                if (initialResponseContentType != null) {
+                    responseHeaders.putSingle(HttpHeaders.CONTENT_TYPE, initialResponseContentType);
+                }
+            } else {
+                message.put(Message.CONTENT_TYPE, customContentType.toString());
+            }
+        }
+        message.put(Message.PROTOCOL_HEADERS, responseHeaders);
+        setResponseDate(responseHeaders, firstTry);
+        return responseHeaders;
+    }
+
+    private MediaType getResponseMediaType(Object mediaTypeHeader) {
+        MediaType responseMediaType;
+        if (mediaTypeHeader instanceof MediaType) {
+            responseMediaType = (MediaType)mediaTypeHeader;
+        } else {
+            responseMediaType = mediaTypeHeader == null ? MediaType.WILDCARD_TYPE
+                : JAXRSUtils.toMediaType(mediaTypeHeader.toString());
+        }
+        return responseMediaType;
+    }
+
+    private int getActualStatus(int status, Object responseObj) {
+        if (status == -1) {
+            return responseObj == null ? 204 : 200;
+        }
+        return status;
+    }
+
+    private boolean checkBufferingMode(Message m, List<WriterInterceptor> writers, boolean firstTry) {
+        if (!firstTry) {
+            return false;
+        }
+        WriterInterceptor last = writers.get(writers.size() - 1);
+        MessageBodyWriter<Object> w = ((WriterInterceptorMBW)last).getMBW();
+        Object outBuf = m.getContextualProperty(OUT_BUFFERING);
+        boolean enabled = PropertyUtils.isTrue(outBuf);
+        boolean configurableProvider = w instanceof AbstractConfigurableProvider;
+        if (!enabled && outBuf == null && configurableProvider) {
+            enabled = ((AbstractConfigurableProvider)w).getEnableBuffering();
+        }
+        if (enabled) {
+            boolean streamingOn = configurableProvider
+                && ((AbstractConfigurableProvider)w).getEnableStreaming();
+            if (streamingOn) {
+                m.setContent(XMLStreamWriter.class, new CachingXmlEventWriter());
+            } else {
+                m.setContent(OutputStream.class, new CachedOutputStream());
+            }
+        }
+        return enabled;
+    }
+
+    private void checkCachedStream(Message m, OutputStream osOriginal, boolean enabled) throws Exception {
+        final XMLStreamWriter writer;
+        if (enabled) {
+            writer = m.getContent(XMLStreamWriter.class);
+        } else {
+            writer = (XMLStreamWriter)m.get(XMLStreamWriter.class.getName());
+        }
+        if (writer instanceof CachingXmlEventWriter) {
+            CachingXmlEventWriter cache = (CachingXmlEventWriter)writer;
+            if (!cache.getEvents().isEmpty()) {
+                XMLStreamWriter origWriter = null;
+                try {
+                    origWriter = StaxUtils.createXMLStreamWriter(osOriginal);
+                    for (XMLEvent event : cache.getEvents()) {
+                        StaxUtils.writeEvent(event, origWriter);
+                    }
+                } finally {
+                    StaxUtils.close(origWriter);
+                }
+            }
+            m.setContent(XMLStreamWriter.class, null);
+            return;
+        }
+        if (enabled) {
+            OutputStream os = m.getContent(OutputStream.class);
+            if (os != osOriginal && os instanceof CachedOutputStream) {
+                CachedOutputStream cos = (CachedOutputStream)os;
+                if (cos.size() != 0) {
+                    cos.writeCacheTo(osOriginal);
+                }
+            }
+        }
+    }
+
+    private void logWriteError(boolean firstTry, Class<?> cls, MediaType ct) {
+        if (firstTry) {
+            JAXRSUtils.logMessageHandlerProblem("MSG_WRITER_PROBLEM", cls, ct);
+        }
+    }
+
+    private void handleWriteException(ServerProviderFactory pf,
+                                      Message message,
+                                      Throwable ex,
+                                      boolean firstTry) {
+        Response excResponse = null;
+        if (firstTry) {
+            excResponse = JAXRSUtils.convertFaultToResponse(ex, message);
+        } else {
+            message.getExchange().put(JAXRSUtils.SECOND_JAXRS_EXCEPTION, Boolean.TRUE);
+        }
+        if (excResponse == null) {
+            setResponseStatus(message, 500);
+            throw new Fault(ex);
+        }
+        serializeMessage(pf, message, excResponse, null, false);
+
+    }
+
+
+    private void writeResponseErrorMessage(Message message, OutputStream out,
+                                           String name, Class<?> cls, MediaType ct) {
+        message.put(Message.CONTENT_TYPE, "text/plain");
+        message.put(Message.RESPONSE_CODE, 500);
+        try {
+            String errorMessage = JAXRSUtils.logMessageHandlerProblem(name, cls, ct);
+            if (out != null) {
+                out.write(errorMessage.getBytes(StandardCharsets.UTF_8));
+            }
+        } catch (IOException another) {
+            // ignore
+        }
+    }
+
+
+    private MediaType checkFinalContentType(MediaType mt, List<WriterInterceptor> writers, boolean checkWriters) {
+        if (checkWriters) {
+            int mbwIndex = writers.size() == 1 ? 0 : writers.size() - 1;
+            MessageBodyWriter<Object> writer = ((WriterInterceptorMBW)writers.get(mbwIndex)).getMBW();
+            Produces pm = writer.getClass().getAnnotation(Produces.class);
+            if (pm != null) {
+                List<MediaType> sorted =
+                    JAXRSUtils.sortMediaTypes(JAXRSUtils.getMediaTypes(pm.value()), JAXRSUtils.MEDIA_TYPE_QS_PARAM);
+                mt = JAXRSUtils.intersectMimeTypes(sorted, mt).get(0);
+            }
+        }
+        if (mt.isWildcardType() || mt.isWildcardSubtype()) {
+            if ("application".equals(mt.getType()) || mt.isWildcardType()) {
+                mt = MediaType.APPLICATION_OCTET_STREAM_TYPE;
+            } else {
+                throw ExceptionUtils.toNotAcceptableException(null,  null);
+            }
+        }
+        return mt;
+    }
+
+    private void setResponseDate(MultivaluedMap<String, Object> headers, boolean firstTry) {
+        if (!firstTry || headers.containsKey(HttpHeaders.DATE)) {
+            return;
+        }
+        SimpleDateFormat format = HttpUtils.getHttpDateFormat();
+        headers.putSingle(HttpHeaders.DATE, format.format(new Date()));
+    }
+
+    private boolean isResponseAlreadyHandled(Message m) {
+        return isResponseAlreadyCommited(m) || isResponseRedirected(m);
+    }
+
+    private boolean isResponseAlreadyCommited(Message m) {
+        return Boolean.TRUE.equals(m.getExchange().get(AbstractHTTPDestination.RESPONSE_COMMITED));
+    }
+
+    private boolean isResponseRedirected(Message m) {
+        return Boolean.TRUE.equals(m.getExchange().get(AbstractHTTPDestination.REQUEST_REDIRECTED));
+    }
+
+    private void writeResponseToStream(OutputStream os, Object responseObj) {
+        try {
+            byte[] bytes = responseObj.toString().getBytes(StandardCharsets.UTF_8);
+            os.write(bytes, 0, bytes.length);
+        } catch (Exception ex) {
+            LOG.severe("Problem with writing the data to the output stream");
+            ex.printStackTrace();
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private void setResponseStatus(Message message, int status) {
+        message.put(Message.RESPONSE_CODE, status);
+        boolean responseHeadersCopied = isResponseHeadersCopied(message);
+        if (responseHeadersCopied) {
+            HttpServletResponse response =
+                (HttpServletResponse)message.get(AbstractHTTPDestination.HTTP_RESPONSE);
+            response.setStatus(status);
+        }
+    }
+
+    // Some CXF interceptors such as FIStaxOutInterceptor will indirectly initiate
+    // an early copying of response code and headers into the HttpServletResponse
+    // TODO : Pushing the filter processing and copying response headers into say
+    // PRE-LOGICAl and PREPARE_SEND interceptors will most likely be a good thing
+    // however JAX-RS MessageBodyWriters are also allowed to add response headers
+    // which is reason why a MultipartMap parameter in MessageBodyWriter.writeTo
+    // method is modifiable. Thus we do need to know if the initial copy has already
+    // occurred: for now we will just use to ensure the correct status is set
+    private boolean isResponseHeadersCopied(Message message) {
+        return PropertyUtils.isTrue(message.get(AbstractHTTPDestination.RESPONSE_HEADERS_COPIED));
+    }
+
+    public void handleFault(Message message) {
+        // complete
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/model/AbstractResourceInfo.java b/transform/src/patch/java/org/apache/cxf/jaxrs/model/AbstractResourceInfo.java
new file mode 100644
index 0000000..edf010e
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/model/AbstractResourceInfo.java
@@ -0,0 +1,389 @@
+/**
+ * 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.cxf.jaxrs.model;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Context;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ReflectionUtil;
+import org.apache.cxf.jaxrs.impl.tl.ThreadLocalProxy;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+
+public abstract class AbstractResourceInfo {
+    public static final String CONSTRUCTOR_PROXY_MAP = "jaxrs-constructor-proxy-map";
+    private static final Logger LOG = LogUtils.getL7dLogger(AbstractResourceInfo.class);
+    private static final String FIELD_PROXY_MAP = "jaxrs-field-proxy-map";
+    private static final String SETTER_PROXY_MAP = "jaxrs-setter-proxy-map";
+
+    protected boolean root;
+    protected Class<?> resourceClass;
+    protected Class<?> serviceClass;
+
+    private Map<Class<?>, List<Field>> contextFields;
+    private Map<Class<?>, Map<Class<?>, Method>> contextMethods;
+    private Bus bus;
+    private boolean constructorProxiesAvailable;
+    private boolean contextsAvailable;
+
+    protected AbstractResourceInfo(Bus bus) {
+        this.bus = bus;
+    }
+
+    protected AbstractResourceInfo(Class<?> resourceClass, Class<?> serviceClass,
+                                   boolean isRoot, boolean checkContexts, Bus bus) {
+        this(resourceClass, serviceClass, isRoot, checkContexts, null, bus, null);
+    }
+
+    protected AbstractResourceInfo(Class<?> resourceClass,
+                                   Class<?> serviceClass,
+                                   boolean isRoot,
+                                   boolean checkContexts,
+                                   Map<Class<?>, ThreadLocalProxy<?>> constructorProxies,
+                                   Bus bus,
+                                   Object provider) {
+        this.bus = bus;
+        this.serviceClass = serviceClass;
+        this.resourceClass = resourceClass;
+        root = isRoot;
+        if (checkContexts && resourceClass != null) {
+            findContexts(serviceClass, provider, constructorProxies);
+        }
+    }
+
+    private void findContexts(Class<?> cls, Object provider,
+                              Map<Class<?>, ThreadLocalProxy<?>> constructorProxies) {
+        findContextFields(cls, provider);
+        findContextSetterMethods(cls, provider);
+        if (constructorProxies != null) {
+            Map<Class<?>, Map<Class<?>, ThreadLocalProxy<?>>> proxies = getConstructorProxyMap();
+            proxies.put(serviceClass, constructorProxies);
+            constructorProxiesAvailable = true;
+        }
+
+
+        contextsAvailable = contextFields != null && !contextFields.isEmpty()
+            || contextMethods != null && !contextMethods.isEmpty()
+            || constructorProxiesAvailable;
+    }
+
+    public boolean contextsAvailable() {
+        return contextsAvailable;
+    }
+
+    public Bus getBus() {
+        return bus;
+    }
+
+    public void setResourceClass(Class<?> rClass) {
+        resourceClass = rClass;
+        if (serviceClass.isInterface() && resourceClass != null && !resourceClass.isInterface()) {
+            findContexts(resourceClass, null, null);
+        }
+    }
+
+    public Class<?> getServiceClass() {
+        return serviceClass;
+    }
+
+    private void findContextFields(Class<?> cls, Object provider) {
+        if (cls == Object.class || cls == null) {
+            return;
+        }
+        for (Field f : ReflectionUtil.getDeclaredFields(cls)) {
+            for (Annotation a : f.getAnnotations()) {
+                if (a.annotationType() == Context.class
+                    && (f.getType().isInterface() || f.getType() == Application.class)) {
+                    contextFields = addContextField(contextFields, f);
+                    checkContextClass(f.getType());
+                    if (!InjectionUtils.VALUE_CONTEXTS.contains(f.getType().getName())) {
+                        addToMap(getFieldProxyMap(true), f, getFieldThreadLocalProxy(f, provider));
+                    }
+                }
+            }
+        }
+        findContextFields(cls.getSuperclass(), provider);
+    }
+
+    private static ThreadLocalProxy<?> getFieldThreadLocalProxy(Field f, Object provider) {
+        if (provider != null) {
+            Object proxy = null;
+            synchronized (provider) {
+                try {
+                    proxy = InjectionUtils.extractFieldValue(f, provider);
+                } catch (Throwable t) {
+                    // continue
+                }
+                if (!(proxy instanceof ThreadLocalProxy)) {
+                    proxy = InjectionUtils.createThreadLocalProxy(f.getType());
+                    InjectionUtils.injectFieldValue(f, provider, proxy);
+                }
+            }
+            return (ThreadLocalProxy<?>)proxy;
+        }
+        return InjectionUtils.createThreadLocalProxy(f.getType());
+    }
+
+    private static ThreadLocalProxy<?> getMethodThreadLocalProxy(Method m, Object provider) {
+        if (provider != null) {
+            Object proxy = null;
+            synchronized (provider) {
+                try {
+                    proxy = InjectionUtils.extractFromMethod(provider,
+                                                             InjectionUtils.getGetterFromSetter(m),
+                                                             false);
+                } catch (Throwable t) {
+                    // continue
+                }
+                if (!(proxy instanceof ThreadLocalProxy)) {
+                    proxy = InjectionUtils.createThreadLocalProxy(m.getParameterTypes()[0]);
+                    InjectionUtils.injectThroughMethod(provider, m, proxy);
+                }
+            }
+            return (ThreadLocalProxy<?>)proxy;
+        }
+        return InjectionUtils.createThreadLocalProxy(m.getParameterTypes()[0]);
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> Map<Class<?>, Map<T, ThreadLocalProxy<?>>> getProxyMap(String prop, boolean create) {
+        // Avoid synchronizing on the bus for a ConcurrentHashMAp
+        if (bus.getProperties() instanceof ConcurrentHashMap) {
+            return (Map<Class<?>, Map<T, ThreadLocalProxy<?>>>) bus.getProperties().computeIfAbsent(prop, k ->
+                new ConcurrentHashMap<Class<?>, Map<T, ThreadLocalProxy<?>>>(2)
+            );
+        }
+
+        Object property;
+        synchronized (bus) {
+            property = bus.getProperty(prop);
+            if (property == null && create) {
+                Map<Class<?>, Map<T, ThreadLocalProxy<?>>> map
+                    = new ConcurrentHashMap<>(2);
+                bus.setProperty(prop, map);
+                property = map;
+            }
+        }
+        return (Map<Class<?>, Map<T, ThreadLocalProxy<?>>>)property;
+    }
+
+    public Map<Class<?>, ThreadLocalProxy<?>> getConstructorProxies() {
+        if (constructorProxiesAvailable) {
+            return getConstructorProxyMap().get(serviceClass);
+        }
+        return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<Class<?>, Map<Class<?>, ThreadLocalProxy<?>>> getConstructorProxyMap() {
+        Object property = bus.getProperty(CONSTRUCTOR_PROXY_MAP);
+        if (property == null) {
+            Map<Class<?>, Map<Class<?>, ThreadLocalProxy<?>>> map
+                = new ConcurrentHashMap<>(2);
+            bus.setProperty(CONSTRUCTOR_PROXY_MAP, map);
+            property = map;
+        }
+        return (Map<Class<?>, Map<Class<?>, ThreadLocalProxy<?>>>)property;
+    }
+
+    private Map<Class<?>, Map<Field, ThreadLocalProxy<?>>> getFieldProxyMap(boolean create) {
+        return getProxyMap(FIELD_PROXY_MAP, create);
+    }
+
+    private Map<Class<?>, Map<Method, ThreadLocalProxy<?>>> getSetterProxyMap(boolean create) {
+        return getProxyMap(SETTER_PROXY_MAP, create);
+    }
+
+    private void findContextSetterMethods(Class<?> cls, Object provider) {
+
+        for (Method m : cls.getMethods()) {
+
+            if (!m.getName().startsWith("set") || m.getParameterTypes().length != 1) {
+                continue;
+            }
+            for (Annotation a : m.getAnnotations()) {
+                if (a.annotationType() == Context.class) {
+                    checkContextMethod(m, provider);
+                    break;
+                }
+            }
+        }
+        Class<?>[] interfaces = cls.getInterfaces();
+        for (Class<?> i : interfaces) {
+            findContextSetterMethods(i, provider);
+        }
+        Class<?> superCls = cls.getSuperclass();
+        if (superCls != null && superCls != Object.class) {
+            findContextSetterMethods(superCls, provider);
+        }
+    }
+
+    private void checkContextMethod(Method m, Object provider) {
+        Class<?> type = m.getParameterTypes()[0];
+        if (type.isInterface() || type == Application.class) {
+            checkContextClass(type);
+            addContextMethod(type, m, provider);
+        }
+    }
+    private void checkContextClass(Class<?> type) {
+        if (!InjectionUtils.STANDARD_CONTEXT_CLASSES.contains(type.getName())) {
+            LOG.fine("Injecting a custom context " + type.getName()
+                     + ", ContextProvider is required for this type");
+        }
+    }
+
+    public Map<Class<?>, Method> getContextMethods() {
+        Map<Class<?>, Method> methods = contextMethods == null ? null : contextMethods.get(getServiceClass());
+        return methods == null ? Collections.emptyMap()
+                                      : Collections.unmodifiableMap(methods);
+    }
+
+    private void addContextMethod(Class<?> contextClass, Method m, Object provider) {
+        if (contextMethods == null) {
+            contextMethods = new HashMap<>();
+        }
+        addToMap(contextMethods, contextClass, m);
+        if (!InjectionUtils.VALUE_CONTEXTS.contains(m.getParameterTypes()[0].getName())) {
+            addToMap(getSetterProxyMap(true), m, getMethodThreadLocalProxy(m, provider));
+        }
+    }
+
+    public boolean isRoot() {
+        return root;
+    }
+
+    public Class<?> getResourceClass() {
+        return resourceClass;
+    }
+
+    public List<Field> getContextFields() {
+        return getList(contextFields);
+    }
+
+    public ThreadLocalProxy<?> getContextFieldProxy(Field f) {
+        return getProxy(getFieldProxyMap(true), f);
+    }
+
+    public ThreadLocalProxy<?> getContextSetterProxy(Method m) {
+        return getProxy(getSetterProxyMap(true), m);
+    }
+
+    public abstract boolean isSingleton();
+
+    @SuppressWarnings("rawtypes")
+    public static void clearAllMaps() {
+        Bus bus = BusFactory.getThreadDefaultBus(false);
+        if (bus != null) {
+            Object property = bus.getProperty(FIELD_PROXY_MAP);
+            if (property != null) {
+                ((Map)property).clear();
+            }
+            property = bus.getProperty(SETTER_PROXY_MAP);
+            if (property != null) {
+                ((Map)property).clear();
+            }
+            property = bus.getProperty(CONSTRUCTOR_PROXY_MAP);
+            if (property != null) {
+                ((Map)property).clear();
+            }
+        }
+    }
+
+    public void clearThreadLocalProxies() {
+        clearProxies(getFieldProxyMap(false));
+        clearProxies(getSetterProxyMap(false));
+        clearProxies(getConstructorProxyMap());
+    }
+
+    private <T> void clearProxies(Map<Class<?>, Map<T, ThreadLocalProxy<?>>> tlps) {
+        Map<T, ThreadLocalProxy<?>> proxies = tlps == null ? null : tlps.get(getServiceClass());
+        if (proxies == null) {
+            return;
+        }
+        for (ThreadLocalProxy<?> tlp : proxies.values()) {
+            if (tlp != null) {
+                tlp.remove();
+            }
+        }
+    }
+
+    private Map<Class<?>, List<Field>> addContextField(Map<Class<?>, List<Field>> theFields, Field f) {
+        if (theFields == null) {
+            theFields = new HashMap<>();
+        }
+
+        List<Field> fields = theFields.get(serviceClass);
+        if (fields == null) {
+            fields = new ArrayList<>();
+            theFields.put(serviceClass, fields);
+        }
+        if (!fields.contains(f)) {
+            fields.add(f);
+        }
+        return theFields;
+    }
+
+    private <T, V> void addToMap(Map<Class<?>, Map<T, V>> proxyMap,
+                                 T f,
+                                 V proxy) {
+        Map<T, V> proxies = proxyMap.get(serviceClass);
+        if (proxies == null) {
+            proxies = new ConcurrentHashMap<>();
+            proxyMap.put(serviceClass, proxies);
+        }
+        if (!proxies.containsKey(f)) {
+            proxies.put(f, proxy);
+        }
+    }
+
+    private List<Field> getList(Map<Class<?>, List<Field>> fields) {
+        List<Field> ret = fields == null ? null : fields.get(getServiceClass());
+        if (ret != null) {
+            ret = Collections.unmodifiableList(ret);
+        } else {
+            ret = Collections.emptyList();
+        }
+        return ret;
+    }
+
+    private <T> ThreadLocalProxy<?> getProxy(Map<Class<?>, Map<T, ThreadLocalProxy<?>>> proxies,
+                                             T key) {
+
+        Map<?, ThreadLocalProxy<?>> theMap = proxies == null ? null : proxies.get(getServiceClass());
+        ThreadLocalProxy<?> ret = null;
+        if (theMap != null) {
+            ret = theMap.get(key);
+        }
+        return ret;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java b/transform/src/patch/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java
new file mode 100644
index 0000000..a69cac1
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java
@@ -0,0 +1,366 @@
+/**
+ * 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.cxf.jaxrs.model;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.ws.rs.BeanParam;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.util.ClassHelper;
+import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.apache.cxf.message.Message;
+
+public class ClassResourceInfo extends BeanResourceInfo {
+
+    private URITemplate uriTemplate;
+    private MethodDispatcher methodDispatcher;
+    private ResourceProvider resourceProvider;
+    private ConcurrentHashMap<SubresourceKey, ClassResourceInfo> subResources
+        = new ConcurrentHashMap<>();
+
+    private boolean enableStatic;
+    private boolean createdFromModel;
+    private String consumesTypes;
+    private String producesTypes;
+    private List<MediaType> defaultConsumes = Collections.singletonList(JAXRSUtils.ALL_TYPES);
+    private List<MediaType> defaultProduces = Collections.singletonList(JAXRSUtils.ALL_TYPES);
+    private Set<String> nameBindings = Collections.emptySet();
+    private ClassResourceInfo parent;
+    private Set<String> injectedSubInstances = new HashSet<>();
+    public ClassResourceInfo(ClassResourceInfo cri) {
+        super(cri.getBus());
+        if (cri.isCreatedFromModel() && !InjectionUtils.isConcreteClass(cri.getServiceClass())) {
+            this.root = cri.root;
+            this.serviceClass = cri.serviceClass;
+            this.uriTemplate = cri.uriTemplate;
+            this.methodDispatcher = new MethodDispatcher(cri.methodDispatcher, this);
+            this.subResources = cri.subResources;
+            //CHECKSTYLE:OFF
+            this.paramFields = cri.paramFields;
+            this.paramMethods = cri.paramMethods;
+            //CHECKSTYLE:ON
+            this.enableStatic = true;
+            this.nameBindings = cri.nameBindings;
+            this.parent = cri.parent;
+        } else {
+            throw new IllegalArgumentException();
+        }
+
+    }
+
+    public ClassResourceInfo(Class<?> theResourceClass, Class<?> theServiceClass,
+                             boolean theRoot, boolean enableStatic, Bus bus) {
+        super(theResourceClass, theServiceClass, theRoot, theRoot || enableStatic, bus);
+        this.enableStatic = enableStatic;
+        if (resourceClass != null) {
+            nameBindings = AnnotationUtils.getNameBindings(bus, serviceClass);
+        }
+    }
+    //CHECKSTYLE:OFF
+    public ClassResourceInfo(Class<?> theResourceClass, Class<?> theServiceClass,
+                             boolean theRoot, boolean enableStatic, Bus bus, List<MediaType> defaultProduces,
+                             List<MediaType> defaultConsumes) {
+    //CHECKSTYLE:ON
+        this(theResourceClass, theServiceClass, theRoot, enableStatic, bus);
+        if (defaultProduces != null) {
+            this.defaultProduces = defaultProduces;
+        }
+        if (defaultConsumes != null) {
+            this.defaultConsumes = defaultConsumes;
+        }
+    }
+    public ClassResourceInfo(Class<?> theResourceClass, Class<?> theServiceClass,
+                             boolean theRoot, boolean enableStatic, boolean createdFromModel, Bus bus) {
+        this(theResourceClass, theServiceClass, theRoot, enableStatic, bus);
+        this.createdFromModel = createdFromModel;
+    }
+    //CHECKSTYLE:OFF
+    public ClassResourceInfo(Class<?> theResourceClass, Class<?> theServiceClass,
+                             boolean theRoot, boolean enableStatic, boolean createdFromModel,
+                             String consumesTypes, String producesTypes, Bus bus) {
+    //CHECKSTYLE:ON
+        this(theResourceClass, theServiceClass, theRoot, enableStatic, createdFromModel, bus);
+        this.consumesTypes = consumesTypes;
+        this.producesTypes = producesTypes;
+    }
+
+    // The following constructors are used by tests only
+    public ClassResourceInfo(Class<?> theResourceClass) {
+        this(theResourceClass, true);
+    }
+
+    public ClassResourceInfo(Class<?> theResourceClass, boolean theRoot) {
+        this(theResourceClass, theResourceClass, theRoot);
+    }
+
+    public ClassResourceInfo(Class<?> theResourceClass, Class<?> theServiceClass) {
+        this(theResourceClass, theServiceClass, false);
+    }
+
+    public ClassResourceInfo(Class<?> theResourceClass, Class<?> theServiceClass, boolean theRoot) {
+        this(theResourceClass, theServiceClass, theRoot, false, BusFactory.getDefaultBus(true));
+    }
+
+    public ClassResourceInfo findResource(Class<?> typedClass, Class<?> instanceClass) {
+        instanceClass = enableStatic ? typedClass : instanceClass;
+        SubresourceKey key = new SubresourceKey(typedClass, instanceClass);
+        return subResources.get(key);
+    }
+
+    @Override
+    public boolean contextsAvailable() {
+        // avoid re-injecting the contexts if the root acts as subresource
+        return super.contextsAvailable() && (isRoot() || parent != null);
+    }
+
+    public ClassResourceInfo getSubResource(Class<?> typedClass, Class<?> instanceClass) {
+        return getSubResource(typedClass, instanceClass, null, enableStatic, null);
+    }
+
+    public ClassResourceInfo getSubResource(Class<?> typedClass, Class<?> instanceClass, Object instance) {
+        instanceClass = enableStatic && typedClass != Object.class ? typedClass : instanceClass;
+        return getSubResource(typedClass, instanceClass, instance, enableStatic, JAXRSUtils.getCurrentMessage());
+    }
+
+    public ClassResourceInfo getSubResource(Class<?> typedClass,
+                                            Class<?> instanceClass,
+                                            Object instance,
+                                            boolean resolveContexts,
+                                            Message message) {
+
+        SubresourceKey key = new SubresourceKey(typedClass, instanceClass);
+        ClassResourceInfo cri = subResources.get(key);
+        if (cri == null) {
+            cri = ResourceUtils.createClassResourceInfo(typedClass, instanceClass, this, false, resolveContexts,
+                                                        getBus());
+            if (cri != null) {
+                if (message != null) {
+                    cri.initBeanParamInfo(ServerProviderFactory.getInstance(message));
+                }
+                subResources.putIfAbsent(key, cri);
+            }
+        }
+        // this branch will run only if ResourceContext is used
+        // or static resolution is enabled for subresources initialized
+        // from within singleton root resources (not default)
+        if (resolveContexts && cri != null && cri.isSingleton() && instance != null && cri.contextsAvailable()) {
+            synchronized (this) {
+                if (!injectedSubInstances.contains(instance.toString())) {
+                    Application app = null;
+                    if (message != null) {
+                        ProviderInfo<?> appProvider =
+                            (ProviderInfo<?>)message.getExchange().getEndpoint().get(Application.class.getName());
+                        if (appProvider != null) {
+                            app = (Application)appProvider.getProvider();
+                        }
+                    }
+                    InjectionUtils.injectContextProxiesAndApplication(cri, instance, app, null);
+                    injectedSubInstances.add(instance.toString());
+                }
+            }
+        }
+
+        return cri;
+    }
+
+    public void addSubClassResourceInfo(ClassResourceInfo cri) {
+        subResources.putIfAbsent(new SubresourceKey(cri.getResourceClass(),
+                                            cri.getServiceClass()),
+                                 cri);
+    }
+
+    public Collection<ClassResourceInfo> getSubResources() {
+        return Collections.unmodifiableCollection(subResources.values());
+    }
+
+    public Set<String> getNameBindings() {
+        if (parent == null) {
+            return nameBindings;
+        }
+        return parent.getNameBindings();
+    }
+
+    public void setNameBindings(Set<String> names) {
+        nameBindings = names;
+    }
+
+    public Set<String> getAllowedMethods() {
+        Set<String> methods = new HashSet<>();
+        for (OperationResourceInfo o : methodDispatcher.getOperationResourceInfos()) {
+            String method = o.getHttpMethod();
+            if (method != null) {
+                methods.add(method);
+            }
+        }
+        return methods;
+    }
+
+
+
+    public URITemplate getURITemplate() {
+        return uriTemplate;
+    }
+
+    public void setURITemplate(URITemplate u) {
+        uriTemplate = u;
+    }
+
+    public MethodDispatcher getMethodDispatcher() {
+        return methodDispatcher;
+    }
+
+    public void setMethodDispatcher(MethodDispatcher md) {
+        methodDispatcher = md;
+    }
+
+    public boolean hasSubResources() {
+        return !subResources.isEmpty();
+    }
+
+
+    public boolean isCreatedFromModel() {
+        return createdFromModel;
+    }
+
+    public ResourceProvider getResourceProvider() {
+        return resourceProvider;
+    }
+
+    public void setResourceProvider(ResourceProvider rp) {
+        resourceProvider = rp;
+    }
+
+    public List<MediaType> getProduceMime() {
+        if (producesTypes != null) {
+            return JAXRSUtils.parseMediaTypes(producesTypes);
+        }
+        Produces produces = AnnotationUtils.getClassAnnotation(getServiceClass(), Produces.class);
+        if (produces != null || parent == null) {
+            return JAXRSUtils.getProduceTypes(produces, defaultProduces);
+        }
+        return parent.getProduceMime();
+    }
+
+    public List<MediaType> getConsumeMime() {
+        if (consumesTypes != null) {
+            return JAXRSUtils.parseMediaTypes(consumesTypes);
+        }
+        Consumes consumes = AnnotationUtils.getClassAnnotation(getServiceClass(), Consumes.class);
+        if (consumes != null || parent == null) {
+            return JAXRSUtils.getConsumeTypes(consumes, defaultConsumes);
+        }
+        return parent.getConsumeMime();
+    }
+
+    public Path getPath() {
+        return AnnotationUtils.getClassAnnotation(getServiceClass(), Path.class);
+    }
+
+    @Override
+    public boolean isSingleton() {
+        if (parent == null) {
+            return resourceProvider != null && resourceProvider.isSingleton();
+        }
+        return parent.isSingleton();
+    }
+
+    public void setParent(ClassResourceInfo parent) {
+        this.parent = parent;
+    }
+
+    public ClassResourceInfo getParent() {
+        return parent;
+    }
+
+    public void initBeanParamInfo(ServerProviderFactory factory) {
+        if (factory != null) {
+            Set<OperationResourceInfo> oris = getMethodDispatcher().getOperationResourceInfos();
+            for (OperationResourceInfo ori : oris) {
+                List<Parameter> params = ori.getParameters();
+                for (Parameter param : params) {
+                    if (param.getType() == ParameterType.BEAN) {
+                        Class<?> cls = ori.getMethodToInvoke().getParameterTypes()[param.getIndex()];
+                        BeanParamInfo bpi = new BeanParamInfo(cls, getBus());
+                        factory.addBeanParamInfo(bpi);
+                    }
+                }
+            }
+            List<Method> methods = super.getParameterMethods();
+            for (Method m : methods) {
+                if (m.getAnnotation(BeanParam.class) != null) {
+                    BeanParamInfo bpi = new BeanParamInfo(m.getParameterTypes()[0], getBus());
+                    factory.addBeanParamInfo(bpi);
+                }
+            }
+            List<Field> fields = super.getParameterFields();
+            for (Field f : fields) {
+                if (f.getAnnotation(BeanParam.class) != null) {
+                    BeanParamInfo bpi = new BeanParamInfo(f.getType(), getBus());
+                    factory.addBeanParamInfo(bpi);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void clearThreadLocalProxies() {
+        super.clearThreadLocalProxies();
+        if (!injectedSubInstances.isEmpty()) {
+            for (ClassResourceInfo sub : subResources.values()) {
+                if (sub != this) {
+                    sub.clearThreadLocalProxies();
+                }
+            }
+        }
+    }
+
+    public void injectContexts(Object resourceObject, OperationResourceInfo ori, Message inMessage) {
+        final boolean contextsAvailable = contextsAvailable();
+        final boolean paramsAvailable = paramsAvailable();
+        if (contextsAvailable || paramsAvailable) {
+            Object realResourceObject = ClassHelper.getRealObject(resourceObject);
+            if (paramsAvailable) {
+                JAXRSUtils.injectParameters(ori, this, realResourceObject, inMessage);
+            }
+            if (contextsAvailable) {
+                InjectionUtils.injectContexts(realResourceObject, this, inMessage);
+            }
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/model/URITemplate.java b/transform/src/patch/java/org/apache/cxf/jaxrs/model/URITemplate.java
new file mode 100644
index 0000000..85fdd7e
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/model/URITemplate.java
@@ -0,0 +1,627 @@
+/**
+ * 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.cxf.jaxrs.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.PathSegment;
+
+import org.apache.cxf.common.util.SystemPropertyAction;
+import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+
+public final class URITemplate {
+
+    public static final String TEMPLATE_PARAMETERS = "jaxrs.template.parameters";
+    public static final String URI_TEMPLATE = "jaxrs.template.uri";
+    public static final String LIMITED_REGEX_SUFFIX = "(/.*)?";
+    public static final String FINAL_MATCH_GROUP = "FINAL_MATCH_GROUP";
+    private static final String DEFAULT_PATH_VARIABLE_REGEX = "([^/]+?)";
+    private static final String CHARACTERS_TO_ESCAPE = ".*+$()";
+    private static final String SLASH = "/";
+    private static final String SLASH_QUOTE = "/;";
+    private static final int MAX_URI_TEMPLATE_CACHE_SIZE = 
+        SystemPropertyAction.getInteger("org.apache.cxf.jaxrs.max_uri_template_cache_size", 2000);
+    private static final Map<String, URITemplate> URI_TEMPLATE_CACHE = new ConcurrentHashMap<>();
+    
+    private final String template;
+    private final List<String> variables = new ArrayList<>();
+    private final List<String> customVariables = new ArrayList<>();
+    private final Pattern templateRegexPattern;
+    private final String literals;
+    private final List<UriChunk> uriChunks;
+
+    public URITemplate(String theTemplate) {
+        template = theTemplate;
+        StringBuilder literalChars = new StringBuilder();
+        StringBuilder patternBuilder = new StringBuilder();
+        CurlyBraceTokenizer tok = new CurlyBraceTokenizer(template);
+        uriChunks = new ArrayList<>();
+        while (tok.hasNext()) {
+            String templatePart = tok.next();
+            UriChunk chunk = UriChunk.createUriChunk(templatePart);
+            uriChunks.add(chunk);
+            if (chunk instanceof Literal) {
+                String encodedValue = HttpUtils.encodePartiallyEncoded(chunk.getValue(), false);
+                String substr = escapeCharacters(encodedValue);
+                literalChars.append(substr);
+                patternBuilder.append(substr);
+            } else if (chunk instanceof Variable) {
+                Variable var = (Variable)chunk;
+                variables.add(var.getName());
+                String pattern = var.getPattern();
+                if (pattern != null) {
+                    customVariables.add(var.getName());
+                    // Add parenthesis to the pattern to identify a regex in the pattern, 
+                    // however do not add them if they already exist since that will cause the Matcher
+                    // to create extraneous values.  Parens identify a group so multiple parens would
+                    // indicate multiple groups.
+                    if (pattern.startsWith("(") && pattern.endsWith(")")) {
+                        patternBuilder.append(pattern);
+                    } else {
+                        patternBuilder.append('(');
+                        patternBuilder.append(pattern);
+                        patternBuilder.append(')');
+                    }
+                } else {
+                    patternBuilder.append(DEFAULT_PATH_VARIABLE_REGEX);
+                }
+            }
+        }
+        literals = literalChars.toString();
+
+        int endPos = patternBuilder.length() - 1;
+        boolean endsWithSlash = (endPos >= 0) && patternBuilder.charAt(endPos) == '/';
+        if (endsWithSlash) {
+            patternBuilder.deleteCharAt(endPos);
+        }
+        patternBuilder.append(LIMITED_REGEX_SUFFIX);
+
+        templateRegexPattern = Pattern.compile(patternBuilder.toString());
+    }
+
+    public String getLiteralChars() {
+        return literals;
+    }
+
+    public String getValue() {
+        return template;
+    }
+
+    public String getPatternValue() {
+        return templateRegexPattern.toString();
+    }
+
+    /**
+     * List of all variables in order of appearance in template.
+     *
+     * @return unmodifiable list of variable names w/o patterns, e.g. for "/foo/{v1:\\d}/{v2}" returned list
+     *         is ["v1","v2"].
+     */
+    public List<String> getVariables() {
+        return Collections.unmodifiableList(variables);
+    }
+
+    /**
+     * List of variables with patterns (regexps). List is subset of elements from {@link #getVariables()}.
+     *
+     * @return unmodifiable list of variables names w/o patterns.
+     */
+    public List<String> getCustomVariables() {
+        return Collections.unmodifiableList(customVariables);
+    }
+
+    private static String escapeCharacters(String expression) {
+
+        int length = expression.length();
+        int i = 0;
+        char ch = ' ';
+        for (; i < length; ++i) {
+            ch = expression.charAt(i);
+            if (isReservedCharacter(ch)) {
+                break;
+            }
+        }
+
+        if (i == length) {
+            return expression;
+        }
+
+        // Allows for up to 8 escaped characters before we start creating more
+        // StringBuilders. 8 is an arbitrary limit, but it seems to be
+        // sufficient in most cases.
+        StringBuilder sb = new StringBuilder(length + 8);
+        sb.append(expression, 0, i);
+        sb.append('\\');
+        sb.append(ch);
+        ++i;
+        for (; i < length; ++i) {
+            ch = expression.charAt(i);
+            if (isReservedCharacter(ch)) {
+                sb.append('\\');
+            }
+            sb.append(ch);
+        }
+        return sb.toString();
+    }
+
+    private static boolean isReservedCharacter(char ch) {
+        return CHARACTERS_TO_ESCAPE.indexOf(ch) != -1;
+    }
+
+    public boolean match(String uri, MultivaluedMap<String, String> templateVariableToValue) {
+
+        if (uri == null) {
+            return (templateRegexPattern == null) ? true : false;
+        }
+
+        if (templateRegexPattern == null) {
+            return false;
+        }
+
+        Matcher m = templateRegexPattern.matcher(uri);
+        if (!m.matches() || template.equals(SLASH) && uri.startsWith(SLASH_QUOTE)) {
+            if (uri.contains(";")) {
+                // we might be trying to match one or few path segments
+                // containing matrix
+                // parameters against a clear path segment as in @Path("base").
+                List<PathSegment> pList = JAXRSUtils.getPathSegments(template, false);
+                List<PathSegment> uList = JAXRSUtils.getPathSegments(uri, false);
+                StringBuilder sb = new StringBuilder();
+                for (int i = 0; i < uList.size(); i++) {
+                    final String segment;
+                    if (pList.size() > i && pList.get(i).getPath().indexOf('{') == -1) {
+                        segment = uList.get(i).getPath();
+                    } else {
+                        segment = HttpUtils.fromPathSegment(uList.get(i));
+                    }
+                    if (!segment.isEmpty()) {
+                        sb.append(SLASH);
+                    }
+                    sb.append(segment);
+                }
+                uri = sb.toString();
+                if (uri.isEmpty()) {
+                    uri = SLASH;
+                }
+                m = templateRegexPattern.matcher(uri);
+                if (!m.matches()) {
+                    return false;
+                }
+            } else {
+                return false;
+            }
+        }
+
+        // Assign the matched template values to template variables
+        int groupCount = m.groupCount();
+
+        int i = 1;
+        for (String name : variables) {
+            while (i <= groupCount) {
+                String value = m.group(i++);
+                if ((value == null || value.length() == 0 && i < groupCount)
+                    && variables.size() + 1 < groupCount) {
+                    continue;
+                }
+                templateVariableToValue.add(name, value);
+                break;
+            }
+        }
+        // The right hand side value, might be used to further resolve
+        // sub-resources.
+
+        String finalGroup = i > groupCount ? SLASH : m.group(groupCount);
+        if (finalGroup == null || finalGroup.startsWith(SLASH_QUOTE)) {
+            finalGroup = SLASH;
+        }
+
+        templateVariableToValue.putSingle(FINAL_MATCH_GROUP, finalGroup);
+
+        return true;
+    }
+
+    /**
+     * Substitutes template variables with listed values. List of values is counterpart for
+     * {@link #getVariables() list of variables}. When list of value is shorter than variables substitution
+     * is partial. When variable has pattern, value must fit to pattern, otherwise
+     * {@link IllegalArgumentException} is thrown.
+     * <p>
+     * Example1: for template "/{a}/{b}/{a}" {@link #getVariables()} returns "[a, b, a]"; providing here list
+     * of value "[foo, bar, baz]" results with "/foo/bar/baz".
+     * <p>
+     * Example2: for template "/{a}/{b}/{a}" providing list of values "[foo]" results with "/foo/{b}/{a}".
+     *
+     * @param values values for variables
+     * @return template with bound variables.
+     * @throws IllegalArgumentException when values is null, any value does not match pattern etc.
+     */
+    public String substitute(List<String> values) throws IllegalArgumentException {
+        if (values == null) {
+            throw new IllegalArgumentException("values is null");
+        }
+        Iterator<String> iter = values.iterator();
+        StringBuilder sb = new StringBuilder();
+        for (UriChunk chunk : uriChunks) {
+            if (chunk instanceof Variable) {
+                Variable var = (Variable)chunk;
+                if (iter.hasNext()) {
+                    String value = iter.next();
+                    if (!var.matches(value)) {
+                        throw new IllegalArgumentException("Value '" + value + "' does not match variable "
+                                                           + var.getName() + " with pattern "
+                                                           + var.getPattern());
+                    }
+                    sb.append(value);
+                } else {
+                    sb.append(var);
+                }
+            } else {
+                sb.append(chunk);
+            }
+        }
+        return sb.toString();
+    }
+
+    String substitute(Map<String, ? extends Object> valuesMap) throws IllegalArgumentException {
+        return this.substitute(valuesMap, Collections.<String>emptySet(), false);
+    }
+
+    /**
+     * Substitutes template variables with mapped values. Variables are mapped to values; if not all variables
+     * are bound result will still contain variables. Note that all variables with the same name are replaced
+     * by one value.
+     * <p>
+     * Example: for template "/{a}/{b}/{a}" {@link #getVariables()} returns "[a, b, a]"; providing here
+     * mapping "[a: foo, b: bar]" results with "/foo/bar/foo" (full substitution) and for mapping "[b: baz]"
+     * result is "{a}/baz/{a}" (partial substitution).
+     *
+     * @param valuesMap map variables to their values; on each value Object.toString() is called.
+     * @return template with bound variables.
+     */
+    public String substitute(Map<String, ? extends Object> valuesMap,
+                             Set<String> encodePathSlashVars,
+                             boolean allowUnresolved) throws IllegalArgumentException {
+        if (valuesMap == null) {
+            throw new IllegalArgumentException("valuesMap is null");
+        }
+        StringBuilder sb = new StringBuilder();
+        for (UriChunk chunk : uriChunks) {
+            if (chunk instanceof Variable) {
+                Variable var = (Variable)chunk;
+                Object value = valuesMap.get(var.getName());
+                if (value != null) {
+                    String sval = value.toString();
+                    if (!var.matches(sval)) {
+                        throw new IllegalArgumentException("Value '" + sval + "' does not match variable "
+                                                           + var.getName() + " with pattern "
+                                                           + var.getPattern());
+                    }
+                    if (encodePathSlashVars.contains(var.getName())) {
+                        sval = sval.replaceAll("/", "%2F");
+                    }
+                    sb.append(sval);
+                } else if (allowUnresolved) {
+                    sb.append(chunk);
+                } else {
+                    throw new IllegalArgumentException("Template variable " + var.getName()
+                                                       + " has no matching value");
+                }
+            } else {
+                sb.append(chunk);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Encoded literal characters surrounding template variables,
+     * ex. "a {id} b" will be encoded to "a%20{id}%20b"
+     * @return encoded value
+     */
+    public String encodeLiteralCharacters(boolean isQuery) {
+        final float encodedRatio = 1.5f;
+        StringBuilder sb = new StringBuilder((int)(encodedRatio * template.length()));
+        for (UriChunk chunk : uriChunks) {
+            String val = chunk.getValue();
+            if (chunk instanceof Literal) {
+                sb.append(HttpUtils.encodePartiallyEncoded(val, isQuery));
+            } else {
+                sb.append(val);
+            }
+        }
+        return sb.toString();
+    }
+
+    public static URITemplate createTemplate(Path path) {
+
+        return createTemplate(path == null ? null : path.value());
+    }
+
+    public static URITemplate createTemplate(String pathValue) {
+        if (pathValue == null) {
+            pathValue = "/";
+        } else if (!pathValue.startsWith("/")) {
+            pathValue = "/" + pathValue;
+        }
+        return createExactTemplate(pathValue);
+    }
+    
+    public static URITemplate createExactTemplate(String pathValue) {
+        URITemplate template = URI_TEMPLATE_CACHE.get(pathValue);
+        if (template == null) {
+            template = new URITemplate(pathValue);
+            if (URI_TEMPLATE_CACHE.size() >= MAX_URI_TEMPLATE_CACHE_SIZE) {
+                URI_TEMPLATE_CACHE.clear();
+            }
+            URI_TEMPLATE_CACHE.put(pathValue, template);
+        }
+        return template;
+    }
+    
+    public static int compareTemplates(URITemplate t1, URITemplate t2) {
+        int l1 = t1.getLiteralChars().length();
+        int l2 = t2.getLiteralChars().length();
+        // descending order
+        int result = l1 < l2 ? 1 : l1 > l2 ? -1 : 0;
+        if (result == 0) {
+            int g1 = t1.getVariables().size();
+            int g2 = t2.getVariables().size();
+            // descending order
+            result = g1 < g2 ? 1 : g1 > g2 ? -1 : 0;
+            if (result == 0) {
+                int gCustom1 = t1.getCustomVariables().size();
+                int gCustom2 = t2.getCustomVariables().size();
+                result = gCustom1 < gCustom2 ? 1 : gCustom1 > gCustom2 ? -1 : 0;
+                if (result == 0) {
+                    result = t1.getPatternValue().compareTo(t2.getPatternValue());
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Stringified part of URI. Chunk is not URI segment; chunk can span over multiple URI segments or one URI
+     * segments can have multiple chunks. Chunk is used to decompose URI of {@link URITemplate} into literals
+     * and variables. Example: "foo/bar/{baz}{blah}" is decomposed into chunks: "foo/bar", "{baz}" and
+     * "{blah}".
+     */
+    private abstract static class UriChunk {
+        /**
+         * Creates object form string.
+         *
+         * @param uriChunk stringified uri chunk
+         * @return If param has variable form then {@link Variable} instance is created, otherwise chunk is
+         *         treated as {@link Literal}.
+         */
+        public static UriChunk createUriChunk(String uriChunk) {
+            if (uriChunk == null || "".equals(uriChunk)) {
+                throw new IllegalArgumentException("uriChunk is empty");
+            }
+            UriChunk uriChunkRepresentation = Variable.create(uriChunk);
+            if (uriChunkRepresentation == null) {
+                uriChunkRepresentation = Literal.create(uriChunk);
+            }
+            return uriChunkRepresentation;
+        }
+
+        public abstract String getValue();
+
+        @Override
+        public String toString() {
+            return getValue();
+        }
+    }
+
+    private static final class Literal extends UriChunk {
+        private String value;
+
+        private Literal() {
+            // empty constructor
+        }
+
+        public static Literal create(String uriChunk) {
+            if (uriChunk == null || "".equals(uriChunk)) {
+                throw new IllegalArgumentException("uriChunk is empty");
+            }
+            Literal literal = new Literal();
+            literal.value = uriChunk;
+            return literal;
+        }
+
+        @Override
+        public String getValue() {
+            return value;
+        }
+
+    }
+
+    /**
+     * Variable of URITemplate. Variable has either "{varname:pattern}" syntax or "{varname}".
+     */
+    private static final class Variable extends UriChunk {
+        private static final Pattern VARIABLE_PATTERN = Pattern.compile("(\\w[-\\w\\.]*[ ]*)(\\:(.+))?");
+        private String name;
+        private Pattern pattern;
+
+        private Variable() {
+            // empty constructor
+        }
+
+        /**
+         * Creates variable from stringified part of URI.
+         *
+         * @param uriChunk uriChunk chunk that depicts variable
+         * @return Variable if variable was successfully created; null if uriChunk was not a variable
+         */
+        public static Variable create(String uriChunk) {
+            Variable newVariable = new Variable();
+            if (uriChunk == null || "".equals(uriChunk)) {
+                return null;
+            }
+            if (CurlyBraceTokenizer.insideBraces(uriChunk)) {
+                uriChunk = CurlyBraceTokenizer.stripBraces(uriChunk).trim();
+                Matcher matcher = VARIABLE_PATTERN.matcher(uriChunk);
+                if (matcher.matches()) {
+                    newVariable.name = matcher.group(1).trim();
+                    if (matcher.group(2) != null && matcher.group(3) != null) {
+                        String patternExpression = matcher.group(3).trim();
+                        newVariable.pattern = Pattern.compile(patternExpression);
+                    }
+                    return newVariable;
+                }
+            }
+            return null;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public String getPattern() {
+            return pattern != null ? pattern.pattern() : null;
+        }
+
+        /**
+         * Checks whether value matches variable. If variable has pattern its checked against, otherwise true
+         * is returned.
+         *
+         * @param value value of variable
+         * @return true if value is valid for variable, false otherwise.
+         */
+        public boolean matches(String value) {
+            if (pattern == null) {
+                return true;
+            }
+            return pattern.matcher(value).matches();
+        }
+
+        @Override
+        public String getValue() {
+            if (pattern != null) {
+                return "{" + name + ":" + pattern + "}";
+            }
+            return "{" + name + "}";
+        }
+    }
+
+    /**
+     * Splits string into parts inside and outside curly braces. Nested curly braces are ignored and treated
+     * as part inside top-level curly braces. Example: string "foo{bar{baz}}blah" is split into three tokens,
+     * "foo","{bar{baz}}" and "blah". When closed bracket is missing, whole unclosed part is returned as one
+     * token, e.g.: "foo{bar" is split into "foo" and "{bar". When opening bracket is missing, closing
+     * bracket is ignored and taken as part of current token e.g.: "foo{bar}baz}blah" is split into "foo",
+     * "{bar}" and "baz}blah".
+     * <p>
+     * This is helper class for {@link URITemplate} that enables recurring literals appearing next to regular
+     * expressions e.g. "/foo/{zipcode:[0-9]{5}}/". Nested expressions with closed sections, like open-closed
+     * brackets causes expression to be out of regular grammar (is context-free grammar) which are not
+     * supported by Java regexp version.
+     */
+    static class CurlyBraceTokenizer {
+
+        private List<String> tokens = new ArrayList<>();
+        private int tokenIdx;
+
+        CurlyBraceTokenizer(String string) {
+            boolean outside = true;
+            int level = 0;
+            int lastIdx = 0;
+            int idx;
+            for (idx = 0; idx < string.length(); idx++) {
+                if (string.charAt(idx) == '{') {
+                    if (outside) {
+                        if (lastIdx < idx) {
+                            tokens.add(string.substring(lastIdx, idx));
+                        }
+                        lastIdx = idx;
+                        outside = false;
+                    } else {
+                        level++;
+                    }
+                } else if (string.charAt(idx) == '}' && !outside) {
+                    if (level > 0) {
+                        level--;
+                    } else {
+                        if (lastIdx < idx) {
+                            tokens.add(string.substring(lastIdx, idx + 1));
+                        }
+                        lastIdx = idx + 1;
+                        outside = true;
+                    }
+                }
+            }
+            if (lastIdx < idx) {
+                tokens.add(string.substring(lastIdx, idx));
+            }
+        }
+
+        /**
+         * Token is enclosed by curly braces.
+         *
+         * @param token
+         *            text to verify
+         * @return true if enclosed, false otherwise.
+         */
+        public static boolean insideBraces(String token) {
+            return token.charAt(0) == '{' && token.charAt(token.length() - 1) == '}';
+        }
+
+        /**
+         * Strips token from enclosed curly braces. If token is not enclosed method
+         * has no side effect.
+         *
+         * @param token
+         *            text to verify
+         * @return text stripped from curly brace begin-end pair.
+         */
+        public static String stripBraces(String token) {
+            if (insideBraces(token)) {
+                return token.substring(1, token.length() - 1);
+            }
+            return token;
+        }
+
+        public boolean hasNext() {
+            return tokens.size() > tokenIdx;
+        }
+
+        public String next() {
+            if (hasNext()) {
+                return tokens.get(tokenIdx++);
+            }
+            throw new IllegalStateException("no more elements");
+        }
+    }
+}
+
+
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/provider/CachingMessageBodyReader.java b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/CachingMessageBodyReader.java
new file mode 100644
index 0000000..ecdc8f1
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/CachingMessageBodyReader.java
@@ -0,0 +1,100 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.List;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+
+@Provider
+public class CachingMessageBodyReader<T> extends AbstractCachingMessageProvider<T>
+    implements MessageBodyReader<T> {
+
+    private List<MessageBodyReader<T>> delegatingReaders;
+
+    public boolean isReadable(Class<?> type, Type gType, Annotation[] anns, MediaType mt) {
+        if (delegatingReaders != null) {
+            return getDelegatingReader(type, gType, anns, mt) != null;
+        }
+        return isProviderKeyNotSet();
+    }
+
+    private MessageBodyReader<T> getDelegatingReader(Class<?> type, Type gType, Annotation[] anns, MediaType mt) {
+        for (MessageBodyReader<T> reader: delegatingReaders) {
+            if (reader.isReadable(type, gType, anns, mt)) {
+                return reader;
+            }
+        }
+        return null;
+    }
+
+    public T readFrom(Class<T> type, Type gType, Annotation[] anns, MediaType mt,
+                        MultivaluedMap<String, String> theheaders, InputStream is)
+        throws IOException, WebApplicationException {
+        this.setObject(
+            getReader(type, gType, anns, mt).readFrom(type, gType, anns, mt, theheaders, is));
+        return getObject();
+    }
+
+
+    protected MessageBodyReader<T> getReader(Class<?> type, Type gType, Annotation[] anns, MediaType mt) {
+        if (delegatingReaders != null) {
+            return getDelegatingReader(type, gType, anns, mt);
+        }
+        final MessageBodyReader<T> r;
+
+        mc.put(ACTIVE_JAXRS_PROVIDER_KEY, this);
+        try {
+            @SuppressWarnings("unchecked")
+            Class<T> actualType = (Class<T>)type;
+            r = mc.getProviders().getMessageBodyReader(actualType, gType, anns, mt);
+        } finally {
+            mc.put(ACTIVE_JAXRS_PROVIDER_KEY, null);
+        }
+
+        if (r == null) {
+            org.apache.cxf.common.i18n.Message message =
+                new org.apache.cxf.common.i18n.Message("NO_MSG_READER", BUNDLE, type);
+            LOG.severe(message.toString());
+            throw ExceptionUtils.toNotAcceptableException(null, null);
+        }
+        return r;
+    }
+
+    public void setDelegatingReader(MessageBodyReader<T> reader) {
+        this.delegatingReaders = Collections.singletonList(reader);
+    }
+
+    public void setDelegatingReaders(List<MessageBodyReader<T>> readers) {
+        this.delegatingReaders = readers;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/provider/CachingMessageBodyWriter.java b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/CachingMessageBodyWriter.java
new file mode 100644
index 0000000..21eab42
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/CachingMessageBodyWriter.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.cxf.jaxrs.provider;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.List;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+
+@Provider
+public class CachingMessageBodyWriter<T> extends AbstractCachingMessageProvider<T>
+    implements MessageBodyWriter<T> {
+
+    private List<MessageBodyWriter<T>> delegatingWriters;
+
+    public long getSize(T t, Class<?> type, Type gType, Annotation[] anns, MediaType mediaType) {
+        return -1;
+    }
+
+    public boolean isWriteable(Class<?> type, Type gType, Annotation[] anns, MediaType mt) {
+        if (delegatingWriters != null) {
+            return getDelegatingWriter(type, gType, anns, mt) != null;
+        }
+        return isProviderKeyNotSet();
+    }
+
+    private MessageBodyWriter<T> getDelegatingWriter(Class<?> type, Type gType, Annotation[] anns, MediaType mt) {
+        for (MessageBodyWriter<T> writer: delegatingWriters) {
+            if (writer.isWriteable(type, gType, anns, mt)) {
+                return writer;
+            }
+        }
+        return null;
+    }
+
+    public void writeTo(T obj, Class<?> type, Type gType, Annotation[] anns, MediaType mt,
+                        MultivaluedMap<String, Object> theheaders, OutputStream os)
+        throws IOException, WebApplicationException {
+        this.setObject(obj);
+        getWriter(type, gType, anns, mt).writeTo(getObject(), type, gType, anns, mt, theheaders, os);
+    }
+
+
+    protected MessageBodyWriter<T> getWriter(Class<?> type, Type gType, Annotation[] anns, MediaType mt) {
+        if (delegatingWriters != null) {
+            return getDelegatingWriter(type, gType, anns, mt);
+        }
+        MessageBodyWriter<T> w;
+
+        mc.put(ACTIVE_JAXRS_PROVIDER_KEY, this);
+        try {
+            @SuppressWarnings("unchecked")
+            Class<T> actualType = (Class<T>)type;
+            w = mc.getProviders().getMessageBodyWriter(actualType, gType, anns, mt);
+        } finally {
+            mc.put(ACTIVE_JAXRS_PROVIDER_KEY, null);
+        }
+
+        if (w == null) {
+            org.apache.cxf.common.i18n.Message message =
+                new org.apache.cxf.common.i18n.Message("NO_MSG_WRITER", BUNDLE, type);
+            LOG.severe(message.toString());
+            throw ExceptionUtils.toInternalServerErrorException(null, null);
+        }
+        return w;
+    }
+
+    public void setDelegatingWriter(MessageBodyWriter<T> writer) {
+        this.delegatingWriters = Collections.singletonList(writer);
+    }
+
+    public void setDelegatingWriters(List<MessageBodyWriter<T>> writers) {
+        this.delegatingWriters = writers;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/provider/DataSourceProvider.java b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/DataSourceProvider.java
new file mode 100644
index 0000000..efecac4
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/DataSourceProvider.java
@@ -0,0 +1,110 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.logging.Logger;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.activation.FileDataSource;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.ext.multipart.InputStreamDataSource;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+
+@Provider
+public class DataSourceProvider<T> implements MessageBodyReader<T>, MessageBodyWriter<T> {
+    protected static final Logger LOG = LogUtils.getL7dLogger(DataSourceProvider.class);
+    private boolean useDataSourceContentType;
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) {
+        return isSupported(type);
+    }
+
+    public T readFrom(Class<T> cls, Type genericType, Annotation[] annotations,
+                               MediaType type,
+                               MultivaluedMap<String, String> headers, InputStream is)
+        throws IOException {
+
+        final DataSource ds;
+        if (cls == FileDataSource.class) {
+            File file = new BinaryDataProvider<File>().readFrom(File.class, File.class, annotations, type, headers, is);
+            ds = new FileDataSource(file);
+        } else if (cls == DataSource.class || cls == DataHandler.class) {
+            ds = new InputStreamDataSource(is, type.toString());
+        } else {
+            LOG.warning("Unsupported DataSource class: " + cls.getName());
+            throw ExceptionUtils.toWebApplicationException(null, null);
+        }
+        return cls.cast(DataSource.class.isAssignableFrom(cls) ? ds : new DataHandler(ds));
+    }
+
+    public long getSize(T t, Class<?> type, Type genericType, Annotation[] annotations,
+                        MediaType mt) {
+        return -1;
+    }
+
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) {
+        return isSupported(type);
+    }
+
+    private static boolean isSupported(Class<?> type) {
+        return DataSource.class.isAssignableFrom(type) || DataHandler.class.isAssignableFrom(type);
+    }
+
+    public void writeTo(T src, Class<?> cls, Type genericType, Annotation[] annotations,
+                        MediaType type, MultivaluedMap<String, Object> headers, OutputStream os)
+        throws IOException {
+        DataSource ds = DataSource.class.isAssignableFrom(cls)
+            ? (DataSource)src : ((DataHandler)src).getDataSource();
+        if (useDataSourceContentType) {
+            setContentTypeIfNeeded(type, headers, ds.getContentType());
+        }
+        IOUtils.copyAndCloseInput(ds.getInputStream(), os);
+    }
+
+    private void setContentTypeIfNeeded(MediaType type,
+        MultivaluedMap<String, Object> headers, String ct) {
+
+        if (!StringUtils.isEmpty(ct) && !type.equals(JAXRSUtils.toMediaType(ct))) {
+            headers.putSingle("Content-Type", ct);
+        }
+    }
+
+    public void setUseDataSourceContentType(boolean useDataSourceContentType) {
+        this.useDataSourceContentType = useDataSourceContentType;
+    }
+
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java
new file mode 100644
index 0000000..0344592
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java
@@ -0,0 +1,228 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Encoded;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Form;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.jaxrs.utils.FormUtils;
+import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+
+@Produces({"application/x-www-form-urlencoded", "multipart/form-data" })
+@Consumes({"application/x-www-form-urlencoded", "multipart/form-data" })
+@Provider
+public class FormEncodingProvider<T> extends AbstractConfigurableProvider
+    implements MessageBodyReader<T>, MessageBodyWriter<T> {
+
+    private FormValidator validator;
+    @Context private MessageContext mc;
+    private String attachmentDir;
+    private String attachmentThreshold;
+    private String attachmentMaxSize;
+
+    private boolean expectEncoded;
+
+    public FormEncodingProvider() {
+
+    }
+
+    public FormEncodingProvider(boolean expectEncoded) {
+        this.expectEncoded = expectEncoded;
+    }
+
+    public void setExpectedEncoded(boolean expect) {
+        this.expectEncoded = expect;
+    }
+
+    public void setAttachmentDirectory(String dir) {
+        attachmentDir = dir;
+    }
+
+    public void setAttachmentThreshold(String threshold) {
+        attachmentThreshold = threshold;
+    }
+
+    public void setAttachmentMaxSize(String maxSize) {
+        attachmentMaxSize = maxSize;
+    }
+
+    public void setValidator(FormValidator formValidator) {
+        validator = formValidator;
+    }
+
+    public boolean isReadable(Class<?> type, Type genericType,
+                              Annotation[] annotations, MediaType mt) {
+        return isSupported(type, mt);
+    }
+
+    public T readFrom(
+        Class<T> clazz, Type genericType, Annotation[] annotations, MediaType mt,
+        MultivaluedMap<String, String> headers, InputStream is)
+        throws IOException {
+        if (is == null) {
+            return null;
+        }
+        try {
+            if (mt.isCompatible(MediaType.MULTIPART_FORM_DATA_TYPE)) {
+                MultipartBody body = AttachmentUtils.getMultipartBody(mc);
+                if (MultipartBody.class.isAssignableFrom(clazz)) {
+                    return clazz.cast(body);
+                } else if (Attachment.class.isAssignableFrom(clazz)) {
+                    return clazz.cast(body.getRootAttachment());
+                }
+            }
+
+            MultivaluedMap<String, String> params = createMap(clazz);
+            populateMap(params, annotations, is, mt, !keepEncoded(annotations));
+            validateMap(params);
+
+            persistParamsOnMessage(params);
+
+            return getFormObject(clazz, params);
+        } catch (WebApplicationException e) {
+            throw e;
+        } catch (Exception e) {
+            throw ExceptionUtils.toBadRequestException(e, null);
+        }
+    }
+
+    protected boolean keepEncoded(Annotation[] anns) {
+        return AnnotationUtils.getAnnotation(anns, Encoded.class) != null
+               || expectEncoded;
+    }
+
+    protected void persistParamsOnMessage(MultivaluedMap<String, String> params) {
+        Message message = PhaseInterceptorChain.getCurrentMessage();
+        if (message != null) {
+            message.put(FormUtils.FORM_PARAM_MAP, params);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    protected MultivaluedMap<String, String> createMap(Class<?> clazz) throws Exception {
+        if (clazz == MultivaluedMap.class || clazz == Form.class) {
+            return new MetadataMap<String, String>();
+        }
+        return (MultivaluedMap<String, String>)clazz.newInstance();
+    }
+
+    private T getFormObject(Class<T> clazz, MultivaluedMap<String, String> params) {
+        return clazz.cast(Form.class.isAssignableFrom(clazz) ? new Form(params) : params);
+    }
+
+    /**
+     * Retrieve map of parameters from the passed in message
+     */
+    protected void populateMap(MultivaluedMap<String, String> params,
+                               Annotation[] anns,
+                               InputStream is,
+                               MediaType mt,
+                               boolean decode) {
+        if (mt.isCompatible(MediaType.MULTIPART_FORM_DATA_TYPE)) {
+            MultipartBody body =
+                AttachmentUtils.getMultipartBody(mc, attachmentDir, attachmentThreshold, attachmentMaxSize);
+            FormUtils.populateMapFromMultipart(params, body, PhaseInterceptorChain.getCurrentMessage(),
+                                               decode);
+        } else {
+            String enc = HttpUtils.getEncoding(mt, StandardCharsets.UTF_8.name());
+
+            Object servletRequest = mc != null ? mc.getHttpServletRequest() : null;
+            if (servletRequest == null) {
+                FormUtils.populateMapFromString(params,
+                                                PhaseInterceptorChain.getCurrentMessage(),
+                                                FormUtils.readBody(is, enc),
+                                                enc,
+                                                decode);
+            } else {
+                FormUtils.populateMapFromString(params,
+                                                PhaseInterceptorChain.getCurrentMessage(),
+                                                FormUtils.readBody(is, enc),
+                                                enc,
+                                                decode,
+                                                (javax.servlet.http.HttpServletRequest)servletRequest);
+            }
+        }
+    }
+
+    protected void validateMap(MultivaluedMap<String, String> params) {
+        if (validator != null) {
+            validator.validate(params);
+        }
+    }
+
+    public long getSize(T t, Class<?> type,
+                        Type genericType, Annotation[] annotations,
+                        MediaType mediaType) {
+        return -1;
+    }
+
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations,
+                               MediaType mt) {
+        return isSupported(type, mt);
+    }
+
+    private static boolean isSupported(Class<?> type, MediaType mt) {
+        return (MultivaluedMap.class.isAssignableFrom(type) || Form.class.isAssignableFrom(type))
+            || ("multipart".equalsIgnoreCase(mt.getType())
+            && mt.isCompatible(MediaType.MULTIPART_FORM_DATA_TYPE)
+            && (MultivaluedMap.class.isAssignableFrom(type) || Form.class.isAssignableFrom(type)));
+    }
+
+    @SuppressWarnings("unchecked")
+    public void writeTo(T obj, Class<?> c, Type t, Annotation[] anns,
+                        MediaType mt, MultivaluedMap<String, Object> headers, OutputStream os)
+        throws IOException, WebApplicationException {
+
+        MultivaluedMap<String, String> map =
+            (MultivaluedMap<String, String>)(obj instanceof Form ? ((Form)obj).asMap() : obj);
+        boolean encoded = keepEncoded(anns);
+
+        String enc = HttpUtils.getSetEncoding(mt, headers, StandardCharsets.UTF_8.name());
+
+        FormUtils.writeMapToOutputStream(map, os, enc, encoded);
+
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
new file mode 100644
index 0000000..ab27e02
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
@@ -0,0 +1,635 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.ext.Provider;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Source;
+
+import org.w3c.dom.Document;
+
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.ext.Nullable;
+import org.apache.cxf.jaxrs.ext.xml.XMLInstruction;
+import org.apache.cxf.jaxrs.ext.xml.XMLSource;
+import org.apache.cxf.jaxrs.ext.xml.XSISchemaLocation;
+import org.apache.cxf.jaxrs.ext.xml.XSLTTransform;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.JAXBUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Attachment;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.staxutils.DepthExceededStaxException;
+import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.cxf.staxutils.transform.TransformUtils;
+
+@Produces({"application/xml", "application/*+xml", "text/xml" })
+@Consumes({"application/xml", "application/*+xml", "text/xml" })
+@Provider
+public class JAXBElementProvider<T> extends AbstractJAXBProvider<T>  {
+    private static final String XML_PI_START = "<?xml version=\"1.0\" encoding=\"";
+    private static final String XML_PI_PROPERTY_RI = "com.sun.xml.bind.xmlHeaders";
+    private static final String XML_PI_PROPERTY_RI_INT = "com.sun.xml.internal.bind.xmlHeaders";
+
+    private static final String[] MARSHALLER_PROPERTIES = {
+        Marshaller.JAXB_ENCODING,
+        Marshaller.JAXB_FORMATTED_OUTPUT,
+        Marshaller.JAXB_FRAGMENT,
+        Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION,
+        Marshaller.JAXB_SCHEMA_LOCATION,
+        NS_MAPPER_PROPERTY_RI,
+        NS_MAPPER_PROPERTY_RI_INT,
+        XML_PI_PROPERTY_RI,
+        XML_PI_PROPERTY_RI_INT
+    };
+
+    private Map<String, Object> mProperties = Collections.emptyMap();
+    private Map<String, String> nsPrefixes = Collections.emptyMap();
+    private String xmlResourceOffset = "";
+    private String xmlPiPropertyName;
+
+    public JAXBElementProvider() {
+
+    }
+
+    protected boolean objectFactoryOrIndexAvailable(Class<?> type) {
+        return !Document.class.isAssignableFrom(type) && super.objectFactoryOrIndexAvailable(type);
+    }
+
+    public void setXmlResourceOffset(String value) {
+        xmlResourceOffset = value;
+    }
+
+    public void setNamespacePrefixes(Map<String, String> prefixes) {
+        nsPrefixes = prefixes;
+    }
+
+    protected void setXmlPiProperty(Marshaller ms, String value) throws Exception {
+        if (xmlPiPropertyName != null) {
+            setMarshallerProp(ms, value, xmlPiPropertyName, null);
+        } else {
+            setMarshallerProp(ms, value, XML_PI_PROPERTY_RI, XML_PI_PROPERTY_RI_INT);
+        }
+    }
+
+    @Override
+    protected boolean canBeReadAsJaxbElement(Class<?> type) {
+        return super.canBeReadAsJaxbElement(type)
+            && type != XMLSource.class && !Source.class.isAssignableFrom(type);
+    }
+
+    @Context
+    public void setMessageContext(MessageContext mc) {
+        super.setContext(mc);
+    }
+
+    public void setMarshallerProperties(Map<String, Object> marshallProperties) {
+        mProperties = marshallProperties;
+    }
+
+    public void setSchemaLocation(String schemaLocation) {
+        mProperties.put(Marshaller.JAXB_SCHEMA_LOCATION, schemaLocation);
+    }
+
+    public T readFrom(Class<T> type, Type genericType, Annotation[] anns, MediaType mt,
+        MultivaluedMap<String, String> headers, InputStream is)
+        throws IOException {
+        if (isPayloadEmpty(headers)) {
+            if (AnnotationUtils.getAnnotation(anns, Nullable.class) != null) {
+                return null;
+            }
+            reportEmptyContentLength();
+        }
+
+        XMLStreamReader reader = null;
+        Unmarshaller unmarshaller = null;
+        try {
+
+            boolean isCollection = InjectionUtils.isSupportedCollectionOrArray(type);
+            Class<?> theGenericType = isCollection ? InjectionUtils.getActualType(genericType) : type;
+            Class<?> theType = getActualType(theGenericType, genericType, anns);
+
+            unmarshaller = createUnmarshaller(theType, genericType, isCollection);
+            addAttachmentUnmarshaller(unmarshaller);
+            Object response = null;
+            if (JAXBElement.class.isAssignableFrom(type)
+                || !isCollection && (unmarshalAsJaxbElement
+                || jaxbElementClassMap != null && jaxbElementClassMap.containsKey(theType.getName()))) {
+                try (InputStream in = IOUtils.nullOrNotEmptyStream(is)) {
+                    // The return value might be "null" in case of empty stream, in this
+                    // case the unmarshaller fails with javax.xml.bind.UnmarshalException instead
+                    // of returning empty response.
+                    if (in != null) {
+                        reader = getStreamReader(in, type, mt);
+                        reader = TransformUtils.createNewReaderIfNeeded(reader, in);
+                        
+                        if (JAXBElement.class.isAssignableFrom(type) && type == theType) {
+                            response = unmarshaller.unmarshal(reader);
+                        } else {
+                            response = unmarshaller.unmarshal(reader, theType);
+                        }
+                    }
+                }
+            } else {
+                response = doUnmarshal(unmarshaller, type, is, anns, mt);
+            }
+            
+            if (response instanceof JAXBElement && !JAXBElement.class.isAssignableFrom(type)) {
+                response = ((JAXBElement<?>)response).getValue();
+            }
+            if (isCollection) {
+                response = ((CollectionWrapper)response).getCollectionOrArray(
+                                 unmarshaller, theType, type, genericType,
+                                 org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(theGenericType, anns));
+            } else {
+                response = checkAdapter(response, type, anns, false);
+            }
+            return type.cast(response);
+
+        } catch (JAXBException e) {
+            handleJAXBException(e, true);
+        } catch (DepthExceededStaxException e) {
+            throw ExceptionUtils.toWebApplicationException(null, JAXRSUtils.toResponse(413));
+        } catch (WebApplicationException e) {
+            throw e;
+        } catch (Exception e) {
+            LOG.warning(ExceptionUtils.getStackTrace(e));
+            throw ExceptionUtils.toBadRequestException(e, null);
+        } finally {
+            try {
+                StaxUtils.close(reader);
+            } catch (XMLStreamException e) {
+                // Ignore
+            }
+            JAXBUtils.closeUnmarshaller(unmarshaller);
+        }
+        // unreachable
+        return null;
+    }
+
+    protected Object doUnmarshal(Unmarshaller unmarshaller, Class<?> type, InputStream is,
+                                 Annotation[] anns, MediaType mt)
+        throws JAXBException {
+        XMLStreamReader reader = getStreamReader(is, type, mt);
+        if (reader != null) {
+            try {
+                return unmarshalFromReader(unmarshaller, reader, anns, mt);
+            } catch (JAXBException e) {
+                throw e;
+            } finally {
+                try {
+                    StaxUtils.close(reader);
+                } catch (XMLStreamException e) {
+                    // Ignore
+                }
+            }
+        }
+        return unmarshalFromInputStream(unmarshaller, is, anns, mt);
+    }
+
+    protected XMLStreamReader getStreamReader(InputStream is, Class<?> type, MediaType mt) {
+        MessageContext mc = getContext();
+        XMLStreamReader reader = mc != null ? mc.getContent(XMLStreamReader.class) : null;
+        if (reader == null && mc != null) {
+            XMLInputFactory factory = (XMLInputFactory)mc.get(XMLInputFactory.class.getName());
+            if (factory != null) {
+                try {
+                    reader = factory.createXMLStreamReader(is);
+                } catch (XMLStreamException e) {
+                    throw ExceptionUtils.toInternalServerErrorException(
+                        new RuntimeException("Can not create XMLStreamReader", e), null);
+                }
+            }
+        }
+
+        if (reader == null && is == null) {
+            reader = getStreamHandlerFromCurrentMessage(XMLStreamReader.class);
+        }
+
+        reader = createTransformReaderIfNeeded(reader, is);
+        reader = createDepthReaderIfNeeded(reader, is);
+        if (InjectionUtils.isSupportedCollectionOrArray(type)) {
+            return new JAXBCollectionWrapperReader(TransformUtils.createNewReaderIfNeeded(reader, is));
+        }
+        return reader;
+
+    }
+
+    protected Object unmarshalFromInputStream(Unmarshaller unmarshaller, InputStream is,
+                                              Annotation[] anns, MediaType mt)
+        throws JAXBException {
+        // Try to create the read before unmarshalling the stream
+        XMLStreamReader xmlReader = null;
+        try {
+            if (is == null) {
+                Reader reader = getStreamHandlerFromCurrentMessage(Reader.class);
+                if (reader == null) {
+                    LOG.severe("No InputStream, Reader, or XMLStreamReader is available");
+                    throw ExceptionUtils.toInternalServerErrorException(null, null);
+                }
+                xmlReader = StaxUtils.createXMLStreamReader(reader);
+            } else {
+                xmlReader = StaxUtils.createXMLStreamReader(is);
+            }
+            configureReaderRestrictions(xmlReader);
+            return unmarshaller.unmarshal(xmlReader);
+        } finally {
+            try {
+                StaxUtils.close(xmlReader);
+            } catch (XMLStreamException e) {
+                // Ignore
+            }
+        }
+    }
+
+    protected Object unmarshalFromReader(Unmarshaller unmarshaller, XMLStreamReader reader,
+                                         Annotation[] anns, MediaType mt)
+        throws JAXBException {
+        return unmarshaller.unmarshal(reader);
+    }
+
+    public void writeTo(T obj, Class<?> cls, Type genericType, Annotation[] anns,
+        MediaType m, MultivaluedMap<String, Object> headers, OutputStream os)
+        throws IOException {
+        try {
+            String encoding = HttpUtils.getSetEncoding(m, headers, StandardCharsets.UTF_8.name());
+            if (InjectionUtils.isSupportedCollectionOrArray(cls)) {
+                marshalCollection(cls, obj, genericType, encoding, os, m, anns);
+            } else {
+                Object actualObject = checkAdapter(obj, cls, anns, true);
+                Class<?> actualClass = obj != actualObject || cls.isInterface()
+                    ? actualObject.getClass() : cls;
+                marshal(actualObject, actualClass, genericType, encoding, os, m, anns);
+            }
+        } catch (JAXBException e) {
+            handleJAXBException(e, false);
+        }  catch (WebApplicationException e) {
+            throw e;
+        } catch (Exception e) {
+            LOG.warning(ExceptionUtils.getStackTrace(e));
+            throw ExceptionUtils.toInternalServerErrorException(e, null);
+        }
+    }
+
+    protected void marshalCollection(Class<?> originalCls, Object collection,
+                                     Type genericType, String enc, OutputStream os,
+                                     MediaType m, Annotation[] anns)
+        throws Exception {
+
+        Class<?> actualClass = InjectionUtils.getActualType(genericType);
+        actualClass = getActualType(actualClass, genericType, anns);
+
+        Collection<?> c = originalCls.isArray() ? Arrays.asList((Object[]) collection)
+                                             : (Collection<?>) collection;
+
+        Iterator<?> it = c.iterator();
+
+        Object firstObj = it.hasNext() ? it.next() : null;
+
+        final QName qname;
+        if (firstObj instanceof JAXBElement) {
+            JAXBElement<?> el = (JAXBElement<?>)firstObj;
+            qname = el.getName();
+            actualClass = el.getDeclaredType();
+        } else {
+            qname = getCollectionWrapperQName(actualClass, genericType, firstObj, true);
+        }
+        if (qname == null) {
+            String message = new org.apache.cxf.common.i18n.Message("NO_COLLECTION_ROOT",
+                                                                    BUNDLE).toString();
+            throw new WebApplicationException(Response.serverError()
+                                              .entity(message).build());
+        }
+
+        os.write((XML_PI_START + (enc == null ? StandardCharsets.UTF_8.name() : enc) + "\"?>").getBytes());
+
+        final String startTag;
+        final String endTag;
+        if (!qname.getNamespaceURI().isEmpty()) {
+            String prefix = nsPrefixes.get(qname.getNamespaceURI());
+            if (prefix == null) {
+                prefix = "ns1";
+            }
+            startTag = "<" + prefix + ':' + qname.getLocalPart() + " xmlns:" + prefix + "=\""
+                + qname.getNamespaceURI() + "\">";
+            endTag = "</" + prefix + ':' + qname.getLocalPart() + ">";
+        } else {
+            startTag = "<" + qname.getLocalPart() + ">";
+            endTag = "</" + qname.getLocalPart() + ">";
+        }
+        os.write(startTag.getBytes());
+        if (firstObj != null) {
+            XmlJavaTypeAdapter adapter =
+                org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(firstObj.getClass(), anns);
+            marshalCollectionMember(JAXBUtils.useAdapter(firstObj, adapter, true),
+                                    actualClass, genericType, enc, os, anns, m,
+                                    qname.getNamespaceURI());
+            while (it.hasNext()) {
+                marshalCollectionMember(JAXBUtils.useAdapter(it.next(), adapter, true), actualClass,
+                                        genericType, enc, os, anns, m,
+                                        qname.getNamespaceURI());
+            }
+        }
+        os.write(endTag.getBytes());
+    }
+    //CHECKSTYLE:OFF
+    protected void marshalCollectionMember(Object obj,
+                                           Class<?> cls,
+                                           Type genericType,
+                                           String enc,
+                                           OutputStream os,
+                                           Annotation[] anns,
+                                           MediaType mt,
+                                           String ns) throws Exception {
+    //CHECKSTYLE:ON
+        if (!(obj instanceof JAXBElement)) {
+            obj = convertToJaxbElementIfNeeded(obj, cls, genericType);
+        }
+
+        if (obj instanceof JAXBElement && cls != JAXBElement.class) {
+            cls = JAXBElement.class;
+        }
+
+        Marshaller ms = createMarshaller(obj, cls, genericType, enc);
+        ms.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
+        if (ns.length() > 0) {
+            Map<String, String> map = new HashMap<>();
+            // set the default just in case
+            if (!nsPrefixes.containsKey(ns)) {
+                map.put(ns, "ns1");
+            }
+            map.putAll(nsPrefixes);
+            setNamespaceMapper(ms, map);
+        }
+        marshal(obj, cls, genericType, enc, os, anns, mt, ms);
+    }
+
+    protected void marshal(Object obj, Class<?> cls, Type genericType,
+                           String enc, OutputStream os, MediaType mt) throws Exception {
+        marshal(obj, cls, genericType, enc, os, mt, new Annotation[]{});
+    }
+
+    protected void marshal(Object obj, Class<?> cls, Type genericType,
+                           String enc, OutputStream os, MediaType mt,
+                           Annotation[] anns) throws Exception {
+        obj = convertToJaxbElementIfNeeded(obj, cls, genericType);
+        if (obj instanceof JAXBElement && cls != JAXBElement.class) {
+            cls = JAXBElement.class;
+        }
+
+        Marshaller ms = createMarshaller(obj, cls, genericType, enc);
+        if (!nsPrefixes.isEmpty()) {
+            setNamespaceMapper(ms, nsPrefixes);
+        }
+        addAttachmentMarshaller(ms);
+        processXmlAnnotations(ms, mt, anns);
+        marshal(obj, cls, genericType, enc, os, anns, mt, ms);
+    }
+
+    private void processXmlAnnotations(Marshaller ms, MediaType mt, Annotation[] anns) throws Exception {
+        if (anns == null) {
+            return;
+        }
+        for (Annotation ann : anns) {
+            if (ann.annotationType() == XMLInstruction.class) {
+                addProcessingInstructions(ms, (XMLInstruction)ann);
+            } else if (ann.annotationType() == XSISchemaLocation.class) {
+                addSchemaLocation(ms, (XSISchemaLocation)ann);
+            } else if (ann.annotationType() == XSLTTransform.class) {
+                addXslProcessingInstruction(ms, mt, (XSLTTransform)ann);
+            }
+        }
+    }
+
+    private void addProcessingInstructions(Marshaller ms, XMLInstruction pi) throws Exception {
+        String value = pi.value();
+        int ind = value.indexOf("href='");
+        if (ind > 0) {
+            String relRef = value.substring(ind + 6);
+            relRef = relRef.substring(0, relRef.length() - 3).trim();
+            if (relRef.endsWith("'")) {
+                relRef = relRef.substring(0, relRef.length() - 1);
+            }
+            String absRef = resolveXMLResourceURI(relRef);
+            value = value.substring(0, ind + 6) + absRef + "'?>";
+        }
+        setXmlPiProperty(ms, value);
+    }
+
+    private void addXslProcessingInstruction(Marshaller ms, MediaType mt, XSLTTransform ann)
+        throws Exception {
+        if (ann.type() == XSLTTransform.TransformType.CLIENT
+            || ann.type() == XSLTTransform.TransformType.BOTH && ann.mediaTypes().length > 0) {
+            for (String s : ann.mediaTypes()) {
+                if (mt.isCompatible(JAXRSUtils.toMediaType(s))) {
+                    return;
+                }
+            }
+            String absRef = resolveXMLResourceURI(ann.value());
+            String xslPi = "<?xml-stylesheet type=\"text/xsl\" href=\"" + absRef + "\"?>";
+            setXmlPiProperty(ms, xslPi);
+        }
+    }
+
+    private void addSchemaLocation(Marshaller ms, XSISchemaLocation sl) throws Exception {
+        String value = sl.resolve() ? resolveXMLResourceURI(sl.value()) : sl.value();
+        String propName = !sl.noNamespace()
+            ? Marshaller.JAXB_SCHEMA_LOCATION : Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION;
+        ms.setProperty(propName, value);
+    }
+
+    protected String resolveXMLResourceURI(String path) {
+        MessageContext mc = getContext();
+        if (mc != null) {
+            String httpBasePath = (String)mc.get("http.base.path");
+            final UriBuilder builder;
+            if (httpBasePath != null) {
+                builder = UriBuilder.fromPath(httpBasePath);
+            } else {
+                builder = mc.getUriInfo().getBaseUriBuilder();
+            }
+            return builder.path(path).path(xmlResourceOffset).build().toString();
+        }
+        return path;
+    }
+
+
+
+    protected void addAttachmentMarshaller(Marshaller ms) {
+        Collection<Attachment> attachments = getAttachments(true);
+        if (attachments != null) {
+            Object value = getContext().getContextualProperty(Message.MTOM_THRESHOLD);
+            Integer threshold = value != null ? Integer.valueOf(value.toString()) : Integer.valueOf(0);
+            ms.setAttachmentMarshaller(new JAXBAttachmentMarshaller(
+                attachments, threshold));
+        }
+    }
+
+    protected void addAttachmentUnmarshaller(Unmarshaller um) {
+        Collection<Attachment> attachments = getAttachments(false);
+        if (attachments != null) {
+            um.setAttachmentUnmarshaller(new JAXBAttachmentUnmarshaller(
+                attachments));
+        }
+    }
+
+    private Collection<Attachment> getAttachments(boolean write) {
+        MessageContext mc = getContext();
+        if (mc != null) {
+            // TODO: there has to be a better fix
+            String propertyName = write ? "WRITE-" + Message.ATTACHMENTS : Message.ATTACHMENTS;
+            return CastUtils.cast((Collection<?>)mc.get(propertyName));
+        }
+        return null;
+    }
+    //CHECKSTYLE:OFF
+    protected final void marshal(Object obj, Class<?> cls, Type genericType,
+                           String enc, OutputStream os,
+                           Annotation[] anns, MediaType mt, Marshaller ms)
+        throws Exception {
+    //CHECKSTYLE:ON
+        for (Map.Entry<String, Object> entry : mProperties.entrySet()) {
+            ms.setProperty(entry.getKey(), entry.getValue());
+        }
+        MessageContext mc = getContext();
+        if (mc != null) {
+            // check Marshaller properties which might've been set earlier on,
+            // they'll overwrite statically configured ones
+            for (String key : MARSHALLER_PROPERTIES) {
+                Object value = mc.get(key);
+                if (value != null) {
+                    ms.setProperty(key, value);
+                }
+            }
+
+        }
+        XMLStreamWriter writer = getStreamWriter(obj, os, mt);
+        if (writer != null) {
+            if (os == null) {
+                ms.setProperty(Marshaller.JAXB_FRAGMENT, true);
+            } else if (mc != null) {
+                if (mc.getContent(XMLStreamWriter.class) != null) {
+                    ms.setProperty(Marshaller.JAXB_FRAGMENT, true);
+                }
+                mc.put(XMLStreamWriter.class.getName(), writer);
+            }
+            marshalToWriter(ms, obj, writer, anns, mt);
+            if (mc != null) {
+                writer.writeEndDocument();
+            }
+        } else {
+            marshalToOutputStream(ms, obj, os, anns, mt);
+        }
+    }
+
+    protected XMLStreamWriter getStreamWriter(Object obj, OutputStream os, MediaType mt) {
+        XMLStreamWriter writer = null;
+        MessageContext mc = getContext();
+        if (mc != null) {
+            writer = mc.getContent(XMLStreamWriter.class);
+            if (writer == null) {
+                XMLOutputFactory factory = (XMLOutputFactory)mc.get(XMLOutputFactory.class.getName());
+                if (factory != null) {
+                    try {
+                        writer = factory.createXMLStreamWriter(os);
+                    } catch (XMLStreamException e) {
+                        throw ExceptionUtils.toInternalServerErrorException(
+                            new RuntimeException("Cant' create XMLStreamWriter", e), null);
+                    }
+                }
+            }
+            if (writer == null && getEnableStreaming()) {
+                writer = StaxUtils.createXMLStreamWriter(os);
+            }
+        }
+
+        if (writer == null && os == null) {
+            writer = getStreamHandlerFromCurrentMessage(XMLStreamWriter.class);
+        }
+        return createTransformWriterIfNeeded(writer, os, true);
+    }
+
+    protected void marshalToOutputStream(Marshaller ms, Object obj, OutputStream os,
+                                         Annotation[] anns, MediaType mt)
+        throws Exception {
+        org.apache.cxf.common.jaxb.JAXBUtils.setMinimumEscapeHandler(ms);
+        if (os == null) {
+            Writer writer = getStreamHandlerFromCurrentMessage(Writer.class);
+            if (writer == null) {
+                LOG.severe("No OutputStream, Writer, or XMLStreamWriter is available");
+                throw ExceptionUtils.toInternalServerErrorException(null, null);
+            }
+            ms.marshal(obj, writer);
+            writer.flush();
+        } else {
+            ms.marshal(obj, os);
+        }
+    }
+
+    protected void marshalToWriter(Marshaller ms, Object obj, XMLStreamWriter writer,
+                                   Annotation[] anns, MediaType mt)
+        throws Exception {
+        org.apache.cxf.common.jaxb.JAXBUtils.setNoEscapeHandler(ms);
+        ms.marshal(obj, writer);
+    }
+
+    public void setXmlPiPropertyName(String xmlPiPropertyName) {
+        this.xmlPiPropertyName = xmlPiPropertyName;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java
new file mode 100644
index 0000000..e129eff
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java
@@ -0,0 +1,474 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.cxf.attachment.AttachmentUtil;
+import org.apache.cxf.attachment.ByteDataSource;
+import org.apache.cxf.common.i18n.BundleUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PrimitiveUtils;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
+import org.apache.cxf.jaxrs.ext.multipart.InputStreamDataSource;
+import org.apache.cxf.jaxrs.ext.multipart.Multipart;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartOutputFilter;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
+import org.apache.cxf.message.Message;
+
+@Provider
+@Consumes({"multipart/related", "multipart/mixed", "multipart/alternative", "multipart/form-data" })
+@Produces({"multipart/related", "multipart/mixed", "multipart/alternative", "multipart/form-data" })
+public class MultipartProvider extends AbstractConfigurableProvider
+    implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
+
+    private static final String SUPPORT_TYPE_AS_MULTIPART = "support.type.as.multipart";
+    private static final String SINGLE_PART_IS_COLLECTION = "single.multipart.is.collection";
+    private static final Logger LOG = LogUtils.getL7dLogger(MultipartProvider.class);
+    private static final ResourceBundle BUNDLE = BundleUtils.getBundle(MultipartProvider.class);
+    private static final Set<Class<?>> WELL_KNOWN_MULTIPART_CLASSES = new HashSet<>();
+    private static final Set<String> MULTIPART_SUBTYPES = new HashSet<>();
+    static {
+        WELL_KNOWN_MULTIPART_CLASSES.add(MultipartBody.class);
+        WELL_KNOWN_MULTIPART_CLASSES.add(Attachment.class);
+
+        MULTIPART_SUBTYPES.add("form-data");
+        MULTIPART_SUBTYPES.add("mixed");
+        MULTIPART_SUBTYPES.add("related");
+        MULTIPART_SUBTYPES.add("alternative");
+    }
+
+    @Context
+    private MessageContext mc;
+    private String attachmentDir;
+    private String attachmentThreshold;
+    private String attachmentMaxSize;
+
+    public void setMessageContext(MessageContext context) {
+        this.mc = context;
+    }
+
+    public void setAttachmentDirectory(String dir) {
+        attachmentDir = dir;
+    }
+
+    public void setAttachmentThreshold(String threshold) {
+        attachmentThreshold = threshold;
+    }
+
+    public void setAttachmentMaxSize(String maxSize) {
+        attachmentMaxSize = maxSize;
+    }
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations,
+                              MediaType mt) {
+        return isSupported(type, annotations, mt);
+
+    }
+
+    private boolean isSupported(Class<?> type, Annotation[] anns, MediaType mt) {
+        return mediaTypeSupported(mt)
+            && (WELL_KNOWN_MULTIPART_CLASSES.contains(type)
+                || Collection.class.isAssignableFrom(type)
+                || Map.class.isAssignableFrom(type) && type != MultivaluedMap.class
+                || AnnotationUtils.getAnnotation(anns, Multipart.class) != null
+                || PropertyUtils.isTrue(mc.getContextualProperty(SUPPORT_TYPE_AS_MULTIPART)));
+    }
+
+    protected void checkContentLength() {
+        if (mc != null && isPayloadEmpty(mc.getHttpHeaders())) {
+            String message = new org.apache.cxf.common.i18n.Message("EMPTY_BODY", BUNDLE).toString();
+            LOG.warning(message);
+            throw new WebApplicationException(400);
+        }
+    }
+
+    public Object readFrom(Class<Object> c, Type t, Annotation[] anns, MediaType mt,
+                           MultivaluedMap<String, String> headers, InputStream is)
+        throws IOException, WebApplicationException {
+        checkContentLength();
+        List<Attachment> infos = AttachmentUtils.getAttachments(
+                mc, attachmentDir, attachmentThreshold, attachmentMaxSize);
+
+        boolean collectionExpected = Collection.class.isAssignableFrom(c);
+        if (collectionExpected
+            && AnnotationUtils.getAnnotation(anns, Multipart.class) == null) {
+            return getAttachmentCollection(t, infos, anns);
+        }
+        if (c.isAssignableFrom(Map.class)) {
+            Map<String, Object> map = new LinkedHashMap<>(infos.size());
+            Class<?> actual = getActualType(t, 1);
+            for (Attachment a : infos) {
+                map.put(a.getContentType().toString(), fromAttachment(a, actual, actual, anns));
+            }
+            return map;
+        }
+        if (MultipartBody.class.isAssignableFrom(c)) {
+            return new MultipartBody(infos);
+        }
+
+        Multipart id = AnnotationUtils.getAnnotation(anns, Multipart.class);
+        Attachment multipart = AttachmentUtils.getMultipart(id, mt, infos);
+        if (multipart != null) {
+            if (collectionExpected
+                && !mediaTypeSupported(multipart.getContentType())
+                && !PropertyUtils.isTrue(mc.getContextualProperty(SINGLE_PART_IS_COLLECTION))) {
+                List<Attachment> allMultiparts = AttachmentUtils.getMatchingAttachments(id, infos);
+                return getAttachmentCollection(t, allMultiparts, anns);
+            }
+            return fromAttachment(multipart, c, t, anns);
+        }
+
+        if (id != null && !id.required()) {
+            /*
+             * Return default value for a missing optional part
+             */
+            Object defaultValue = null;
+            if (c.isPrimitive()) {
+                defaultValue = PrimitiveUtils.read((Class<?>)c == boolean.class ? "false" : "0", c);
+            }
+            return defaultValue;
+        }
+
+        throw ExceptionUtils.toBadRequestException(null, null);
+
+    }
+
+    private Object getAttachmentCollection(Type t, List<Attachment> infos, Annotation[] anns) throws IOException {
+        Class<?> actual = getActualType(t, 0);
+        if (Attachment.class.isAssignableFrom(actual)) {
+            return infos;
+        }
+        Collection<Object> objects = new ArrayList<>();
+        for (Attachment a : infos) {
+            objects.add(fromAttachment(a, actual, actual, anns));
+        }
+        return objects;
+    }
+
+    private Class<?> getActualType(Type type, int pos) {
+        Class<?> actual = null;
+        try {
+            actual = InjectionUtils.getActualType(type, pos);
+        } catch (Exception ex) {
+            // ignore;
+        }
+        return actual != null && actual != Object.class ? actual : Attachment.class;
+    }
+
+    private <T> Object fromAttachment(Attachment multipart, Class<T> c, Type t, Annotation[] anns)
+        throws IOException {
+        if (DataHandler.class.isAssignableFrom(c)) {
+            return multipart.getDataHandler();
+        } else if (DataSource.class.isAssignableFrom(c)) {
+            return multipart.getDataHandler().getDataSource();
+        } else if (Attachment.class.isAssignableFrom(c)) {
+            return multipart;
+        } else {
+            if (mediaTypeSupported(multipart.getContentType())) {
+                mc.put("org.apache.cxf.multipart.embedded", true);
+                mc.put("org.apache.cxf.multipart.embedded.ctype", multipart.getContentType());
+                mc.put("org.apache.cxf.multipart.embedded.input",
+                       multipart.getDataHandler().getInputStream());
+                anns = new Annotation[]{};
+            }
+            MessageBodyReader<T> r =
+                mc.getProviders().getMessageBodyReader(c, t, anns, multipart.getContentType());
+            if (r != null) {
+                InputStream is = multipart.getDataHandler().getInputStream();
+                return r.readFrom(c, t, anns, multipart.getContentType(), multipart.getHeaders(),
+                                  is);
+            }
+        }
+        return null;
+    }
+
+    private boolean mediaTypeSupported(MediaType mt) {
+        return "multipart".equals(mt.getType()) && MULTIPART_SUBTYPES.contains(mt.getSubtype());
+    }
+
+    public long getSize(Object t, Class<?> type, Type genericType, Annotation[] annotations,
+                        MediaType mediaType) {
+        return -1;
+    }
+
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations,
+                               MediaType mt) {
+        return isSupported(type, annotations, mt);
+    }
+
+
+    public void writeTo(Object obj, Class<?> type, Type genericType, Annotation[] anns, MediaType mt,
+                        MultivaluedMap<String, Object> headers, OutputStream os)
+        throws IOException, WebApplicationException {
+
+        List<Attachment> handlers = convertToDataHandlers(obj, type, genericType, anns, mt);
+        if (mc.get(AttachmentUtils.OUT_FILTERS) != null) {
+            List<MultipartOutputFilter> filters = CastUtils.cast((List<?>)mc.get(AttachmentUtils.OUT_FILTERS));
+            for (MultipartOutputFilter filter : filters) {
+                filter.filter(handlers);
+            }
+        }
+        mc.put(MultipartBody.OUTBOUND_MESSAGE_ATTACHMENTS, handlers);
+        handlers.get(0).getDataHandler().writeTo(os);
+    }
+
+    private List<Attachment> convertToDataHandlers(Object obj,
+                                                   Class<?> type, Type genericType,
+                                                   Annotation[] anns, MediaType mt)  throws IOException {
+        if (Map.class.isAssignableFrom(obj.getClass())) {
+            Map<Object, Object> objects = CastUtils.cast((Map<?, ?>)obj);
+            List<Attachment> handlers = new ArrayList<>(objects.size());
+            int i = 0;
+            for (Iterator<Map.Entry<Object, Object>> iter = objects.entrySet().iterator();
+                iter.hasNext();) {
+                Map.Entry<Object, Object> entry = iter.next();
+                Object value = entry.getValue();
+                Attachment handler = createDataHandler(value, value.getClass(),
+                                                       new Annotation[]{},
+                                                       entry.getKey().toString(),
+                                                       mt.toString(),
+                                                       i++);
+                handlers.add(handler);
+            }
+            return handlers;
+        }
+        String rootMediaType = getRootMediaType(anns, mt);
+        if (List.class.isAssignableFrom(obj.getClass())) {
+            return getAttachments((List<?>)obj, rootMediaType);
+        }
+        if (MultipartBody.class.isAssignableFrom(type)) {
+            List<Attachment> atts = ((MultipartBody)obj).getAllAttachments();
+            // these attachments may have no DataHandlers, but objects only
+            return getAttachments(atts, rootMediaType);
+        }
+        Attachment handler = createDataHandler(obj,
+                                               genericType, anns,
+                                               rootMediaType, mt.toString(), 1);
+        return Collections.singletonList(handler);
+    }
+
+    private List<Attachment> getAttachments(List<?> objects, String rootMediaType) throws IOException {
+        List<Attachment> handlers = new ArrayList<>(objects.size());
+        for (int i = 0; i < objects.size(); i++) {
+            Object value = objects.get(i);
+            Attachment handler = createDataHandler(value,
+                                           value.getClass(), new Annotation[]{},
+                                           rootMediaType, rootMediaType, i);
+            handlers.add(handler);
+        }
+        return handlers;
+    }
+
+    private <T> Attachment createDataHandler(T obj,
+                                             Type genericType,
+                                             Annotation[] anns,
+                                             String mimeType,
+                                             String mainMediaType,
+                                             int id) throws IOException {
+        @SuppressWarnings("unchecked")
+        Class<T> cls = (Class<T>)obj.getClass();
+        return createDataHandler(obj, cls, genericType, anns, mimeType, mainMediaType, id);
+    }
+    private <T> Attachment createDataHandler(T obj,
+                                         Class<T> cls,
+                                         Type genericType,
+                                         Annotation[] anns,
+                                         String mimeType,
+                                         String mainMediaType,
+                                         int id) throws IOException {
+        final DataHandler dh;
+        if (InputStream.class.isAssignableFrom(obj.getClass())) {
+            dh = createInputStreamDH((InputStream)obj, mimeType);
+        } else if (DataHandler.class.isAssignableFrom(obj.getClass())) {
+            dh = (DataHandler)obj;
+        } else if (DataSource.class.isAssignableFrom(obj.getClass())) {
+            dh = new DataHandler((DataSource)obj);
+        } else if (File.class.isAssignableFrom(obj.getClass())) {
+            File f = (File)obj;
+            ContentDisposition cd = mainMediaType.startsWith(MediaType.MULTIPART_FORM_DATA)
+                ? new ContentDisposition("form-data;name=file;filename=" + f.getName()) :  null;
+            return new Attachment(AttachmentUtil.BODY_ATTACHMENT_ID, Files.newInputStream(f.toPath()), cd);
+        } else if (Attachment.class.isAssignableFrom(obj.getClass())) {
+            Attachment att = (Attachment)obj;
+            if (att.getObject() == null) {
+                return att;
+            }
+            dh = getHandlerForObject(att.getObject(),
+                                     att.getObject().getClass(), new Annotation[]{},
+                                     att.getContentType().toString(), id);
+            return new Attachment(att.getContentId(), dh, att.getHeaders());
+        } else if (byte[].class.isAssignableFrom(obj.getClass())) {
+            ByteDataSource source = new ByteDataSource((byte[])obj);
+            source.setContentType(mimeType);
+            dh = new DataHandler(source);
+        } else {
+            dh = getHandlerForObject(obj, cls, genericType, anns, mimeType);
+        }
+        String contentId = getContentId(anns, id);
+        MultivaluedMap<String, String> headers = new MetadataMap<>();
+        headers.putSingle("Content-Type", mimeType);
+        
+        return new Attachment(contentId, dh, headers);
+    }
+
+    private String getContentId(Annotation[] anns, int id) {
+        Multipart part = AnnotationUtils.getAnnotation(anns, Multipart.class);
+        if (part != null && !"".equals(part.value())) {
+            return part.value();
+        }
+        return id == 0 ? AttachmentUtil.BODY_ATTACHMENT_ID : Integer.toString(id);
+    }
+
+    private <T> DataHandler getHandlerForObject(T obj,
+                                            Class<T> cls, Type genericType,
+                                            Annotation[] anns,
+                                            String mimeType) {
+        MediaType mt = JAXRSUtils.toMediaType(mimeType);
+        mc.put(ProviderFactory.ACTIVE_JAXRS_PROVIDER_KEY, this);
+
+        final MessageBodyWriter<T> r;
+        try {
+            r = mc.getProviders().getMessageBodyWriter(cls, genericType, anns, mt);
+        } finally {
+            mc.put(ProviderFactory.ACTIVE_JAXRS_PROVIDER_KEY, null);
+        }
+        if (r == null) {
+            org.apache.cxf.common.i18n.Message message =
+                new org.apache.cxf.common.i18n.Message("NO_MSG_WRITER",
+                                                   BUNDLE,
+                                                   cls);
+            LOG.severe(message.toString());
+            throw ExceptionUtils.toInternalServerErrorException(null, null);
+        }
+
+        return new MessageBodyWriterDataHandler<T>(r, obj, cls, genericType, anns, mt);
+    }
+    private <T> DataHandler getHandlerForObject(T obj,
+                                            Type genericType,
+                                            Annotation[] anns,
+                                            String mimeType, int id) {
+        @SuppressWarnings("unchecked")
+        Class<T> cls = (Class<T>)obj.getClass();
+        return getHandlerForObject(obj, cls, genericType, anns, mimeType);
+    }
+
+    private DataHandler createInputStreamDH(InputStream is, String mimeType) {
+        return new DataHandler(new InputStreamDataSource(is, mimeType));
+    }
+
+    private String getRootMediaType(Annotation[] anns, MediaType mt) {
+        String mimeType = mt.getParameters().get("type");
+        if (mimeType != null) {
+            return mimeType;
+        }
+        Multipart id = AnnotationUtils.getAnnotation(anns, Multipart.class);
+        if (id != null && !MediaType.WILDCARD.equals(id.type())) {
+            mimeType = id.type();
+        }
+        if (mimeType == null) {
+            if (PropertyUtils.isTrue(mc.getContextualProperty(Message.MTOM_ENABLED))) {
+                mimeType = "text/xml";
+            } else {
+                mimeType = MediaType.APPLICATION_OCTET_STREAM;
+            }
+        }
+        return mimeType;
+    }
+
+    private static class MessageBodyWriterDataHandler<T> extends DataHandler {
+        private MessageBodyWriter<T> writer;
+        private T obj;
+        private Class<T> cls;
+        private Type genericType;
+        private Annotation[] anns;
+        private MediaType contentType;
+        MessageBodyWriterDataHandler(MessageBodyWriter<T> writer,
+                                     T obj,
+                                     Class<T> cls,
+                                     Type genericType,
+                                     Annotation[] anns,
+                                     MediaType contentType) {
+            super(new ByteDataSource("1".getBytes(), contentType.toString()));
+            this.writer = writer;
+            this.obj = obj;
+            this.cls = cls;
+            this.genericType = genericType;
+            this.anns = anns;
+            this.contentType = contentType;
+        }
+
+        @Override
+        public void writeTo(OutputStream os) {
+            try {
+                writer.writeTo(obj, cls, genericType, anns, contentType,
+                               new MetadataMap<String, Object>(), os);
+            } catch (IOException ex) {
+                throw ExceptionUtils.toInternalServerErrorException(ex, null);
+            }
+        }
+
+        @Override
+        public String getContentType() {
+            return contentType.toString();
+        }
+
+        // TODO : throw UnsupportedOperationException for all other DataHandler methods
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/provider/SourceProvider.java b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/SourceProvider.java
new file mode 100644
index 0000000..76980b8
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/SourceProvider.java
@@ -0,0 +1,236 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+import java.util.logging.Logger;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.ext.xml.XMLSource;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.apache.cxf.staxutils.DepthExceededStaxException;
+import org.apache.cxf.staxutils.StaxSource;
+import org.apache.cxf.staxutils.StaxUtils;
+
+@Provider
+@Produces({"application/xml", "application/*+xml", "text/xml" })
+@Consumes({"application/xml", "application/*+xml", "text/xml", "text/html" })
+public class SourceProvider<T> extends AbstractConfigurableProvider implements
+    MessageBodyReader<T>, MessageBodyWriter<T> {
+
+    private static final String PREFERRED_FORMAT = "source-preferred-format";
+    private static final Logger LOG = LogUtils.getL7dLogger(SourceProvider.class);
+    @Context
+    private MessageContext context;
+
+
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) {
+        return Source.class.isAssignableFrom(type)
+            || Node.class.isAssignableFrom(type);
+    }
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) {
+        return Source.class.isAssignableFrom(type)
+               || XMLSource.class.isAssignableFrom(type)
+               || Document.class.isAssignableFrom(type);
+    }
+
+    public T readFrom(Class<T> source, Type genericType, Annotation[] annotations, MediaType m,
+        MultivaluedMap<String, String> headers, InputStream is)
+        throws IOException {
+
+        Class<?> theSource = source;
+        if (theSource == Source.class) {
+            String s = getPreferredSource();
+            if ("sax".equalsIgnoreCase(s) || "cxf.stax".equalsIgnoreCase(s)) {
+                theSource = SAXSource.class;
+            }
+        }
+        try {
+            if (DOMSource.class.isAssignableFrom(theSource) || Document.class.isAssignableFrom(theSource)) {
+
+                boolean docRequired = Document.class.isAssignableFrom(theSource);
+                XMLStreamReader reader = getReader(is);
+                try {
+                    Document doc = StaxUtils.read(reader);
+                    return source.cast(docRequired ? doc : new DOMSource(doc));
+                } catch (DepthExceededStaxException e) {
+                    throw ExceptionUtils.toWebApplicationException(null, JAXRSUtils.toResponse(413));
+                } catch (XMLStreamException e) {
+                    if (e.getMessage() != null && e.getMessage().startsWith("Maximum Number")) {
+                        throw ExceptionUtils.toWebApplicationException(null, JAXRSUtils.toResponse(413));
+                    }
+                    throw ExceptionUtils.toBadRequestException(e, null);
+                } catch (Exception e) {
+                    IOException ioex = new IOException("Problem creating a Source object");
+                    ioex.setStackTrace(e.getStackTrace());
+                    throw ioex;
+                } finally {
+                    try {
+                        reader.close();
+                    } catch (XMLStreamException e) {
+                        //ignore
+                    }
+                }
+            } else if (SAXSource.class.isAssignableFrom(theSource)
+                      || StaxSource.class.isAssignableFrom(theSource)) {
+                return source.cast(new StaxSource(getReader(is)));
+            } else if (StreamSource.class.isAssignableFrom(theSource)
+                       || Source.class.isAssignableFrom(theSource)) {
+                return source.cast(new StreamSource(getRealStream(is)));
+            } else if (XMLSource.class.isAssignableFrom(theSource)) {
+                return source.cast(new XMLSource(getRealStream(is)));
+            }
+        } catch (ClassCastException e) {
+            String msg = "Unsupported class: " + source.getName();
+            LOG.warning(msg);
+            throw ExceptionUtils.toInternalServerErrorException(null, null);
+        }
+
+        throw new IOException("Unrecognized source");
+    }
+
+    protected XMLStreamReader getReader(InputStream is) {
+        XMLStreamReader reader = getReaderFromMessage();
+        if (reader == null) {
+            reader = StaxUtils.createXMLStreamReader(is);
+        }
+        return configureReaderRestrictions(reader);
+    }
+
+    protected XMLStreamReader configureReaderRestrictions(XMLStreamReader reader) {
+        Message message = PhaseInterceptorChain.getCurrentMessage();
+        if (message != null) {
+            try {
+                return StaxUtils.configureReader(reader, message);
+            } catch (XMLStreamException ex) {
+                throw ExceptionUtils.toInternalServerErrorException(ex, null);
+            }
+        }
+        return reader;
+    }
+
+    protected InputStream getRealStream(InputStream is) throws IOException {
+        XMLStreamReader reader = getReaderFromMessage();
+        return reader == null ? is : getStreamFromReader(reader);
+    }
+
+    private InputStream getStreamFromReader(XMLStreamReader input)
+        throws IOException {
+
+        try (CachedOutputStream out = new CachedOutputStream()) {
+            StaxUtils.copy(input, out);
+            return out.getInputStream();
+        } catch (XMLStreamException ex) {
+            throw new IOException("XMLStreamException:" + ex.getMessage());
+        }
+    }
+
+    protected XMLStreamReader getReaderFromMessage() {
+        MessageContext mc = getContext();
+        if (mc != null) {
+            return mc.getContent(XMLStreamReader.class);
+        }
+        return null;
+    }
+
+    public void writeTo(T source, Class<?> clazz, Type genericType, Annotation[] annotations,
+        MediaType mt, MultivaluedMap<String, Object> headers, OutputStream os)
+        throws IOException {
+
+        String encoding = HttpUtils.getSetEncoding(mt, headers, StandardCharsets.UTF_8.name());
+
+        final XMLStreamReader reader;
+        if (source instanceof Source) {
+            reader = StaxUtils.createXMLStreamReader((Source)source);
+        } else if (source instanceof Document) {
+            reader = StaxUtils.createXMLStreamReader((Document)source);
+        } else {
+            reader = StaxUtils.createXMLStreamReader(new DOMSource((Node)source));
+        }
+        XMLStreamWriter writer = StaxUtils.createXMLStreamWriter(os, encoding);
+        try {
+            StaxUtils.copy(reader, writer);
+        } catch (XMLStreamException e) {
+            throw ExceptionUtils.toInternalServerErrorException(e, null);
+        } finally {
+            try {
+                reader.close();
+            } catch (XMLStreamException e) {
+                //ignore
+            }
+            try {
+                writer.flush();
+                writer.close();
+            } catch (XMLStreamException e) {
+                //ignore
+            }
+        }
+    }
+
+    public long getSize(T source, Class<?> type, Type genericType, Annotation[] annotations,
+                        MediaType mt) {
+        return -1;
+    }
+
+    protected String getPreferredSource() {
+        MessageContext mc = getContext();
+        String source = null;
+        if (mc != null) {
+            source = (String)mc.getContextualProperty(PREFERRED_FORMAT);
+        }
+        return source != null ? source : "sax";
+
+    }
+
+    protected MessageContext getContext() {
+        return context;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProvider.java b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProvider.java
new file mode 100644
index 0000000..4250963
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/XSLTJaxbProvider.java
@@ -0,0 +1,588 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.Provider;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.xml.sax.XMLFilter;
+import org.xml.sax.XMLReader;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.ext.xml.XSLTTransform;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.apache.cxf.staxutils.StaxSource;
+import org.apache.cxf.staxutils.StaxUtils;
+
+@Produces({"application/xml", "application/*+xml", "text/xml", "text/html" })
+@Consumes({"application/xml", "application/*+xml", "text/xml", "text/html" })
+@Provider
+public class XSLTJaxbProvider<T> extends JAXBElementProvider<T> {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(XSLTJaxbProvider.class);
+
+    private static final String ABSOLUTE_PATH_PARAMETER = "absolute.path";
+    private static final String BASE_PATH_PARAMETER = "base.path";
+    private static final String RELATIVE_PATH_PARAMETER = "relative.path";
+    private static final String XSLT_TEMPLATE_PROPERTY = "xslt.template";
+    private SAXTransformerFactory factory;
+    private Templates inTemplates;
+    private Templates outTemplates;
+    private Map<String, Templates> inMediaTemplates;
+    private Map<String, Templates> outMediaTemplates;
+    private ConcurrentHashMap<String, Templates> annotationTemplates =
+        new ConcurrentHashMap<>();
+
+    private List<String> inClassesToHandle;
+    private List<String> outClassesToHandle;
+    private Map<String, Object> inParamsMap;
+    private Map<String, Object> outParamsMap;
+    private Map<String, String> inProperties;
+    private Map<String, String> outProperties;
+    private URIResolver uriResolver;
+    private String systemId;
+
+    private boolean supportJaxbOnly;
+    private boolean refreshTemplates;
+    private boolean secureProcessing = true;
+
+    public void setSupportJaxbOnly(boolean support) {
+        this.supportJaxbOnly = support;
+    }
+
+    @Override
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] anns, MediaType mt) {
+        if (!super.isReadable(type, genericType, anns, mt)) {
+            return false;
+        }
+
+        if (InjectionUtils.isSupportedCollectionOrArray(type)) {
+            return supportJaxbOnly;
+        }
+
+        // if the user has set the list of in classes and a given class
+        // is in that list then it can only be handled by the template
+        if (inClassCanBeHandled(type.getName()) || inClassesToHandle == null && !supportJaxbOnly) {
+            return inTemplatesAvailable(type, anns, mt);
+        }
+        return supportJaxbOnly;
+    }
+
+    @Override
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] anns, MediaType mt) {
+        // JAXB support is required
+        if (!super.isWriteable(type, genericType, anns, mt)) {
+            return false;
+        }
+        if (InjectionUtils.isSupportedCollectionOrArray(type)) {
+            return supportJaxbOnly;
+        }
+
+        // if the user has set the list of out classes and a given class
+        // is in that list then it can only be handled by the template
+        if (outClassCanBeHandled(type.getName()) || outClassesToHandle == null && !supportJaxbOnly) {
+            return outTemplatesAvailable(type, anns, mt);
+        }
+        return supportJaxbOnly;
+    }
+
+    protected boolean inTemplatesAvailable(Class<?> cls, Annotation[] anns, MediaType mt) {
+        return inTemplates != null
+            || inMediaTemplates != null && inMediaTemplates.containsKey(mt.getType() + "/"
+                                                                        + mt.getSubtype())
+            || getTemplatesFromAnnotation(cls, anns, mt) != null;
+    }
+
+    protected boolean outTemplatesAvailable(Class<?> cls, Annotation[] anns, MediaType mt) {
+        return outTemplates != null
+            || outMediaTemplates != null && outMediaTemplates.containsKey(mt.getType()
+                                                                          + "/" + mt.getSubtype())
+            || getTemplatesFromAnnotation(cls, anns, mt) != null;
+    }
+
+    protected Templates getTemplatesFromAnnotation(Class<?> cls,
+                                                   Annotation[] anns,
+                                                   MediaType mt) {
+        Templates t = null;
+        XSLTTransform ann = getXsltTransformAnn(anns, mt);
+        if (ann != null) {
+            t = annotationTemplates.get(ann.value());
+            if (t == null || refreshTemplates) {
+                String path = ann.value();
+                final String cp = "classpath:";
+                if (!path.startsWith(cp)) {
+                    path = cp + path;
+                }
+                t = createTemplates(path);
+                if (t == null) {
+                    createTemplates(ClassLoaderUtils.getResource(ann.value(), cls));
+                }
+                if (t != null) {
+                    annotationTemplates.put(ann.value(), t);
+                }
+            }
+        }
+        return t;
+
+    }
+
+    protected Templates getAnnotationTemplates(Annotation[] anns) {
+        Templates t = null;
+        XSLTTransform ann = AnnotationUtils.getAnnotation(anns, XSLTTransform.class);
+        if (ann != null) {
+            t = annotationTemplates.get(ann.value());
+        }
+        return t;
+
+    }
+
+    protected XSLTTransform getXsltTransformAnn(Annotation[] anns, MediaType mt) {
+        XSLTTransform ann = AnnotationUtils.getAnnotation(anns, XSLTTransform.class);
+        if (ann != null && ann.type() != XSLTTransform.TransformType.CLIENT) {
+            if (ann.mediaTypes().length > 0) {
+                for (String s : ann.mediaTypes()) {
+                    if (mt.isCompatible(JAXRSUtils.toMediaType(s))) {
+                        return ann;
+                    }
+                }
+                return null;
+            }
+            return ann;
+        }
+        return null;
+    }
+
+
+
+    protected Templates getInTemplates(Annotation[] anns, MediaType mt) {
+        Templates t = createTemplatesFromContext();
+        if (t != null) {
+            return t;
+        }
+        t = inTemplates != null ? inTemplates
+            : inMediaTemplates != null ? inMediaTemplates.get(mt.getType() + "/" + mt.getSubtype()) : null;
+        if (t == null) {
+            t = getAnnotationTemplates(anns);
+        }
+        return t;
+    }
+
+    protected Templates getOutTemplates(Annotation[] anns, MediaType mt) {
+        Templates t = createTemplatesFromContext();
+        if (t != null) {
+            return t;
+        }
+        t = outTemplates != null ? outTemplates
+            : outMediaTemplates != null ? outMediaTemplates.get(mt.getType() + "/" + mt.getSubtype()) : null;
+        if (t == null) {
+            t = getAnnotationTemplates(anns);
+        }
+        return t;
+    }
+
+    @Override
+    protected Object unmarshalFromInputStream(Unmarshaller unmarshaller, InputStream is,
+                                              Annotation[] anns, MediaType mt)
+        throws JAXBException {
+        try {
+
+            Templates t = createTemplates(getInTemplates(anns, mt), inParamsMap, inProperties);
+            if (t == null && supportJaxbOnly) {
+                return super.unmarshalFromInputStream(unmarshaller, is, anns, mt);
+            }
+
+            if (unmarshaller.getClass().getName().contains("eclipse")) {
+                //eclipse MOXy doesn't work properly with the XMLFilter/Reader thing
+                //so we need to bounce through a DOM
+                Source reader = new StaxSource(StaxUtils.createXMLStreamReader(is));
+                DOMResult dom = new DOMResult();
+                t.newTransformer().transform(reader, dom);
+                return unmarshaller.unmarshal(dom.getNode());
+            }
+            XMLFilter filter;
+            try {
+                filter = factory.newXMLFilter(t);
+            } catch (TransformerConfigurationException ex) {
+                TemplatesImpl ti = (TemplatesImpl)t;
+                filter = factory.newXMLFilter(ti.getTemplates());
+                trySettingProperties(filter, ti);
+            }
+            XMLReader reader = new StaxSource(StaxUtils.createXMLStreamReader(is));
+            filter.setParent(reader);
+            SAXSource source = new SAXSource();
+            source.setXMLReader(filter);
+            if (systemId != null) {
+                source.setSystemId(systemId);
+            }
+            return unmarshaller.unmarshal(source);
+        } catch (TransformerException ex) {
+            LOG.warning("Transformation exception : " + ex.getMessage());
+            throw ExceptionUtils.toInternalServerErrorException(ex, null);
+        }
+    }
+
+    private void trySettingProperties(Object filter, TemplatesImpl ti) {
+        try {
+            //Saxon doesn't allow creating a Filter or Handler from anything other than it's original
+            //Templates.  That then requires setting the parameters after the fact, but there
+            //isn't a standard API for that, so we have to grab the Transformer via reflection to
+            //set the parameters.
+            Transformer tr = (Transformer)filter.getClass().getMethod("getTransformer").invoke(filter);
+            tr.setURIResolver(ti.resolver);
+            for (Map.Entry<String, Object> entry : ti.transformParameters.entrySet()) {
+                tr.setParameter(entry.getKey(), entry.getValue());
+            }
+            for (Map.Entry<String, String> entry : ti.outProps.entrySet()) {
+                tr.setOutputProperty(entry.getKey(), entry.getValue());
+            }
+        } catch (Exception e) {
+            LOG.log(Level.WARNING, "Could not set properties for transfomer", e);
+        }
+    }
+
+    @Override
+    protected Object unmarshalFromReader(Unmarshaller unmarshaller, XMLStreamReader reader,
+                                         Annotation[] anns, MediaType mt)
+        throws JAXBException {
+        CachedOutputStream out = new CachedOutputStream();
+        try {
+            XMLStreamWriter writer = StaxUtils.createXMLStreamWriter(out);
+            StaxUtils.copy(new StaxSource(reader), writer);
+            writer.writeEndDocument();
+            writer.flush();
+            writer.close();
+            return unmarshalFromInputStream(unmarshaller, out.getInputStream(), anns, mt);
+        } catch (Exception ex) {
+            throw ExceptionUtils.toBadRequestException(ex, null);
+        }
+    }
+
+    @Override
+    protected void marshalToWriter(Marshaller ms, Object obj, XMLStreamWriter writer,
+                                   Annotation[] anns, MediaType mt)
+        throws Exception {
+        CachedOutputStream out = new CachedOutputStream();
+        marshalToOutputStream(ms, obj, out, anns, mt);
+
+        StaxUtils.copy(new StreamSource(out.getInputStream()), writer);
+    }
+
+    @Override
+    protected void addAttachmentMarshaller(Marshaller ms) {
+        // complete
+    }
+
+    protected Result getStreamResult(OutputStream os, Annotation[] anns, MediaType mt) throws Exception {
+        return new StreamResult(os);
+    }
+
+    @Override
+    protected void marshalToOutputStream(Marshaller ms, Object obj, OutputStream os,
+                                         Annotation[] anns, MediaType mt)
+        throws Exception {
+
+        Templates t = createTemplates(getOutTemplates(anns, mt), outParamsMap, outProperties);
+        if (t == null && supportJaxbOnly) {
+            super.marshalToOutputStream(ms, obj, os, anns, mt);
+            return;
+        }
+        org.apache.cxf.common.jaxb.JAXBUtils.setMinimumEscapeHandler(ms);
+        TransformerHandler th;
+        try {
+            th = factory.newTransformerHandler(t);
+        } catch (TransformerConfigurationException ex) {
+            TemplatesImpl ti = (TemplatesImpl)t;
+            th = factory.newTransformerHandler(ti.getTemplates());
+            this.trySettingProperties(th, ti);
+        }
+        Result result = getStreamResult(os, anns, mt);
+        if (systemId != null) {
+            result.setSystemId(systemId);
+        }
+        th.setResult(result);
+
+        if (getContext() == null) {
+            th.startDocument();
+        }
+        ms.marshal(obj, th);
+        if (getContext() == null) {
+            th.endDocument();
+        }
+    }
+
+    public void setOutTemplate(String loc) {
+        outTemplates = createTemplates(loc);
+    }
+
+    public void setInTemplate(String loc) {
+        inTemplates = createTemplates(loc);
+    }
+
+    public void setInMediaTemplates(Map<String, String> map) {
+        inMediaTemplates = new HashMap<>();
+        for (Map.Entry<String, String> entry : map.entrySet()) {
+            inMediaTemplates.put(entry.getKey(), createTemplates(entry.getValue()));
+        }
+    }
+
+    public void setOutMediaTemplates(Map<String, String> map) {
+        outMediaTemplates = new HashMap<>();
+        for (Map.Entry<String, String> entry : map.entrySet()) {
+            outMediaTemplates.put(entry.getKey(), createTemplates(entry.getValue()));
+        }
+    }
+
+    public void setResolver(URIResolver resolver) {
+        uriResolver = resolver;
+        if (factory != null) {
+            factory.setURIResolver(uriResolver);
+        }
+    }
+
+    public void setSystemId(String system) {
+        systemId = system;
+    }
+
+    public void setInParameters(Map<String, Object> inParams) {
+        this.inParamsMap = inParams;
+    }
+
+    public void setOutParameters(Map<String, Object> outParams) {
+        this.outParamsMap = outParams;
+    }
+
+    public void setInProperties(Map<String, String> inProps) {
+        this.inProperties = inProps;
+    }
+
+    public void setOutProperties(Map<String, String> outProps) {
+        this.outProperties = outProps;
+    }
+
+    public void setInClassNames(List<String> classNames) {
+        inClassesToHandle = classNames;
+    }
+
+    public boolean inClassCanBeHandled(String className) {
+        return inClassesToHandle != null && inClassesToHandle.contains(className);
+    }
+
+    public void setOutClassNames(List<String> classNames) {
+        outClassesToHandle = classNames;
+    }
+
+    public boolean outClassCanBeHandled(String className) {
+        return outClassesToHandle != null && outClassesToHandle.contains(className);
+    }
+
+    protected Templates createTemplates(Templates templates,
+                                      Map<String, Object> configuredParams,
+                                      Map<String, String> outProps) {
+        if (templates == null) {
+            if (supportJaxbOnly) {
+                return null;
+            }
+            LOG.severe("No template is available");
+            throw ExceptionUtils.toInternalServerErrorException(null, null);
+        }
+
+        TemplatesImpl templ = new TemplatesImpl(templates, uriResolver);
+        MessageContext mc = getContext();
+        if (mc != null) {
+            UriInfo ui = mc.getUriInfo();
+            MultivaluedMap<String, String> params = ui.getPathParameters();
+            for (Map.Entry<String, List<String>> entry : params.entrySet()) {
+                String value = entry.getValue().get(0);
+                int ind = value.indexOf(';');
+                if (ind > 0) {
+                    value = value.substring(0, ind);
+                }
+                templ.setTransformerParameter(entry.getKey(), value);
+            }
+
+            List<PathSegment> segments = ui.getPathSegments();
+            if (!segments.isEmpty()) {
+                setTransformParameters(templ, segments.get(segments.size() - 1).getMatrixParameters());
+            }
+            setTransformParameters(templ, ui.getQueryParameters());
+            templ.setTransformerParameter(ABSOLUTE_PATH_PARAMETER, ui.getAbsolutePath().toString());
+            templ.setTransformerParameter(RELATIVE_PATH_PARAMETER, ui.getPath());
+            templ.setTransformerParameter(BASE_PATH_PARAMETER, ui.getBaseUri().toString());
+            if (configuredParams != null) {
+                for (Map.Entry<String, Object> entry : configuredParams.entrySet()) {
+                    templ.setTransformerParameter(entry.getKey(), entry.getValue());
+                }
+            }
+        }
+        if (outProps != null) {
+            templ.setOutProperties(outProps);
+        }
+
+        return templ;
+    }
+
+    private void setTransformParameters(TemplatesImpl templ, MultivaluedMap<String, String> params) {
+        for (Map.Entry<String, List<String>> entry : params.entrySet()) {
+            templ.setTransformerParameter(entry.getKey(), entry.getValue().get(0));
+        }
+    }
+
+    protected Templates createTemplates(String loc) {
+        try {
+            return createTemplates(ResourceUtils.getResourceURL(loc, this.getBus()));
+        } catch (Exception ex) {
+            LOG.warning("No template can be created : " + ex.getMessage());
+        }
+        return null;
+    }
+
+    protected Templates createTemplatesFromContext() {
+        MessageContext mc = getContext();
+        if (mc != null) {
+            String template = (String)mc.getContextualProperty(XSLT_TEMPLATE_PROPERTY);
+            if (template != null) {
+                return createTemplates(template);
+            }
+        }
+        return null;
+    }
+
+    protected Templates createTemplates(URL urlStream) {
+        if (urlStream == null) {
+            return null;
+        }
+
+        try (Reader r = new BufferedReader(
+                           new InputStreamReader(urlStream.openStream(), StandardCharsets.UTF_8))) {
+            Source source = new StreamSource(r);
+            source.setSystemId(urlStream.toExternalForm());
+            if (factory == null) {
+                factory = (SAXTransformerFactory)TransformerFactory.newInstance();
+                factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, secureProcessing);
+                if (uriResolver != null) {
+                    factory.setURIResolver(uriResolver);
+                }
+            }
+            return factory.newTemplates(source);
+
+        } catch (Exception ex) {
+            LOG.warning("No template can be created : " + ex.getMessage());
+        }
+        return null;
+    }
+
+    public void setRefreshTemplates(boolean refresh) {
+        this.refreshTemplates = refresh;
+    }
+
+    public void setSecureProcessing(boolean secureProcessing) {
+        this.secureProcessing = secureProcessing;
+    }
+
+    private static class TemplatesImpl implements Templates {
+
+        private Templates templates;
+        private URIResolver resolver;
+        private Map<String, Object> transformParameters = new HashMap<>();
+        private Map<String, String> outProps = new HashMap<>();
+
+        TemplatesImpl(Templates templates, URIResolver resolver) {
+            this.templates = templates;
+            this.resolver = resolver;
+        }
+
+        public Templates getTemplates() {
+            return templates;
+        }
+
+        public void setTransformerParameter(String name, Object value) {
+            transformParameters.put(name, value);
+        }
+
+        public void setOutProperties(Map<String, String> props) {
+            this.outProps = props;
+        }
+
+        public Properties getOutputProperties() {
+            return templates.getOutputProperties();
+        }
+
+        public Transformer newTransformer() throws TransformerConfigurationException {
+            Transformer tr = templates.newTransformer();
+            tr.setURIResolver(resolver);
+            for (Map.Entry<String, Object> entry : transformParameters.entrySet()) {
+                tr.setParameter(entry.getKey(), entry.getValue());
+            }
+            for (Map.Entry<String, String> entry : outProps.entrySet()) {
+                tr.setOutputProperty(entry.getKey(), entry.getValue());
+            }
+            return tr;
+        }
+
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/security/JAASAuthenticationFilter.java b/transform/src/patch/java/org/apache/cxf/jaxrs/security/JAASAuthenticationFilter.java
new file mode 100644
index 0000000..4dd05e3
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/security/JAASAuthenticationFilter.java
@@ -0,0 +1,170 @@
+/**
+ * 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.cxf.jaxrs.security;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Priority;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.Configuration;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.core.UriBuilder;
+
+import org.apache.cxf.interceptor.security.JAASLoginInterceptor;
+import org.apache.cxf.interceptor.security.NamePasswordCallbackHandler;
+import org.apache.cxf.jaxrs.impl.HttpHeadersImpl;
+import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
+
+@PreMatching
+@Priority(Priorities.AUTHENTICATION)
+public class JAASAuthenticationFilter implements ContainerRequestFilter {
+
+    private static final List<MediaType> HTML_MEDIA_TYPES =
+        Arrays.asList(MediaType.APPLICATION_XHTML_XML_TYPE, MediaType.TEXT_HTML_TYPE);
+
+    private URI redirectURI;
+    private String realmName;
+    private boolean ignoreBasePath = true;
+
+    private JAASLoginInterceptor interceptor;
+
+    public JAASAuthenticationFilter() {
+        interceptor = new JAASLoginInterceptor() {
+            protected CallbackHandler getCallbackHandler(String name, String password) {
+                return JAASAuthenticationFilter.this.getCallbackHandler(name, password);
+            }
+        };
+        interceptor.setUseDoAs(false);
+    }
+
+    @Deprecated
+    public void setRolePrefix(String name) {
+        interceptor.setRolePrefix(name);
+    }
+
+
+    public void setIgnoreBasePath(boolean ignore) {
+        this.ignoreBasePath = ignore;
+    }
+
+    public void setContextName(String name) {
+        interceptor.setContextName(name);
+    }
+
+    public void setLoginConfig(Configuration config) {
+        interceptor.setLoginConfig(config);
+    }
+
+    public void setRoleClassifier(String rc) {
+        interceptor.setRoleClassifier(rc);
+    }
+
+    public void setRoleClassifierType(String rct) {
+        interceptor.setRoleClassifierType(rct);
+    }
+
+
+    public void setRedirectURI(String uri) {
+        this.redirectURI = URI.create(uri);
+    }
+
+    public void setRealmName(String name) {
+        this.realmName = name;
+    }
+
+    protected CallbackHandler getCallbackHandler(String name, String password) {
+        return new NamePasswordCallbackHandler(name, password);
+    }
+
+    @Override
+    public void filter(ContainerRequestContext context) {
+        Message m = JAXRSUtils.getCurrentMessage();
+        try {
+            interceptor.handleMessage(m);
+        } catch (SecurityException ex) {
+            context.abortWith(handleAuthenticationException(ex, m));
+        }
+    }
+
+    protected Response handleAuthenticationException(SecurityException ex, Message m) {
+        HttpHeaders headers = new HttpHeadersImpl(m);
+        if (redirectURI != null && isRedirectPossible(headers)) {
+
+            final URI finalRedirectURI;
+
+            if (!redirectURI.isAbsolute()) {
+                String endpointAddress = HttpUtils.getEndpointAddress(m);
+                Object basePathProperty = m.get(Message.BASE_PATH);
+                if (ignoreBasePath && basePathProperty != null && !"/".equals(basePathProperty)) {
+                    int index = endpointAddress.lastIndexOf(basePathProperty.toString());
+                    if (index != -1) {
+                        endpointAddress = endpointAddress.substring(0, index);
+                    }
+                }
+                finalRedirectURI = UriBuilder.fromUri(endpointAddress).path(redirectURI.toString()).build();
+            } else {
+                finalRedirectURI = redirectURI;
+            }
+
+            return Response.status(getRedirectStatus()).
+                    header(HttpHeaders.LOCATION, finalRedirectURI).build();
+        }
+        ResponseBuilder builder = Response.status(Response.Status.UNAUTHORIZED);
+
+        StringBuilder sb = new StringBuilder();
+
+        List<String> authHeader = headers.getRequestHeader(HttpHeaders.AUTHORIZATION);
+        if (authHeader != null && !authHeader.isEmpty()) {
+            // should HttpHeadersImpl do it ?
+            String[] authValues = authHeader.get(0).split(" ");
+            if (authValues.length > 0) {
+                sb.append(authValues[0]);
+            }
+        } else {
+            sb.append("Basic");
+        }
+        if (realmName != null) {
+            sb.append(" realm=\"").append(realmName).append('"');
+        }
+        builder.header(HttpHeaders.WWW_AUTHENTICATE, sb.toString());
+
+        return builder.build();
+    }
+
+    protected Response.Status getRedirectStatus() {
+        return Response.Status.TEMPORARY_REDIRECT;
+    }
+
+    protected boolean isRedirectPossible(HttpHeaders headers) {
+        List<MediaType> clientTypes = headers.getAcceptableMediaTypes();
+        return !JAXRSUtils.intersectMimeTypes(clientTypes, HTML_MEDIA_TYPES, false)
+                          .isEmpty();
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/security/KerberosAuthenticationFilter.java b/transform/src/patch/java/org/apache/cxf/jaxrs/security/KerberosAuthenticationFilter.java
new file mode 100644
index 0000000..1c7a164
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/security/KerberosAuthenticationFilter.java
@@ -0,0 +1,251 @@
+/**
+ * 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.cxf.jaxrs.security;
+
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.List;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.security.SimplePrincipal;
+import org.apache.cxf.common.security.SimpleSecurityContext;
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.security.SecurityContext;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+@PreMatching
+public class KerberosAuthenticationFilter implements ContainerRequestFilter {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(KerberosAuthenticationFilter.class);
+
+    private static final String NEGOTIATE_SCHEME = "Negotiate";
+    private static final String PROPERTY_USE_KERBEROS_OID = "auth.spnego.useKerberosOid";
+    private static final String KERBEROS_OID = "1.2.840.113554.1.2.2";
+    private static final String SPNEGO_OID = "1.3.6.1.5.5.2";
+
+    private MessageContext messageContext;
+    private CallbackHandler callbackHandler;
+    private Configuration loginConfig;
+    private String loginContextName = "";
+    private String servicePrincipalName;
+    private String realm;
+
+    @Override
+    public void filter(ContainerRequestContext context) {
+
+        List<String> authHeaders = messageContext.getHttpHeaders()
+            .getRequestHeader(HttpHeaders.AUTHORIZATION);
+        if (authHeaders == null || authHeaders.size() != 1) {
+            LOG.fine("No Authorization header is available");
+            throw ExceptionUtils.toNotAuthorizedException(null, getFaultResponse());
+        }
+        String[] authPair = authHeaders.get(0).split(" ");
+        if (authPair.length != 2 || !NEGOTIATE_SCHEME.equalsIgnoreCase(authPair[0])) {
+            LOG.fine("Negotiate Authorization scheme is expected");
+            throw ExceptionUtils.toNotAuthorizedException(null, getFaultResponse());
+        }
+
+        byte[] serviceTicket = getServiceTicket(authPair[1]);
+
+        try {
+            Subject serviceSubject = loginAndGetSubject();
+
+            GSSContext gssContext = createGSSContext();
+
+            Subject.doAs(serviceSubject, new ValidateServiceTicketAction(gssContext, serviceTicket));
+
+            GSSName srcName = gssContext.getSrcName();
+            if (srcName == null) {
+                throw ExceptionUtils.toNotAuthorizedException(null, getFaultResponse());
+            }
+
+            String complexUserName = srcName.toString();
+
+            String simpleUserName = complexUserName;
+            int index = simpleUserName.lastIndexOf('@');
+            if (index > 0) {
+                simpleUserName = simpleUserName.substring(0, index);
+            }
+            Message m = JAXRSUtils.getCurrentMessage();
+            m.put(SecurityContext.class, createSecurityContext(simpleUserName, complexUserName, gssContext));
+
+            if (!gssContext.getCredDelegState()) {
+                gssContext.dispose();
+            }
+
+        } catch (LoginException e) {
+            LOG.fine("Unsuccessful JAAS login for the service principal: " + e.getMessage());
+            throw ExceptionUtils.toNotAuthorizedException(e, getFaultResponse());
+        } catch (GSSException e) {
+            LOG.fine("GSS API exception: " + e.getMessage());
+            throw ExceptionUtils.toNotAuthorizedException(e, getFaultResponse());
+        } catch (PrivilegedActionException e) {
+            LOG.fine("PrivilegedActionException: " + e.getMessage());
+            throw ExceptionUtils.toNotAuthorizedException(e, getFaultResponse());
+        }
+    }
+
+    protected SecurityContext createSecurityContext(String simpleUserName, String complexUserName,
+                                                    GSSContext gssContext) {
+        return new KerberosSecurityContext(new KerberosPrincipal(simpleUserName, complexUserName), gssContext);
+    }
+
+    protected GSSContext createGSSContext() throws GSSException {
+        boolean useKerberosOid = PropertyUtils.isTrue(
+            messageContext.getContextualProperty(PROPERTY_USE_KERBEROS_OID));
+        Oid oid = new Oid(useKerberosOid ? KERBEROS_OID : SPNEGO_OID);
+
+        GSSManager gssManager = GSSManager.getInstance();
+
+        String spn = getCompleteServicePrincipalName();
+        GSSName gssService = gssManager.createName(spn, null);
+
+        return gssManager.createContext(gssService.canonicalize(oid),
+                   oid, null, GSSContext.DEFAULT_LIFETIME);
+    }
+
+    protected Subject loginAndGetSubject() throws LoginException {
+
+        // The login without a callback can work if
+        // - Kerberos keytabs are used with a principal name set in the JAAS config
+        // - Kerberos is integrated into the OS logon process
+        //   meaning that a process which runs this code has the
+        //   user identity
+
+        final LoginContext lc;
+        if (!StringUtils.isEmpty(loginContextName) || loginConfig != null) {
+            lc = new LoginContext(loginContextName, null, callbackHandler, loginConfig);
+        } else {
+            LOG.fine("LoginContext can not be initialized");
+            throw new LoginException();
+        }
+        lc.login();
+        return lc.getSubject();
+    }
+
+    private byte[] getServiceTicket(String encodedServiceTicket) {
+        try {
+            return Base64Utility.decode(encodedServiceTicket);
+        } catch (Base64Exception ex) {
+            throw ExceptionUtils.toNotAuthorizedException(null, getFaultResponse());
+        }
+    }
+
+    private static Response getFaultResponse() {
+        return JAXRSUtils.toResponseBuilder(401).header(HttpHeaders.WWW_AUTHENTICATE, NEGOTIATE_SCHEME).build();
+    }
+
+    protected String getCompleteServicePrincipalName() {
+        String name = servicePrincipalName == null
+            ? "HTTP/" + messageContext.getUriInfo().getBaseUri().getHost() : servicePrincipalName;
+        if (realm != null) {
+            name += "@" + realm;
+        }
+        return name;
+
+
+    }
+
+    @Context
+    public void setMessageContext(MessageContext context) {
+        this.messageContext = context;
+    }
+
+    public void setLoginContextName(String contextName) {
+        this.loginContextName = contextName;
+    }
+
+    public void setServicePrincipalName(String servicePrincipalName) {
+        this.servicePrincipalName = servicePrincipalName;
+    }
+
+    public void setRealm(String realm) {
+        this.realm = realm;
+    }
+
+    public void setCallbackHandler(CallbackHandler callbackHandler) {
+        this.callbackHandler = callbackHandler;
+    }
+
+    private static final class ValidateServiceTicketAction implements PrivilegedExceptionAction<byte[]> {
+        private final GSSContext context;
+        private final byte[] token;
+
+        private ValidateServiceTicketAction(GSSContext context, byte[] token) {
+            this.context = context;
+            this.token = token;
+        }
+
+        public byte[] run() throws GSSException {
+            return context.acceptSecContext(token, 0, token.length);
+        }
+    }
+
+    public static class KerberosPrincipal extends SimplePrincipal {
+        private static final long serialVersionUID = 1L;
+        private String complexName;
+        public KerberosPrincipal(String simpleName, String complexName) {
+            super(simpleName);
+            this.complexName = complexName;
+        }
+
+        public String getKerberosName() {
+            return complexName;
+        }
+    }
+
+    public static class KerberosSecurityContext extends SimpleSecurityContext {
+        private GSSContext context;
+        public KerberosSecurityContext(KerberosPrincipal principal,
+                                       GSSContext context) {
+            super(principal);
+            this.context = context;
+        }
+
+        public GSSContext getGSSContext() {
+            return context;
+        }
+    }
+
+
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java b/transform/src/patch/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java
new file mode 100644
index 0000000..290c223
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java
@@ -0,0 +1,640 @@
+/**
+ * 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.cxf.jaxrs.servlet;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.ws.rs.core.Application;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PrimitiveUtils;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.feature.Feature;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.lifecycle.PerRequestResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.jaxrs.model.ApplicationInfo;
+import org.apache.cxf.jaxrs.model.ProviderInfo;
+import org.apache.cxf.jaxrs.provider.ProviderFactory;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.service.invoker.Invoker;
+import org.apache.cxf.transport.http.DestinationRegistry;
+import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
+
+public class CXFNonSpringJaxrsServlet extends CXFNonSpringServlet {
+
+    private static final long serialVersionUID = -8916352798780577499L;
+
+    private static final Logger LOG = LogUtils.getL7dLogger(CXFNonSpringJaxrsServlet.class);
+
+    private static final String USER_MODEL_PARAM = "user.model";
+    private static final String SERVICE_ADDRESS_PARAM = "jaxrs.address";
+    private static final String IGNORE_APP_PATH_PARAM = "jaxrs.application.address.ignore";
+    private static final String SERVICE_CLASSES_PARAM = "jaxrs.serviceClasses";
+    private static final String PROVIDERS_PARAM = "jaxrs.providers";
+    private static final String FEATURES_PARAM = "jaxrs.features";
+    private static final String OUT_INTERCEPTORS_PARAM = "jaxrs.outInterceptors";
+    private static final String OUT_FAULT_INTERCEPTORS_PARAM = "jaxrs.outFaultInterceptors";
+    private static final String IN_INTERCEPTORS_PARAM = "jaxrs.inInterceptors";
+    private static final String INVOKER_PARAM = "jaxrs.invoker";
+    private static final String SERVICE_SCOPE_PARAM = "jaxrs.scope";
+    private static final String EXTENSIONS_PARAM = "jaxrs.extensions";
+    private static final String LANGUAGES_PARAM = "jaxrs.languages";
+    private static final String PROPERTIES_PARAM = "jaxrs.properties";
+    private static final String SCHEMAS_PARAM = "jaxrs.schemaLocations";
+    private static final String DOC_LOCATION_PARAM = "jaxrs.documentLocation";
+    private static final String STATIC_SUB_RESOLUTION_PARAM = "jaxrs.static.subresources";
+    private static final String SERVICE_SCOPE_SINGLETON = "singleton";
+    private static final String SERVICE_SCOPE_REQUEST = "prototype";
+
+    private static final String PARAMETER_SPLIT_CHAR = "class.parameter.split.char";
+    private static final String DEFAULT_PARAMETER_SPLIT_CHAR = ",";
+    private static final String SPACE_PARAMETER_SPLIT_CHAR = "space";
+
+    private static final String JAXRS_APPLICATION_PARAM = "javax.ws.rs.Application";
+
+    private ClassLoader classLoader;
+    private Application application;
+
+    public CXFNonSpringJaxrsServlet() {
+
+    }
+
+    public CXFNonSpringJaxrsServlet(Application app) {
+        this.application = app;
+    }
+
+    public CXFNonSpringJaxrsServlet(Object singletonService) {
+        this(Collections.singleton(singletonService));
+    }
+    public CXFNonSpringJaxrsServlet(Set<Object> applicationSingletons) {
+        this(new ApplicationImpl(applicationSingletons));
+    }
+
+    public CXFNonSpringJaxrsServlet(Application app, DestinationRegistry destinationRegistry, Bus bus) {
+        super(destinationRegistry, bus);
+        this.application = app;
+    }
+
+    @Override
+    public void init(ServletConfig servletConfig) throws ServletException {
+        super.init(servletConfig);
+
+        if (getApplication() != null) {
+            createServerFromApplication(servletConfig);
+            return;
+        }
+
+        String applicationClass = servletConfig.getInitParameter(JAXRS_APPLICATION_PARAM);
+        if (applicationClass != null) {
+            createServerFromApplication(applicationClass, servletConfig);
+            return;
+        }
+
+        String splitChar = getParameterSplitChar(servletConfig);
+        JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean();
+        bean.setBus(getBus());
+
+        String address = servletConfig.getInitParameter(SERVICE_ADDRESS_PARAM);
+        if (address == null) {
+            address = "/";
+        }
+        bean.setAddress(address);
+
+        bean.setStaticSubresourceResolution(getStaticSubResolutionValue(servletConfig));
+
+        String modelRef = servletConfig.getInitParameter(USER_MODEL_PARAM);
+        if (modelRef != null) {
+            bean.setModelRef(modelRef.trim());
+        }
+        setDocLocation(bean, servletConfig);
+        setSchemasLocations(bean, servletConfig);
+        setAllInterceptors(bean, servletConfig, splitChar);
+        setInvoker(bean, servletConfig);
+
+        Map<Class<?>, Map<String, List<String>>> resourceClasses =
+            getServiceClasses(servletConfig, modelRef != null, splitChar);
+        Map<Class<?>, ResourceProvider> resourceProviders =
+            getResourceProviders(servletConfig, resourceClasses);
+
+        List<?> providers = getProviders(servletConfig, splitChar);
+
+        bean.setResourceClasses(new ArrayList<Class<?>>(resourceClasses.keySet()));
+        bean.setProviders(providers);
+        for (Map.Entry<Class<?>, ResourceProvider> entry : resourceProviders.entrySet()) {
+            bean.setResourceProvider(entry.getKey(), entry.getValue());
+        }
+        setExtensions(bean, servletConfig);
+
+        List<? extends Feature> features = getFeatures(servletConfig, splitChar);
+        bean.getFeatures().addAll(features);
+
+        bean.create();
+    }
+
+    protected String getParameterSplitChar(ServletConfig servletConfig) {
+        String param = servletConfig.getInitParameter(PARAMETER_SPLIT_CHAR);
+        if (!StringUtils.isEmpty(param) && SPACE_PARAMETER_SPLIT_CHAR.equals(param.trim())) {
+            return " ";
+        }
+        return DEFAULT_PARAMETER_SPLIT_CHAR;
+    }
+    protected boolean getStaticSubResolutionValue(ServletConfig servletConfig) {
+        String param = servletConfig.getInitParameter(STATIC_SUB_RESOLUTION_PARAM);
+        if (param != null) {
+            return Boolean.valueOf(param.trim());
+        }
+        return false;
+    }
+
+    protected void setExtensions(JAXRSServerFactoryBean bean, ServletConfig servletConfig) {
+        bean.setExtensionMappings(
+             CastUtils.cast((Map<?, ?>)parseMapSequence(servletConfig.getInitParameter(EXTENSIONS_PARAM))));
+        bean.setLanguageMappings(
+             CastUtils.cast((Map<?, ?>)parseMapSequence(servletConfig.getInitParameter(LANGUAGES_PARAM))));
+        Map<String, Object> properties = CastUtils.cast(
+                parseMapSequence(servletConfig.getInitParameter(PROPERTIES_PARAM)),
+                String.class, Object.class);
+        if (properties != null) {
+            bean.getProperties(true).putAll(properties);
+        }
+    }
+
+    protected void setAllInterceptors(JAXRSServerFactoryBean bean, ServletConfig servletConfig,
+                                      String splitChar)
+        throws ServletException {
+        setInterceptors(bean, servletConfig, OUT_INTERCEPTORS_PARAM, splitChar);
+        setInterceptors(bean, servletConfig, OUT_FAULT_INTERCEPTORS_PARAM, splitChar);
+        setInterceptors(bean, servletConfig, IN_INTERCEPTORS_PARAM, splitChar);
+    }
+
+    protected void setSchemasLocations(JAXRSServerFactoryBean bean, ServletConfig servletConfig) {
+        String schemas = servletConfig.getInitParameter(SCHEMAS_PARAM);
+        if (schemas == null) {
+            return;
+        }
+        String[] locations = schemas.split(" ");
+        List<String> list = new ArrayList<>();
+        for (String loc : locations) {
+            String theLoc = loc.trim();
+            if (!theLoc.isEmpty()) {
+                list.add(theLoc);
+            }
+        }
+        if (!list.isEmpty()) {
+            bean.setSchemaLocations(list);
+        }
+    }
+
+    protected void setDocLocation(JAXRSServerFactoryBean bean, ServletConfig servletConfig) {
+        String wadlLoc = servletConfig.getInitParameter(DOC_LOCATION_PARAM);
+        if (wadlLoc != null) {
+            bean.setDocLocation(wadlLoc);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    protected void setInterceptors(JAXRSServerFactoryBean bean, ServletConfig servletConfig,
+                                   String paramName,
+                                   String splitChar) throws ServletException {
+        String value = servletConfig.getInitParameter(paramName);
+        if (value == null) {
+            return;
+        }
+        String[] values = value.split(splitChar);
+        List<Interceptor<? extends Message>> list = new ArrayList<>();
+        for (String interceptorVal : values) {
+            Map<String, List<String>> props = new HashMap<>();
+            String theValue = getClassNameAndProperties(interceptorVal, props);
+            if (!theValue.isEmpty()) {
+                try {
+                    Class<?> intClass = loadClass(theValue, "Interceptor");
+                    Object object = intClass.newInstance();
+                    injectProperties(object, props);
+                    list.add((Interceptor<? extends Message>)object);
+                } catch (ServletException ex) {
+                    throw ex;
+                } catch (Exception ex) {
+                    LOG.warning("Interceptor class " + theValue + " can not be created");
+                    throw new ServletException(ex);
+                }
+            }
+        }
+        if (!list.isEmpty()) {
+            if (OUT_INTERCEPTORS_PARAM.equals(paramName)) {
+                bean.setOutInterceptors(list);
+            } else if (OUT_FAULT_INTERCEPTORS_PARAM.equals(paramName)) {
+                bean.setOutFaultInterceptors(list);
+            } else {
+                bean.setInInterceptors(list);
+            }
+        }
+    }
+
+    protected void setInvoker(JAXRSServerFactoryBean bean, ServletConfig servletConfig)
+        throws ServletException {
+        String value = servletConfig.getInitParameter(INVOKER_PARAM);
+        if (value == null) {
+            return;
+        }
+        Map<String, List<String>> props = new HashMap<>();
+        String theValue = getClassNameAndProperties(value, props);
+        if (!theValue.isEmpty()) {
+            try {
+                Class<?> intClass = loadClass(theValue, "Invoker");
+                Object object = intClass.newInstance();
+                injectProperties(object, props);
+                bean.setInvoker((Invoker)object);
+            } catch (ServletException ex) {
+                throw ex;
+            } catch (Exception ex) {
+                LOG.warning("Invoker class " + theValue + " can not be created");
+                throw new ServletException(ex);
+            }
+        }
+
+
+    }
+
+    protected Map<Class<?>, Map<String, List<String>>> getServiceClasses(ServletConfig servletConfig,
+                                            boolean modelAvailable,
+                                            String splitChar) throws ServletException {
+        String serviceBeans = servletConfig.getInitParameter(SERVICE_CLASSES_PARAM);
+        if (serviceBeans == null) {
+            if (modelAvailable) {
+                return Collections.emptyMap();
+            }
+            throw new ServletException("At least one resource class should be specified");
+        }
+        String[] classNames = serviceBeans.split(splitChar);
+        Map<Class<?>, Map<String, List<String>>> map = new HashMap<>();
+        for (String cName : classNames) {
+            Map<String, List<String>> props = new HashMap<>();
+            String theName = getClassNameAndProperties(cName, props);
+            if (!theName.isEmpty()) {
+                Class<?> cls = loadClass(theName);
+                map.put(cls, props);
+            }
+        }
+        if (map.isEmpty()) {
+            throw new ServletException("At least one resource class should be specified");
+        }
+        return map;
+    }
+
+    protected List<? extends Feature> getFeatures(ServletConfig servletConfig, String splitChar)
+        throws ServletException {
+
+        String featuresList = servletConfig.getInitParameter(FEATURES_PARAM);
+        if (featuresList == null) {
+            return Collections.< Feature >emptyList();
+        }
+        String[] classNames = featuresList.split(splitChar);
+        List< Feature > features = new ArrayList<>();
+        for (String cName : classNames) {
+            Map<String, List<String>> props = new HashMap<>();
+            String theName = getClassNameAndProperties(cName, props);
+            if (!theName.isEmpty()) {
+                Class<?> cls = loadClass(theName);
+                if (Feature.class.isAssignableFrom(cls)) {
+                    features.add((Feature)createSingletonInstance(cls, props, servletConfig));
+                }
+            }
+        }
+        return features;
+    }
+
+    protected List<?> getProviders(ServletConfig servletConfig, String splitChar) throws ServletException {
+        String providersList = servletConfig.getInitParameter(PROVIDERS_PARAM);
+        if (providersList == null) {
+            return Collections.emptyList();
+        }
+        String[] classNames = providersList.split(splitChar);
+        List<Object> providers = new ArrayList<>();
+        for (String cName : classNames) {
+            Map<String, List<String>> props = new HashMap<>();
+            String theName = getClassNameAndProperties(cName, props);
+            if (!theName.isEmpty()) {
+                Class<?> cls = loadClass(theName);
+                providers.add(createSingletonInstance(cls, props, servletConfig));
+            }
+        }
+        return providers;
+    }
+
+    private String getClassNameAndProperties(String cName, Map<String, List<String>> props) {
+        String theName = cName.trim();
+        int ind = theName.indexOf('(');
+        if (ind != -1 && theName.endsWith(")")) {
+            props.putAll(parseMapListSequence(theName.substring(ind + 1, theName.length() - 1)));
+            theName = theName.substring(0, ind).trim();
+        }
+        return theName;
+    }
+
+    protected static Map<String, List<String>> parseMapListSequence(String sequence) {
+        if (sequence != null) {
+            sequence = sequence.trim();
+            Map<String, List<String>> map = new HashMap<>();
+            String[] pairs = sequence.split(" ");
+            for (String pair : pairs) {
+                String thePair = pair.trim();
+                if (thePair.length() == 0) {
+                    continue;
+                }
+                String[] values = thePair.split("=");
+                String key;
+                String value;
+                if (values.length == 2) {
+                    key = values[0].trim();
+                    value = values[1].trim();
+                } else {
+                    key = thePair;
+                    value = "";
+                }
+                List<String> list = map.get(key);
+                if (list == null) {
+                    list = new LinkedList<>();
+                    map.put(key, list);
+                }
+                list.add(value);
+            }
+            return map;
+        }
+        return Collections.emptyMap();
+    }
+
+    protected Map<Class<?>, ResourceProvider> getResourceProviders(ServletConfig servletConfig,
+            Map<Class<?>, Map<String, List<String>>> resourceClasses) throws ServletException {
+        String scope = servletConfig.getInitParameter(SERVICE_SCOPE_PARAM);
+        if (scope != null && !SERVICE_SCOPE_SINGLETON.equals(scope)
+            && !SERVICE_SCOPE_REQUEST.equals(scope)) {
+            throw new ServletException("Only singleton and prototype scopes are supported");
+        }
+        boolean isPrototype = SERVICE_SCOPE_REQUEST.equals(scope);
+        Map<Class<?>, ResourceProvider> map = new HashMap<>();
+        for (Map.Entry<Class<?>, Map<String, List<String>>> entry : resourceClasses.entrySet()) {
+            Class<?> c = entry.getKey();
+            map.put(c, isPrototype ? new PerRequestResourceProvider(c)
+                                   : new SingletonResourceProvider(
+                                         createSingletonInstance(c, entry.getValue(), servletConfig),
+                                         true));
+        }
+        return map;
+    }
+
+    protected boolean isAppResourceLifecycleASingleton(Application app, ServletConfig servletConfig) {
+        String scope = servletConfig.getInitParameter(SERVICE_SCOPE_PARAM);
+        if (scope == null) {
+            scope = (String)app.getProperties().get(SERVICE_SCOPE_PARAM);
+        }
+        return SERVICE_SCOPE_SINGLETON.equals(scope);
+    }
+
+    protected Object createSingletonInstance(Class<?> cls, Map<String, List<String>> props, ServletConfig sc)
+        throws ServletException {
+        Constructor<?> c = ResourceUtils.findResourceConstructor(cls, false);
+        if (c == null) {
+            throw new ServletException("No valid constructor found for " + cls.getName());
+        }
+        boolean isApplication = Application.class.isAssignableFrom(c.getDeclaringClass());
+        try {
+            final ProviderInfo<? extends Object> provider;
+            if (c.getParameterTypes().length == 0) {
+                if (isApplication) {
+                    provider = new ApplicationInfo((Application)c.newInstance(), getBus());
+                } else {
+                    provider = new ProviderInfo<>(c.newInstance(), getBus(), false, true);
+                }
+            } else {
+                Map<Class<?>, Object> values = new HashMap<>();
+                values.put(ServletContext.class, sc.getServletContext());
+                values.put(ServletConfig.class, sc);
+                provider = ProviderFactory.createProviderFromConstructor(c, values, getBus(), isApplication, true);
+            }
+            Object instance = provider.getProvider();
+            injectProperties(instance, props);
+            configureSingleton(instance);
+            return isApplication ? provider : instance;
+        } catch (InstantiationException ex) {
+            ex.printStackTrace();
+            throw new ServletException("Resource class " + cls.getName()
+                                       + " can not be instantiated");
+        } catch (IllegalAccessException ex) {
+            ex.printStackTrace();
+            throw new ServletException("Resource class " + cls.getName()
+                                       + " can not be instantiated due to IllegalAccessException");
+        } catch (InvocationTargetException ex) {
+            ex.printStackTrace();
+            throw new ServletException("Resource class " + cls.getName()
+                                       + " can not be instantiated due to InvocationTargetException");
+        }
+    }
+
+    private void injectProperties(Object instance, Map<String, List<String>> props) {
+        if (props == null || props.isEmpty()) {
+            return;
+        }
+        Method[] methods = instance.getClass().getMethods();
+        Map<String, Method> methodsMap = new HashMap<>();
+        for (Method m : methods) {
+            methodsMap.put(m.getName(), m);
+        }
+        for (Map.Entry<String, List<String>> entry : props.entrySet()) {
+            Method m = methodsMap.get("set" + StringUtils.capitalize(entry.getKey()));
+            if (m != null) {
+                Class<?> type = m.getParameterTypes()[0];
+                Object value;
+                if (InjectionUtils.isPrimitive(type)) {
+                    value = PrimitiveUtils.read(entry.getValue().get(0), type);
+                } else {
+                    value = entry.getValue();
+                }
+                InjectionUtils.injectThroughMethod(instance, m, value);
+            }
+        }
+    }
+
+    protected void configureSingleton(Object instance) {
+
+    }
+
+    protected void createServerFromApplication(String applicationNames, ServletConfig servletConfig)
+        throws ServletException {
+
+        boolean ignoreApplicationPath = isIgnoreApplicationPath(servletConfig);
+
+        String[] classNames = applicationNames.split(getParameterSplitChar(servletConfig));
+
+        if (classNames.length > 1 && ignoreApplicationPath) {
+            throw new ServletException("\"" + IGNORE_APP_PATH_PARAM
+                + "\" parameter must be set to false for multiple Applications be supported");
+        }
+
+        for (String cName : classNames) {
+            ApplicationInfo providerApp = createApplicationInfo(cName, servletConfig);
+
+            Application app = providerApp.getProvider();
+            JAXRSServerFactoryBean bean = ResourceUtils.createApplication(
+                                                app,
+                                                ignoreApplicationPath,
+                                                getStaticSubResolutionValue(servletConfig),
+                                                isAppResourceLifecycleASingleton(app, servletConfig),
+                                                getBus());
+            String splitChar = getParameterSplitChar(servletConfig);
+            setAllInterceptors(bean, servletConfig, splitChar);
+            setInvoker(bean, servletConfig);
+            setExtensions(bean, servletConfig);
+            setDocLocation(bean, servletConfig);
+            setSchemasLocations(bean, servletConfig);
+
+            List<?> providers = getProviders(servletConfig, splitChar);
+            bean.setProviders(providers);
+            List<? extends Feature> features = getFeatures(servletConfig, splitChar);
+            bean.getFeatures().addAll(features);
+
+            bean.setBus(getBus());
+            bean.setApplicationInfo(providerApp);
+            bean.create();
+        }
+    }
+
+    protected boolean isIgnoreApplicationPath(ServletConfig servletConfig) {
+        String ignoreParam = servletConfig.getInitParameter(IGNORE_APP_PATH_PARAM);
+        return ignoreParam == null || PropertyUtils.isTrue(ignoreParam);
+    }
+
+    protected void createServerFromApplication(ServletConfig servletConfig)
+        throws ServletException {
+
+        Application app = getApplication();
+        JAXRSServerFactoryBean bean = ResourceUtils.createApplication(
+                                          app,
+                                          isIgnoreApplicationPath(servletConfig),
+                                          getStaticSubResolutionValue(servletConfig),
+                                          isAppResourceLifecycleASingleton(app, servletConfig),
+                                          getBus());
+        String splitChar = getParameterSplitChar(servletConfig);
+        setAllInterceptors(bean, servletConfig, splitChar);
+        setInvoker(bean, servletConfig);
+        setExtensions(bean, servletConfig);
+        setDocLocation(bean, servletConfig);
+        setSchemasLocations(bean, servletConfig);
+
+        List<?> providers = getProviders(servletConfig, splitChar);
+        bean.setProviders(providers);
+        List<? extends Feature> features = getFeatures(servletConfig, splitChar);
+        bean.getFeatures().addAll(features);
+
+        bean.setBus(getBus());
+        bean.setApplication(getApplication());
+        bean.create();
+    }
+
+    protected Application createApplicationInstance(String appClassName, ServletConfig servletConfig)
+        throws ServletException {
+        return null;
+    }
+    protected ApplicationInfo createApplicationInfo(String appClassName, ServletConfig servletConfig)
+        throws ServletException {
+
+        Application customApp = createApplicationInstance(appClassName, servletConfig);
+        if (customApp != null) {
+            return new ApplicationInfo(customApp, getBus());
+        }
+        Map<String, List<String>> props = new HashMap<>();
+        appClassName = getClassNameAndProperties(appClassName, props);
+        Class<?> appClass = loadApplicationClass(appClassName);
+        ApplicationInfo appInfo = (ApplicationInfo)createSingletonInstance(appClass, props, servletConfig);
+        Map<String, Object> servletProps = new HashMap<>();
+        ServletContext servletContext = servletConfig.getServletContext();
+        for (Enumeration<String> names = servletContext.getInitParameterNames(); names.hasMoreElements();) {
+            String name = names.nextElement();
+            servletProps.put(name, servletContext.getInitParameter(name));
+        }
+        for (Enumeration<String> names = servletConfig.getInitParameterNames(); names.hasMoreElements();) {
+            String name = names.nextElement();
+            servletProps.put(name, servletConfig.getInitParameter(name));
+        }
+        appInfo.setOverridingProps(servletProps);
+        return appInfo;
+    }
+
+    protected Class<?> loadApplicationClass(String appClassName) throws ServletException {
+        return loadClass(appClassName, "Application");
+    }
+
+    protected Class<?> loadClass(String cName) throws ServletException {
+        return loadClass(cName, "Resource");
+    }
+
+    protected Class<?> loadClass(String cName, String classType) throws ServletException {
+        try {
+            final Class<?> cls;
+            if (classLoader == null) {
+                cls = ClassLoaderUtils.loadClass(cName, CXFNonSpringJaxrsServlet.class);
+            } else {
+                cls = classLoader.loadClass(cName);
+            }
+            return cls;
+        } catch (ClassNotFoundException ex) {
+            throw new ServletException("No " + classType + " class " + cName.trim() + " can be found", ex);
+        }
+    }
+
+    public void setClassLoader(ClassLoader loader) {
+        this.classLoader = loader;
+    }
+
+    protected Application getApplication() {
+        return application;
+    }
+
+    private static class ApplicationImpl extends Application {
+        private Set<Object> applicationSingletons;
+        ApplicationImpl(Set<Object> applicationSingletons) {
+            this.applicationSingletons = applicationSingletons;
+        }
+        public Set<Object> getSingletons() {
+            return applicationSingletons;
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java b/transform/src/patch/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java
new file mode 100644
index 0000000..2115f6d
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java
@@ -0,0 +1,286 @@
+/**
+ * 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.cxf.jaxrs.spring;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.ext.Provider;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.bus.spring.BusWiringBeanFactoryPostProcessor;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ClasspathScanner;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean;
+import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.jaxrs.model.UserResource;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+
+
+public class JAXRSServerFactoryBeanDefinitionParser extends AbstractBeanDefinitionParser {
+    private static final Logger LOG = LogUtils.getL7dLogger(JAXRSServerFactoryBeanDefinitionParser.class);
+
+    public JAXRSServerFactoryBeanDefinitionParser() {
+        super();
+        setBeanClass(SpringJAXRSServerFactoryBean.class);
+    }
+
+    @Override
+    protected void mapAttribute(BeanDefinitionBuilder bean, Element e, String name, String val) {
+        if ("beanNames".equals(name)) {
+            String[] values = val.split(" ");
+            List<SpringResourceFactory> tempFactories = new ArrayList<>(values.length);
+            for (String v : values) {
+                String theValue = v.trim();
+                if (theValue.length() > 0) {
+                    tempFactories.add(new SpringResourceFactory(theValue));
+                }
+            }
+            bean.addPropertyValue("tempResourceProviders", tempFactories);
+        } else if ("serviceName".equals(name)) {
+            QName q = parseQName(e, val);
+            bean.addPropertyValue(name, q);
+        } else if ("basePackages".equals(name)) {
+            bean.addPropertyValue("basePackages", ClasspathScanner.parsePackages(val));
+        } else if ("serviceAnnotation".equals(name)) {
+            bean.addPropertyValue("serviceAnnotation", val);
+        } else if ("publish".equals(name)) {
+            mapToProperty(bean, "start", val);
+        } else {
+            mapToProperty(bean, name, val);
+        }
+    }
+
+    @Override
+    protected void mapElement(ParserContext ctx, BeanDefinitionBuilder bean, Element el, String name) {
+        if ("properties".equals(name)
+            || "extensionMappings".equals(name)
+            || "languageMappings".equals(name)) {
+            Map<?, ?> map = ctx.getDelegate().parseMapElement(el, bean.getBeanDefinition());
+            bean.addPropertyValue(name, map);
+        } else if ("executor".equals(name)) {
+            setFirstChildAsProperty(el, ctx, bean, "serviceFactory.executor");
+        } else if ("invoker".equals(name)) {
+            setFirstChildAsProperty(el, ctx, bean, "serviceFactory.invoker");
+        } else if ("binding".equals(name)) {
+            setFirstChildAsProperty(el, ctx, bean, "bindingConfig");
+        } else if ("inInterceptors".equals(name) || "inFaultInterceptors".equals(name)
+            || "outInterceptors".equals(name) || "outFaultInterceptors".equals(name)) {
+            List<?> list = ctx.getDelegate().parseListElement(el, bean.getBeanDefinition());
+            bean.addPropertyValue(name, list);
+        } else if ("features".equals(name) || "schemaLocations".equals(name)
+            || "providers".equals(name) || "serviceBeans".equals(name)
+            || "modelBeans".equals(name)) {
+            List<?> list = ctx.getDelegate().parseListElement(el, bean.getBeanDefinition());
+            bean.addPropertyValue(name, list);
+        }  else if ("serviceFactories".equals(name)) {
+            List<?> list = ctx.getDelegate().parseListElement(el, bean.getBeanDefinition());
+            bean.addPropertyValue("resourceProviders", list);
+        } else if ("model".equals(name)) {
+            List<UserResource> resources = ResourceUtils.getResourcesFromElement(el);
+            bean.addPropertyValue("modelBeans", resources);
+        } else {
+            setFirstChildAsProperty(el, ctx, bean, name);
+        }
+    }
+
+
+    @Override
+    protected void doParse(Element element, ParserContext ctx, BeanDefinitionBuilder bean) {
+        super.doParse(element, ctx, bean);
+
+        bean.setInitMethodName("create");
+        bean.setDestroyMethodName("destroy");
+
+        // We don't really want to delay the registration of our Server
+        bean.setLazyInit(false);
+    }
+
+    @Override
+    protected String resolveId(Element elem,
+                               AbstractBeanDefinition definition,
+                               ParserContext ctx)
+        throws BeanDefinitionStoreException {
+        String id = super.resolveId(elem, definition, ctx);
+        if (StringUtils.isEmpty(id)) {
+            id = getBeanClass().getName() + "--" + definition.hashCode();
+        }
+
+        return id;
+    }
+
+    @Override
+    protected boolean hasBusProperty() {
+        return true;
+    }
+
+    public static class SpringJAXRSServerFactoryBean extends JAXRSServerFactoryBean implements
+        ApplicationContextAware {
+
+        private List<SpringResourceFactory> tempFactories;
+        private List<String> basePackages;
+        private String serviceAnnotation;
+        private ApplicationContext context;
+        private boolean serviceBeansAvailable;
+        private boolean providerBeansAvailable;
+        private boolean resourceProvidersAvailable;
+
+        public SpringJAXRSServerFactoryBean() {
+            super();
+        }
+
+        public SpringJAXRSServerFactoryBean(JAXRSServiceFactoryBean sf) {
+            super(sf);
+        }
+
+        public void destroy() {
+            Server server = super.getServer();
+            if (server != null && server.isStarted()) {
+                server.destroy();
+            }
+        }
+        @Override
+        public void setServiceBeans(List<Object> beans) {
+            super.setServiceBeans(beans);
+            this.serviceBeansAvailable = true;
+        }
+        @Override
+        public void setProviders(List<? extends Object> beans) {
+            super.setProviders(beans);
+            this.providerBeansAvailable = true;
+        }
+        public void setResourceProviders(List<ResourceProvider> rps) {
+            super.setResourceProviders(rps);
+            this.resourceProvidersAvailable = true;
+        }
+        public void setBasePackages(List<String> basePackages) {
+            this.basePackages = basePackages;
+        }
+
+        public void setServiceAnnotation(String serviceAnnotation) {
+            this.serviceAnnotation = serviceAnnotation;
+        }
+
+        public void setTempResourceProviders(List<SpringResourceFactory> providers) {
+            tempFactories = providers;
+        }
+
+        public void setApplicationContext(ApplicationContext ctx) throws BeansException {
+            this.context = ctx;
+
+            if (tempFactories != null) {
+                List<ResourceProvider> factories = new ArrayList<>(
+                    tempFactories.size());
+                for (int i = 0; i < tempFactories.size(); i++) {
+                    SpringResourceFactory factory = tempFactories.get(i);
+                    factory.setApplicationContext(ctx);
+                    factories.add(factory);
+                }
+                tempFactories.clear();
+                setResourceProviders(factories);
+            }
+            Class<? extends Annotation> serviceAnnotationClass = loadServiceAnnotationClass();
+            if (basePackages != null) {
+                try {
+                    final Map< Class< ? extends Annotation >, Collection< Class< ? > > > classes =
+                        ClasspathScanner.findClasses(basePackages, Provider.class, Path.class);
+
+                    this.setServiceBeans(createBeansFromDiscoveredClasses(context,
+                                                                          classes.get(Path.class),
+                                                                          serviceAnnotationClass));
+                    this.setProviders(createBeansFromDiscoveredClasses(context,
+                                                                       classes.get(Provider.class),
+                                                                       serviceAnnotationClass));
+                } catch (IOException ex) {
+                    throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
+                } catch (ClassNotFoundException ex) {
+                    throw new BeanCreationException("Failed to create bean from classfile", ex);
+                }
+            } else if (serviceAnnotationClass != null
+                && !serviceBeansAvailable && !providerBeansAvailable && !resourceProvidersAvailable) {
+                discoverContextResources(serviceAnnotationClass);
+            }
+            if (bus == null) {
+                setBus(BusWiringBeanFactoryPostProcessor.addDefaultBus(ctx));
+            }
+        }
+        private void discoverContextResources(Class<? extends Annotation> serviceAnnotationClass) {
+            AbstractSpringComponentScanServer scanServer =
+                new AbstractSpringComponentScanServer(serviceAnnotationClass) { };
+            scanServer.setApplicationContext(context);
+            scanServer.setJaxrsResources(this);
+        }
+        @SuppressWarnings("unchecked")
+        private Class<? extends Annotation> loadServiceAnnotationClass() {
+            if (serviceAnnotation != null) {
+                try {
+                    return (Class<? extends Annotation>)ClassLoaderUtils.loadClass(serviceAnnotation, this.getClass());
+                } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+            return null;
+        }
+    }
+    static List<Object> createBeansFromDiscoveredClasses(ApplicationContext context,
+                                                         Collection<Class<?>> classes,
+                                                         Class<? extends Annotation> serviceClassAnnotation) {
+        AutowireCapableBeanFactory beanFactory = context.getAutowireCapableBeanFactory();
+        final List< Object > providers = new ArrayList<>();
+        for (final Class< ? > clazz: classes) {
+            if (serviceClassAnnotation != null && clazz.getAnnotation(serviceClassAnnotation) == null) {
+                continue;
+            }
+            Object bean;
+            try {
+                bean = beanFactory.createBean(clazz, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+            } catch (Exception ex) {
+                String stackTrace = ExceptionUtils.getStackTrace(ex);
+                LOG.fine("Autowire failure for a " + clazz.getName() + " bean: " + stackTrace);
+                bean = beanFactory.createBean(clazz);
+            }
+            providers.add(bean);
+        }
+        return providers;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/utils/HttpUtils.java b/transform/src/patch/java/org/apache/cxf/jaxrs/utils/HttpUtils.java
new file mode 100644
index 0000000..aa42382
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/utils/HttpUtils.java
@@ -0,0 +1,704 @@
+/**
+ * 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.cxf.jaxrs.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.ext.RuntimeDelegate;
+import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
+
+import org.apache.cxf.common.i18n.BundleUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.common.util.UrlUtils;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.jaxrs.impl.HttpHeadersImpl;
+import org.apache.cxf.jaxrs.impl.HttpServletRequestFilter;
+import org.apache.cxf.jaxrs.impl.HttpServletResponseFilter;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.impl.PathSegmentImpl;
+import org.apache.cxf.jaxrs.impl.RuntimeDelegateImpl;
+import org.apache.cxf.jaxrs.model.ParameterType;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.transport.http.AbstractHTTPDestination;
+import org.apache.cxf.transport.http.Headers;
+import org.apache.cxf.transport.servlet.BaseUrlHelper;
+
+public final class HttpUtils {
+
+    private static final ResourceBundle BUNDLE = BundleUtils.getBundle(HttpUtils.class);
+    private static final Logger LOG = LogUtils.getL7dLogger(HttpUtils.class);
+
+    private static final String REQUEST_PATH_TO_MATCH = "path_to_match";
+    private static final String REQUEST_PATH_TO_MATCH_SLASH = "path_to_match_slash";
+
+    private static final String HTTP_SCHEME = "http";
+    private static final String LOCAL_HOST_IP_ADDRESS = "127.0.0.1";
+    private static final String REPLACE_LOOPBACK_PROPERTY = "replace.loopback.address.with.localhost";
+    private static final String LOCAL_HOST_IP_ADDRESS_SCHEME = "://" + LOCAL_HOST_IP_ADDRESS;
+    private static final String ANY_IP_ADDRESS = "0.0.0.0";
+    private static final String ANY_IP_ADDRESS_SCHEME = "://" + ANY_IP_ADDRESS;
+    private static final int DEFAULT_HTTP_PORT = 80;
+
+    private static final Pattern ENCODE_PATTERN = Pattern.compile("%[0-9a-fA-F][0-9a-fA-F]");
+    private static final String CHARSET_PARAMETER = "charset";
+    private static final String DOUBLE_QUOTE = "\"";
+
+    // there are more of such characters, ex, '*' but '*' is not affected by UrlEncode
+    private static final String PATH_RESERVED_CHARACTERS = "=@/:!$&\'(),;~";
+    private static final String QUERY_RESERVED_CHARACTERS = "?/,";
+    
+    private static final Set<String> KNOWN_HTTP_VERBS_WITH_NO_REQUEST_CONTENT =
+        new HashSet<>(Arrays.asList(new String[]{"GET", "HEAD", "OPTIONS", "TRACE"}));
+    private static final Set<String> KNOWN_HTTP_VERBS_WITH_NO_RESPONSE_CONTENT =
+        new HashSet<>(Arrays.asList(new String[]{"HEAD", "OPTIONS"}));
+
+    private HttpUtils() {
+    }
+
+    public static String urlDecode(String value, String enc) {
+        return UrlUtils.urlDecode(value, enc);
+    }
+
+    public static String urlDecode(String value) {
+        return UrlUtils.urlDecode(value);
+    }
+
+    public static String pathDecode(String value) {
+        return UrlUtils.pathDecode(value);
+    }
+
+    private static String componentEncode(String reservedChars, String value) {
+
+        StringBuilder buffer = null;
+        int length = value.length();
+        int startingIndex = 0;
+        for (int i = 0; i < length; i++) {
+            char currentChar = value.charAt(i);
+            if (reservedChars.indexOf(currentChar) != -1) {
+                if (buffer == null) {
+                    buffer = new StringBuilder(length + 8);
+                }
+                // If it is going to be an empty string nothing to encode.
+                if (i != startingIndex) {
+                    buffer.append(urlEncode(value.substring(startingIndex, i)));
+                }
+                buffer.append(currentChar);
+                startingIndex = i + 1;
+            }
+        }
+
+        if (buffer == null) {
+            return urlEncode(value);
+        }
+        if (startingIndex < length) {
+            buffer.append(urlEncode(value.substring(startingIndex, length)));
+        }
+
+        return buffer.toString();
+    }
+
+    public static String queryEncode(String value) {
+
+        return componentEncode(QUERY_RESERVED_CHARACTERS, value);
+    }
+
+    public static String urlEncode(String value) {
+
+        return urlEncode(value, StandardCharsets.UTF_8.name());
+    }
+
+    public static String urlEncode(String value, String enc) {
+
+        return UrlUtils.urlEncode(value, enc);
+    }
+
+    public static String pathEncode(String value) {
+
+        String result = componentEncode(PATH_RESERVED_CHARACTERS, value);
+        // URLEncoder will encode '+' to %2B but will turn ' ' into '+'
+        // We need to retain '+' and encode ' ' as %20
+        if (result.indexOf('+') != -1) {
+            result = result.replace("+", "%20");
+        }
+        if (result.indexOf("%2B") != -1) {
+            result = result.replace("%2B", "+");
+        }
+
+        return result;
+    }
+
+    public static boolean isPartiallyEncoded(String value) {
+        return ENCODE_PATTERN.matcher(value).find();
+    }
+
+    /**
+     * Encodes partially encoded string. Encode all values but those matching pattern
+     * "percent char followed by two hexadecimal digits".
+     *
+     * @param encoded fully or partially encoded string.
+     * @return fully encoded string
+     */
+    public static String encodePartiallyEncoded(String encoded, boolean query) {
+        if (encoded.length() == 0) {
+            return encoded;
+        }
+        Matcher m = ENCODE_PATTERN.matcher(encoded);
+
+        if (!m.find()) {
+            return query ? HttpUtils.queryEncode(encoded) : HttpUtils.pathEncode(encoded);
+        }
+
+        int length = encoded.length();
+        StringBuilder sb = new StringBuilder(length + 8);
+        int i = 0;
+        do {
+            String before = encoded.substring(i, m.start());
+            sb.append(query ? HttpUtils.queryEncode(before) : HttpUtils.pathEncode(before));
+            sb.append(m.group());
+            i = m.end();
+        } while (m.find());
+        String tail = encoded.substring(i, length);
+        sb.append(query ? HttpUtils.queryEncode(tail) : HttpUtils.pathEncode(tail));
+        return sb.toString();
+    }
+
+    public static SimpleDateFormat getHttpDateFormat() {
+        return Headers.getHttpDateFormat();
+    }
+
+    public static String toHttpDate(Date date) {
+        return Headers.toHttpDate(date);
+    }
+
+    public static RuntimeDelegate getOtherRuntimeDelegate() {
+        try {
+            RuntimeDelegate rd = RuntimeDelegate.getInstance();
+            return rd instanceof RuntimeDelegateImpl ? null : rd;
+        } catch (Throwable t) {
+            return null;
+        }
+    }
+
+    public static HeaderDelegate<Object> getHeaderDelegate(Object o) {
+        return getHeaderDelegate(RuntimeDelegate.getInstance(), o);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static HeaderDelegate<Object> getHeaderDelegate(RuntimeDelegate rd, Object o) {
+        return rd == null ? null : (HeaderDelegate<Object>)rd.createHeaderDelegate(o.getClass());
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> MultivaluedMap<String, T> getModifiableStringHeaders(Message m) {
+        MultivaluedMap<String, Object> headers = getModifiableHeaders(m);
+        convertHeaderValuesToString(headers, false);
+        return (MultivaluedMap<String, T>)headers;
+    }
+
+    public static MultivaluedMap<String, Object> getModifiableHeaders(Message m) {
+        Map<String, List<Object>> headers = CastUtils.cast((Map<?, ?>)m.get(Message.PROTOCOL_HEADERS));
+        return new MetadataMap<String, Object>(headers, false, false, true);
+    }
+
+    public static void convertHeaderValuesToString(Map<String, List<Object>> headers, boolean delegateOnly) {
+        if (headers == null) {
+            return;
+        }
+        RuntimeDelegate rd = getOtherRuntimeDelegate();
+        if (rd == null && delegateOnly) {
+            return;
+        }
+        for (Map.Entry<String, List<Object>> entry : headers.entrySet()) {
+            List<Object> values = entry.getValue();
+            for (int i = 0; i < values.size(); i++) {
+                Object value = values.get(i);
+
+                if (value != null && !(value instanceof String)) {
+
+                    HeaderDelegate<Object> hd = getHeaderDelegate(rd, value);
+
+                    if (hd != null) {
+                        value = hd.toString(value);
+                    } else if (!delegateOnly) {
+                        value = value.toString();
+                    }
+
+                    try {
+                        values.set(i, value);
+                    } catch (UnsupportedOperationException ex) {
+                        // this may happen if an unmodifiable List was set via Map put
+                        List<Object> newList = new ArrayList<>(values);
+                        newList.set(i, value);
+                        // Won't help if the map is unmodifiable in which case it is a bug anyway
+                        headers.put(entry.getKey(), newList);
+                    }
+
+                }
+
+            }
+        }
+
+    }
+
+    public static Date getHttpDate(String value) {
+        if (value == null) {
+            return null;
+        }
+        try {
+            return Headers.getHttpDateFormat().parse(value);
+        } catch (ParseException ex) {
+            return null;
+        }
+    }
+
+    public static Locale getLocale(String value) {
+        if (value == null) {
+            return null;
+        }
+        final String language;
+        String locale = null;
+        int index = value.indexOf('-');
+        if (index == 0 || index == value.length() - 1) {
+            throw new IllegalArgumentException("Illegal locale value : " + value);
+        }
+
+        if (index > 0) {
+            language = value.substring(0, index);
+            locale = value.substring(index + 1);
+        } else {
+            language = value;
+        }
+
+        if (locale == null) {
+            return new Locale(language);
+        }
+        return new Locale(language, locale);
+
+    }
+
+    public static int getContentLength(String value) {
+        if (value == null) {
+            return -1;
+        }
+        try {
+            int len = Integer.parseInt(value);
+            return len >= 0 ? len : -1;
+        } catch (Exception ex) {
+            return -1;
+        }
+    }
+
+    public static String getHeaderString(List<String> values) {
+        if (values == null) {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < values.size(); i++) {
+            String value = values.get(i);
+            if (StringUtils.isEmpty(value)) {
+                continue;
+            }
+            sb.append(value);
+            if (i + 1 < values.size()) {
+                sb.append(',');
+            }
+        }
+        return sb.toString();
+    }
+
+    public static boolean isDateRelatedHeader(String headerName) {
+        return HttpHeaders.DATE.equalsIgnoreCase(headerName)
+               || HttpHeaders.IF_MODIFIED_SINCE.equalsIgnoreCase(headerName)
+               || HttpHeaders.IF_UNMODIFIED_SINCE.equalsIgnoreCase(headerName)
+               || HttpHeaders.EXPIRES.equalsIgnoreCase(headerName)
+               || HttpHeaders.LAST_MODIFIED.equalsIgnoreCase(headerName);
+    }
+
+    public static boolean isHttpRequest(Message message) {
+        return message.get(AbstractHTTPDestination.HTTP_REQUEST) != null;
+    }
+
+    public static URI toAbsoluteUri(String relativePath, Message message) {
+        String base = BaseUrlHelper.getBaseURL(
+            (HttpServletRequest)message.get(AbstractHTTPDestination.HTTP_REQUEST));
+        return URI.create(base + relativePath);
+    }
+
+    public static URI toAbsoluteUri(URI u, Message message) {
+        HttpServletRequest request =
+            (HttpServletRequest)message.get(AbstractHTTPDestination.HTTP_REQUEST);
+        boolean absolute = u.isAbsolute();
+        StringBuilder uriBuf = new StringBuilder();
+        if (request != null && (!absolute || isLocalHostOrAnyIpAddress(u, uriBuf, message))) {
+            String serverAndPort = request.getServerName();
+            boolean localAddressUsed = false;
+            if (absolute) {
+                if (ANY_IP_ADDRESS.equals(serverAndPort)) {
+                    serverAndPort = request.getLocalAddr();
+                    localAddressUsed = true;
+                }
+                if (LOCAL_HOST_IP_ADDRESS.equals(serverAndPort)) {
+                    serverAndPort = "localhost";
+                    localAddressUsed = true;
+                }
+            }
+
+
+            int port = localAddressUsed ? request.getLocalPort() : request.getServerPort();
+            if (port != DEFAULT_HTTP_PORT) {
+                serverAndPort += ":" + port;
+            }
+            String base = request.getScheme() + "://" + serverAndPort;
+            if (!absolute) {
+                u = URI.create(base + u.toString());
+            } else {
+                int originalPort = u.getPort();
+                String hostValue = uriBuf.toString().contains(ANY_IP_ADDRESS_SCHEME)
+                    ? ANY_IP_ADDRESS : LOCAL_HOST_IP_ADDRESS;
+                String replaceValue = originalPort == -1 ? hostValue : hostValue + ":" + originalPort;
+                u = URI.create(u.toString().replace(replaceValue, serverAndPort));
+            }
+        }
+        return u;
+    }
+
+    private static boolean isLocalHostOrAnyIpAddress(URI u, StringBuilder uriStringBuffer, Message m) {
+        String uriString = u.toString();
+        boolean result = uriString.contains(LOCAL_HOST_IP_ADDRESS_SCHEME) && replaceLoopBackAddress(m)
+            || uriString.contains(ANY_IP_ADDRESS_SCHEME);
+        uriStringBuffer.append(uriString);
+        return result;
+    }
+
+    private static boolean replaceLoopBackAddress(Message m) {
+        Object prop = m.getContextualProperty(REPLACE_LOOPBACK_PROPERTY);
+        return prop == null || PropertyUtils.isTrue(prop);
+    }
+
+    public static void resetRequestURI(Message m, String requestURI) {
+        m.remove(REQUEST_PATH_TO_MATCH_SLASH);
+        m.remove(REQUEST_PATH_TO_MATCH);
+        m.put(Message.REQUEST_URI, requestURI);
+    }
+
+
+    public static String getPathToMatch(Message m, boolean addSlash) {
+        String var = addSlash ? REQUEST_PATH_TO_MATCH_SLASH : REQUEST_PATH_TO_MATCH;
+        String pathToMatch = (String)m.get(var);
+        if (pathToMatch != null) {
+            return pathToMatch;
+        }
+        String requestAddress = getProtocolHeader(m, Message.REQUEST_URI, "/");
+        if (m.get(Message.QUERY_STRING) == null) {
+            int index = requestAddress.lastIndexOf('?');
+            if (index > 0 && index < requestAddress.length()) {
+                m.put(Message.QUERY_STRING, requestAddress.substring(index + 1));
+                requestAddress = requestAddress.substring(0, index);
+            }
+        }
+        String baseAddress = getBaseAddress(m);
+        pathToMatch = getPathToMatch(requestAddress, baseAddress, addSlash);
+        m.put(var, pathToMatch);
+        return pathToMatch;
+    }
+
+    public static String getProtocolHeader(Message m, String name, String defaultValue) {
+        return getProtocolHeader(m, name, defaultValue, false);
+    }
+
+    public static String getProtocolHeader(Message m, String name, String defaultValue, boolean setOnMessage) {
+        String value = (String)m.get(name);
+        if (value == null) {
+            value = new HttpHeadersImpl(m).getRequestHeaders().getFirst(name);
+            if (value != null && setOnMessage) {
+                m.put(name, value);
+            }
+        }
+        return value == null ? defaultValue : value;
+    }
+
+    public static String getBaseAddress(Message m) {
+        String endpointAddress = getEndpointAddress(m);
+        try {
+            URI uri = new URI(endpointAddress);
+            String path = uri.getRawPath();
+            String scheme = uri.getScheme();
+            if (scheme != null && !scheme.startsWith(HttpUtils.HTTP_SCHEME)
+                && HttpUtils.isHttpRequest(m)) {
+                path = HttpUtils.toAbsoluteUri(path, m).getRawPath();
+            }
+            return (path == null || path.length() == 0) ? "/" : path;
+        } catch (URISyntaxException ex) {
+            return endpointAddress;
+        }
+    }
+
+    public static String getEndpointAddress(Message m) {
+        String address;
+        Destination d = m.getExchange().getDestination();
+        if (d != null) {
+            if (d instanceof AbstractHTTPDestination) {
+                EndpointInfo ei = ((AbstractHTTPDestination)d).getEndpointInfo();
+                HttpServletRequest request = (HttpServletRequest)m.get(AbstractHTTPDestination.HTTP_REQUEST);
+                Object property = request != null
+                    ? request.getAttribute("org.apache.cxf.transport.endpoint.address") : null;
+                address = property != null ? property.toString() : ei.getAddress();
+            } else {
+                address = m.containsKey(Message.BASE_PATH)
+                    ? (String)m.get(Message.BASE_PATH) : d.getAddress().getAddress().getValue();
+            }
+        } else {
+            address = (String)m.get(Message.ENDPOINT_ADDRESS);
+        }
+        if (address.startsWith("http") && address.endsWith("//")) {
+            address = address.substring(0, address.length() - 1);
+        }
+        return address;
+    }
+
+    public static void updatePath(Message m, String path) {
+        String baseAddress = getBaseAddress(m);
+        boolean pathSlash = path.startsWith("/");
+        boolean baseSlash = baseAddress.endsWith("/");
+        if (pathSlash && baseSlash) {
+            path = path.substring(1);
+        } else if (!pathSlash && !baseSlash) {
+            path = "/" + path;
+        }
+        m.put(Message.REQUEST_URI, baseAddress + path);
+        m.remove(REQUEST_PATH_TO_MATCH);
+        m.remove(REQUEST_PATH_TO_MATCH_SLASH);
+    }
+
+
+    public static String getPathToMatch(String path, String address, boolean addSlash) {
+
+        int ind = path.indexOf(address);
+        if (ind == -1 && address.equals(path + "/")) {
+            path += "/";
+            ind = 0;
+        }
+        if (ind == 0) {
+            path = path.substring(address.length());
+        }
+        if (addSlash && !path.startsWith("/")) {
+            path = "/" + path;
+        }
+
+        return path;
+    }
+
+    public static String getOriginalAddress(Message m) {
+        Destination d = m.getDestination();
+        return d == null ? "/" : d.getAddress().getAddress().getValue();
+    }
+
+    public static String fromPathSegment(PathSegment ps) {
+        if (PathSegmentImpl.class.isAssignableFrom(ps.getClass())) {
+            return ((PathSegmentImpl)ps).getOriginalPath();
+        }
+        StringBuilder sb = new StringBuilder();
+        sb.append(ps.getPath());
+        for (Map.Entry<String, List<String>> entry : ps.getMatrixParameters().entrySet()) {
+            for (String value : entry.getValue()) {
+                sb.append(';').append(entry.getKey());
+                if (value != null) {
+                    sb.append('=').append(value);
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    public static Response.Status getParameterFailureStatus(ParameterType pType) {
+        if (pType == ParameterType.MATRIX || pType == ParameterType.PATH
+            || pType == ParameterType.QUERY) {
+            return Response.Status.NOT_FOUND;
+        }
+        return Response.Status.BAD_REQUEST;
+    }
+
+    public static String getSetEncoding(MediaType mt, MultivaluedMap<String, Object> headers,
+                                        String defaultEncoding) {
+        String enc = getMediaTypeCharsetParameter(mt);
+        if (enc == null) {
+            return defaultEncoding;
+        }
+        try {
+            "0".getBytes(enc);
+            return enc;
+        } catch (UnsupportedEncodingException ex) {
+            String message = new org.apache.cxf.common.i18n.Message("UNSUPPORTED_ENCODING",
+                                 BUNDLE, enc, defaultEncoding).toString();
+            LOG.warning(message);
+            headers.putSingle(HttpHeaders.CONTENT_TYPE,
+                JAXRSUtils.mediaTypeToString(mt, CHARSET_PARAMETER)
+                + ';' + CHARSET_PARAMETER + "="
+                + (defaultEncoding == null ? StandardCharsets.UTF_8 : defaultEncoding));
+        }
+        return defaultEncoding;
+    }
+
+    public static String getEncoding(MediaType mt, String defaultEncoding) {
+        String charset = mt == null ? defaultEncoding : getMediaTypeCharsetParameter(mt);
+        return charset == null ? defaultEncoding : charset;
+    }
+
+    public static String getMediaTypeCharsetParameter(MediaType mt) {
+        String charset = mt.getParameters().get(CHARSET_PARAMETER);
+        if (charset != null && charset.startsWith(DOUBLE_QUOTE) 
+            && charset.endsWith(DOUBLE_QUOTE) && charset.length() > 1) {
+            charset = charset.substring(1,  charset.length() - 1);
+        }
+        return charset;
+    }
+
+    public static URI resolve(UriBuilder baseBuilder, URI uri) {
+        if (!uri.isAbsolute()) {
+            return baseBuilder.build().resolve(uri);
+        }
+        return uri;
+    }
+
+    public static URI relativize(URI base, URI uri) {
+        // quick bail-out
+        if (!(base.isAbsolute()) || !(uri.isAbsolute())) {
+            return uri;
+        }
+        if (base.isOpaque() || uri.isOpaque()) {
+            // Unlikely case of an URN which can't deal with
+            // relative path, such as urn:isbn:0451450523
+            return uri;
+        }
+        // Check for common root
+        URI root = base.resolve("/");
+        if (!(root.equals(uri.resolve("/")))) {
+            // Different protocol/auth/host/port, return as is
+            return uri;
+        }
+
+        // Ignore hostname bits for the following , but add "/" in the beginning
+        // so that in worst case we'll still return "/fred" rather than
+        // "http://example.com/fred".
+        URI baseRel = URI.create("/").resolve(root.relativize(base));
+        URI uriRel = URI.create("/").resolve(root.relativize(uri));
+
+        // Is it same path?
+        if (baseRel.getPath().equals(uriRel.getPath())) {
+            return baseRel.relativize(uriRel);
+        }
+
+        // Direct siblings? (ie. in same folder)
+        URI commonBase = baseRel.resolve("./");
+        if (commonBase.equals(uriRel.resolve("./"))) {
+            return commonBase.relativize(uriRel);
+        }
+
+        // No, then just keep climbing up until we find a common base.
+        URI relative = URI.create("");
+        while (!(uriRel.getPath().startsWith(commonBase.getPath())) && !"/".equals(commonBase.getPath())) {
+            commonBase = commonBase.resolve("../");
+            relative = relative.resolve("../");
+        }
+
+        // Now we can use URI.relativize
+        URI relToCommon = commonBase.relativize(uriRel);
+        // and prepend the needed ../
+        return relative.resolve(relToCommon);
+
+    }
+
+    public static String toHttpLanguage(Locale locale) {
+        return Headers.toHttpLanguage(locale);
+    }
+
+    public static boolean isPayloadEmpty(MultivaluedMap<String, String> headers) {
+        if (headers != null) {
+            String value = headers.getFirst(HttpHeaders.CONTENT_LENGTH);
+            if (value != null) {
+                try {
+                    Long len = Long.valueOf(value);
+                    return len <= 0;
+                } catch (NumberFormatException ex) {
+                    // ignore
+                }
+            }
+        }
+
+        return false;
+    }
+    
+    public static <T> T createServletResourceValue(Message m, Class<T> clazz) {
+
+        Object value = null;
+        if (clazz == HttpServletRequest.class) {
+            HttpServletRequest request = (HttpServletRequest)m.get(AbstractHTTPDestination.HTTP_REQUEST);
+            value = request != null ? new HttpServletRequestFilter(request, m) : null;
+        } else if (clazz == HttpServletResponse.class) {
+            HttpServletResponse response = (HttpServletResponse)m.get(AbstractHTTPDestination.HTTP_RESPONSE);
+            value = response != null ? new HttpServletResponseFilter(response, m) : null;
+        } else if (clazz == ServletContext.class) {
+            value = m.get(AbstractHTTPDestination.HTTP_CONTEXT);
+        } else if (clazz == ServletConfig.class) {
+            value = m.get(AbstractHTTPDestination.HTTP_CONFIG);
+        }
+
+        return clazz.cast(value);
+    }
+
+    public static boolean isMethodWithNoRequestContent(String method) {
+        return KNOWN_HTTP_VERBS_WITH_NO_REQUEST_CONTENT.contains(method);
+    }
+    
+    public static boolean isMethodWithNoResponseContent(String method) {
+        return KNOWN_HTTP_VERBS_WITH_NO_RESPONSE_CONTENT.contains(method);
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java b/transform/src/patch/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
new file mode 100644
index 0000000..fb53bd6
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
@@ -0,0 +1,1044 @@
+/**
+ * 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.cxf.jaxrs.utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.BeanParam;
+import javax.ws.rs.CookieParam;
+import javax.ws.rs.Encoded;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.MatrixParam;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.Suspended;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.i18n.BundleUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.feature.Feature;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.ext.DefaultMethod;
+import org.apache.cxf.jaxrs.ext.xml.ElementClass;
+import org.apache.cxf.jaxrs.ext.xml.XMLName;
+import org.apache.cxf.jaxrs.lifecycle.PerRequestResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.MethodDispatcher;
+import org.apache.cxf.jaxrs.model.OperationResourceInfo;
+import org.apache.cxf.jaxrs.model.Parameter;
+import org.apache.cxf.jaxrs.model.ParameterType;
+import org.apache.cxf.jaxrs.model.ResourceTypes;
+import org.apache.cxf.jaxrs.model.URITemplate;
+import org.apache.cxf.jaxrs.model.UserOperation;
+import org.apache.cxf.jaxrs.model.UserResource;
+import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.resource.ResourceManager;
+import org.apache.cxf.staxutils.StaxUtils;
+
+public final class ResourceUtils {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(ResourceUtils.class);
+    private static final ResourceBundle BUNDLE = BundleUtils.getBundle(ResourceUtils.class);
+    private static final String CLASSPATH_PREFIX = "classpath:";
+    private static final String NOT_RESOURCE_METHOD_MESSAGE_ID = "NOT_RESOURCE_METHOD";
+    private static final String NOT_SUSPENDED_ASYNC_MESSAGE_ID = "NOT_SUSPENDED_ASYNC_METHOD";
+    private static final String NO_VOID_RETURN_ASYNC_MESSAGE_ID = "NO_VOID_RETURN_ASYNC_METHOD";
+    private static final Set<String> SERVER_PROVIDER_CLASS_NAMES;
+    static {
+        SERVER_PROVIDER_CLASS_NAMES = new HashSet<>();
+        SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.ext.MessageBodyWriter");
+        SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.ext.MessageBodyReader");
+        SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.ext.ExceptionMapper");
+        SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.ext.ContextResolver");
+        SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.ext.ReaderInterceptor");
+        SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.ext.WriterInterceptor");
+        SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.ext.ParamConverterProvider");
+        SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.container.ContainerRequestFilter");
+        SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.container.ContainerResponseFilter");
+        SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.container.DynamicFeature");
+        SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.core.Feature");
+        SERVER_PROVIDER_CLASS_NAMES.add("org.apache.cxf.jaxrs.ext.ContextProvider");
+
+    }
+
+    private ResourceUtils() {
+    }
+
+    private static Method[] getDeclaredMethods(final Class<?> c) {
+        return AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
+            @Override
+            public Method[] run() {
+                return c.getDeclaredMethods();
+            }
+        });
+    }
+    public static Method findPostConstructMethod(Class<?> c) {
+        return findPostConstructMethod(c, null);
+    }
+    public static Method findPostConstructMethod(Class<?> c, String name) {
+        if (Object.class == c || null == c) {
+            return null;
+        }
+        for (Method m : getDeclaredMethods(c)) {
+            if (name != null) {
+                if (m.getName().equals(name)) {
+                    return m;
+                }
+            } else if (m.getAnnotation(PostConstruct.class) != null) {
+                return m;
+            }
+        }
+        Method m = findPostConstructMethod(c.getSuperclass(), name);
+        if (m != null) {
+            return m;
+        }
+        for (Class<?> i : c.getInterfaces()) {
+            m = findPostConstructMethod(i, name);
+            if (m != null) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+    public static Method findPreDestroyMethod(Class<?> c) {
+        return findPreDestroyMethod(c, null);
+    }
+
+    public static Method findPreDestroyMethod(Class<?> c, String name) {
+        if (Object.class == c || null == c) {
+            return null;
+        }
+        for (Method m : getDeclaredMethods(c)) {
+            if (name != null) {
+                if (m.getName().equals(name)) {
+                    return m;
+                }
+            } else if (m.getAnnotation(PreDestroy.class) != null) {
+                return m;
+            }
+        }
+        Method m = findPreDestroyMethod(c.getSuperclass(), name);
+        if (m != null) {
+            return m;
+        }
+        for (Class<?> i : c.getInterfaces()) {
+            m = findPreDestroyMethod(i, name);
+            if (m != null) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+    public static ClassResourceInfo createClassResourceInfo(
+        Map<String, UserResource> resources, UserResource model,
+        Class<?> defaultClass,
+        boolean isRoot, boolean enableStatic,
+        Bus bus) {
+        final boolean isDefaultClass = defaultClass != null;
+        Class<?> sClass = !isDefaultClass  ? loadClass(model.getName()) : defaultClass;
+        return createServiceClassResourceInfo(resources, model, sClass, isRoot, enableStatic, bus);
+    }
+
+    public static ClassResourceInfo createServiceClassResourceInfo(
+        Map<String, UserResource> resources, UserResource model,
+        Class<?> sClass, boolean isRoot, boolean enableStatic, Bus bus) {
+        if (model == null) {
+            throw new RuntimeException("Resource class " + sClass.getName() + " has no model info");
+        }
+        ClassResourceInfo cri =
+            new ClassResourceInfo(sClass, sClass, isRoot, enableStatic, true,
+                                  model.getConsumes(), model.getProduces(), bus);
+        URITemplate t = URITemplate.createTemplate(model.getPath());
+        cri.setURITemplate(t);
+
+        MethodDispatcher md = new MethodDispatcher();
+        Map<String, UserOperation> ops = model.getOperationsAsMap();
+
+        Method defaultMethod = null;
+        Map<String, Method> methodNames = new HashMap<>();
+        for (Method m : cri.getServiceClass().getMethods()) {
+            if (m.getAnnotation(DefaultMethod.class) != null) {
+                // if needed we can also support multiple default methods
+                defaultMethod = m;
+            }
+            methodNames.put(m.getName(), m);
+        }
+
+        for (Map.Entry<String, UserOperation> entry : ops.entrySet()) {
+            UserOperation op = entry.getValue();
+            Method actualMethod = methodNames.get(op.getName());
+            if (actualMethod == null) {
+                actualMethod = defaultMethod;
+            }
+            if (actualMethod == null) {
+                continue;
+            }
+            OperationResourceInfo ori =
+                new OperationResourceInfo(actualMethod, cri, URITemplate.createTemplate(op.getPath()),
+                                          op.getVerb(), op.getConsumes(), op.getProduces(),
+                                          op.getParameters(),
+                                          op.isOneway());
+            String rClassName = actualMethod.getReturnType().getName();
+            if (op.getVerb() == null) {
+                if (resources.containsKey(rClassName)) {
+                    ClassResourceInfo subCri = rClassName.equals(model.getName()) ? cri
+                        : createServiceClassResourceInfo(resources, resources.get(rClassName),
+                                                         actualMethod.getReturnType(), false, enableStatic, bus);
+                    if (subCri != null) {
+                        cri.addSubClassResourceInfo(subCri);
+                        md.bind(ori, actualMethod);
+                    }
+                }
+            } else {
+                md.bind(ori, actualMethod);
+            }
+        }
+
+        cri.setMethodDispatcher(md);
+        return checkMethodDispatcher(cri) ? cri : null;
+
+    }
+
+    public static ClassResourceInfo createClassResourceInfo(final Class<?> rClass,
+                                                            final Class<?> sClass,
+                                                            boolean root,
+                                                            boolean enableStatic) {
+        return createClassResourceInfo(rClass, sClass, root, enableStatic, BusFactory.getThreadDefaultBus());
+
+    }
+
+    public static ClassResourceInfo createClassResourceInfo(final Class<?> rClass,
+                                                            final Class<?> sClass,
+                                                            boolean root,
+                                                            boolean enableStatic,
+                                                            Bus bus) {
+        return createClassResourceInfo(rClass, sClass, null, root, enableStatic, bus);
+    }
+
+    public static ClassResourceInfo createClassResourceInfo(final Class<?> rClass,
+                                                            final Class<?> sClass,
+                                                            ClassResourceInfo parent,
+                                                            boolean root,
+                                                            boolean enableStatic,
+                                                            Bus bus) {
+        return createClassResourceInfo(rClass, sClass, parent, root, enableStatic, bus, null, null);
+    }
+
+    //CHECKSTYLE:OFF
+    public static ClassResourceInfo createClassResourceInfo(final Class<?> rClass,
+                                                            final Class<?> sClass,
+                                                            ClassResourceInfo parent,
+                                                            boolean root,
+                                                            boolean enableStatic,
+                                                            Bus bus,
+                                                            List<MediaType> defaultConsumes,
+                                                            List<MediaType> defaultProduces) {
+    //CHECKSTYLE:ON
+        ClassResourceInfo cri = new ClassResourceInfo(rClass, sClass, root, enableStatic, bus,
+                                                      defaultConsumes, defaultProduces);
+        cri.setParent(parent);
+
+        if (root) {
+            URITemplate t = URITemplate.createTemplate(cri.getPath());
+            cri.setURITemplate(t);
+        }
+
+        evaluateResourceClass(cri, enableStatic);
+        return checkMethodDispatcher(cri) ? cri : null;
+    }
+
+    private static void evaluateResourceClass(ClassResourceInfo cri, boolean enableStatic) {
+        MethodDispatcher md = new MethodDispatcher();
+        Class<?> serviceClass = cri.getServiceClass();
+
+        final Set<Method> annotatedMethods = new HashSet<>();
+
+        for (Method m : serviceClass.getMethods()) {
+            if (!m.isBridge() && !m.isSynthetic()) {
+                //do real methods first
+                Method annotatedMethod = AnnotationUtils.getAnnotatedMethod(serviceClass, m);
+                if (!annotatedMethods.contains(annotatedMethod)) {
+                    evaluateResourceMethod(cri, enableStatic, md, m, annotatedMethod);
+                    annotatedMethods.add(annotatedMethod);
+                }
+            }
+        }
+        for (Method m : serviceClass.getMethods()) {
+            if (m.isBridge() || m.isSynthetic()) {
+                //if a bridge/synthetic method isn't already mapped to something, go ahead and do it
+                Method annotatedMethod = AnnotationUtils.getAnnotatedMethod(serviceClass, m);
+                if (!annotatedMethods.contains(annotatedMethod)) {
+                    evaluateResourceMethod(cri, enableStatic, md, m, annotatedMethod);
+                    annotatedMethods.add(annotatedMethod);
+                }
+            }
+        }
+        cri.setMethodDispatcher(md);
+    }
+
+    private static void evaluateResourceMethod(ClassResourceInfo cri, boolean enableStatic, MethodDispatcher md,
+                                               Method m, Method annotatedMethod) {
+        String httpMethod = AnnotationUtils.getHttpMethodValue(annotatedMethod);
+        Path path = AnnotationUtils.getMethodAnnotation(annotatedMethod, Path.class);
+
+        if (httpMethod != null || path != null) {
+            if (!checkAsyncResponse(annotatedMethod)) {
+                return;
+            }
+
+            md.bind(createOperationInfo(m, annotatedMethod, cri, path, httpMethod), m);
+            if (httpMethod == null) {
+                // subresource locator
+                Class<?> subClass = m.getReturnType();
+                if (subClass == Class.class) {
+                    subClass = InjectionUtils.getActualType(m.getGenericReturnType());
+                }
+                if (enableStatic) {
+                    ClassResourceInfo subCri = cri.findResource(subClass, subClass);
+                    if (subCri == null) {
+                        ClassResourceInfo ancestor = getAncestorWithSameServiceClass(cri, subClass);
+                        subCri = ancestor != null ? ancestor
+                                : createClassResourceInfo(subClass, subClass, cri, false, enableStatic,
+                                cri.getBus());
+                    }
+
+                    if (subCri != null) {
+                        cri.addSubClassResourceInfo(subCri);
+                    }
+                }
+            }
+        } else {
+            reportInvalidResourceMethod(m, NOT_RESOURCE_METHOD_MESSAGE_ID, Level.FINE);
+        }
+    }
+
+    private static void reportInvalidResourceMethod(Method m, String messageId, Level logLevel) {
+        if (LOG.isLoggable(logLevel)) {
+            LOG.log(logLevel, new org.apache.cxf.common.i18n.Message(messageId,
+                                                             BUNDLE,
+                                                             m.getDeclaringClass().getName(),
+                                                             m.getName()).toString());
+        }
+    }
+
+    private static boolean checkAsyncResponse(Method m) {
+        Class<?>[] types = m.getParameterTypes();
+        for (int i = 0; i < types.length; i++) {
+            if (types[i] == AsyncResponse.class) {
+                if (AnnotationUtils.getAnnotation(m.getParameterAnnotations()[i], Suspended.class) == null) {
+                    reportInvalidResourceMethod(m, NOT_SUSPENDED_ASYNC_MESSAGE_ID, Level.FINE);
+                    return false;
+                }
+                if (m.getReturnType() == Void.TYPE || m.getReturnType() == Void.class) {
+                    return true;
+                }
+                reportInvalidResourceMethod(m, NO_VOID_RETURN_ASYNC_MESSAGE_ID, Level.WARNING);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static ClassResourceInfo getAncestorWithSameServiceClass(ClassResourceInfo parent, Class<?> subClass) {
+        if (parent == null) {
+            return null;
+        }
+        if (parent.getServiceClass() == subClass) {
+            return parent;
+        }
+        return getAncestorWithSameServiceClass(parent.getParent(), subClass);
+    }
+
+    public static Constructor<?> findResourceConstructor(Class<?> resourceClass, boolean perRequest) {
+        List<Constructor<?>> cs = new LinkedList<>();
+        for (Constructor<?> c : resourceClass.getConstructors()) {
+            Class<?>[] params = c.getParameterTypes();
+            Annotation[][] anns = c.getParameterAnnotations();
+            boolean match = true;
+            for (int i = 0; i < params.length; i++) {
+                if (!perRequest) {
+                    if (AnnotationUtils.getAnnotation(anns[i], Context.class) == null) {
+                        match = false;
+                        break;
+                    }
+                } else if (!AnnotationUtils.isValidParamAnnotations(anns[i])) {
+                    match = false;
+                    break;
+                }
+            }
+            if (match) {
+                cs.add(c);
+            }
+        }
+        Collections.sort(cs, new Comparator<Constructor<?>>() {
+
+            public int compare(Constructor<?> c1, Constructor<?> c2) {
+                int p1 = c1.getParameterTypes().length;
+                int p2 = c2.getParameterTypes().length;
+                return p1 > p2 ? -1 : p1 < p2 ? 1 : 0;
+            }
+
+        });
+        return cs.isEmpty() ? null : cs.get(0);
+    }
+
+    public static List<Parameter> getParameters(Method resourceMethod) {
+        Annotation[][] paramAnns = resourceMethod.getParameterAnnotations();
+        if (paramAnns.length == 0) {
+            return CastUtils.cast(Collections.emptyList(), Parameter.class);
+        }
+        Class<?>[] types = resourceMethod.getParameterTypes();
+        List<Parameter> params = new ArrayList<>(paramAnns.length);
+        for (int i = 0; i < paramAnns.length; i++) {
+            Parameter p = getParameter(i, paramAnns[i], types[i]);
+            params.add(p);
+        }
+        return params;
+    }
+
+    //CHECKSTYLE:OFF
+    public static Parameter getParameter(int index, Annotation[] anns, Class<?> type) {
+
+        Context ctx = AnnotationUtils.getAnnotation(anns, Context.class);
+        if (ctx != null) {
+            return new Parameter(ParameterType.CONTEXT, index, null);
+        }
+
+        boolean isEncoded = AnnotationUtils.getAnnotation(anns, Encoded.class) != null;
+
+        BeanParam bp = AnnotationUtils.getAnnotation(anns, BeanParam.class);
+        if (bp != null) {
+            return new Parameter(ParameterType.BEAN, index, null, isEncoded, null);
+        }
+
+        String dValue = AnnotationUtils.getDefaultParameterValue(anns);
+
+        PathParam a = AnnotationUtils.getAnnotation(anns, PathParam.class);
+        if (a != null) {
+            return new Parameter(ParameterType.PATH, index, a.value(), isEncoded, dValue);
+        }
+        QueryParam q = AnnotationUtils.getAnnotation(anns, QueryParam.class);
+        if (q != null) {
+            return new Parameter(ParameterType.QUERY, index, q.value(), isEncoded, dValue);
+        }
+        MatrixParam m = AnnotationUtils.getAnnotation(anns, MatrixParam.class);
+        if (m != null) {
+            return new Parameter(ParameterType.MATRIX, index, m.value(), isEncoded, dValue);
+        }
+
+        FormParam f = AnnotationUtils.getAnnotation(anns, FormParam.class);
+        if (f != null) {
+            return new Parameter(ParameterType.FORM, index, f.value(), isEncoded, dValue);
+        }
+
+        HeaderParam h = AnnotationUtils.getAnnotation(anns, HeaderParam.class);
+        if (h != null) {
+            return new Parameter(ParameterType.HEADER, index, h.value(), isEncoded, dValue);
+        }
+
+        CookieParam c = AnnotationUtils.getAnnotation(anns, CookieParam.class);
+        if (c != null) {
+            return new Parameter(ParameterType.COOKIE, index, c.value(), isEncoded, dValue);
+        }
+
+        return new Parameter(ParameterType.REQUEST_BODY, index, null);
+
+    }
+    //CHECKSTYLE:ON
+
+    private static OperationResourceInfo createOperationInfo(Method m, Method annotatedMethod,
+                                                      ClassResourceInfo cri, Path path, String httpMethod) {
+        OperationResourceInfo ori = new OperationResourceInfo(m, annotatedMethod, cri);
+        URITemplate t = URITemplate.createTemplate(path);
+        ori.setURITemplate(t);
+        ori.setHttpMethod(httpMethod);
+        return ori;
+    }
+
+
+    private static boolean checkMethodDispatcher(ClassResourceInfo cr) {
+        if (cr.getMethodDispatcher().getOperationResourceInfos().isEmpty()) {
+            LOG.warning(new org.apache.cxf.common.i18n.Message("NO_RESOURCE_OP_EXC",
+                                                               BUNDLE,
+                                                               cr.getServiceClass().getName()).toString());
+            return false;
+        }
+        return true;
+    }
+
+
+    private static Class<?> loadClass(String cName) {
+        try {
+            return ClassLoaderUtils.loadClass(cName.trim(), ResourceUtils.class);
+        } catch (ClassNotFoundException ex) {
+            throw new RuntimeException("No class " + cName.trim() + " can be found", ex);
+        }
+    }
+
+
+    public static List<UserResource> getUserResources(String loc, Bus bus) {
+        try (InputStream is = ResourceUtils.getResourceStream(loc, bus)) {
+            if (is == null) {
+                return null;
+            }
+            return getUserResources(is);
+        } catch (Exception ex) {
+            LOG.warning("Problem with processing a user model at " + loc);
+        }
+
+        return null;
+    }
+
+    public static InputStream getResourceStream(String loc, Bus bus) throws IOException {
+        URL url = getResourceURL(loc, bus);
+        return url == null ? null : url.openStream();
+    }
+
+    public static URL getResourceURL(String loc, Bus bus) throws IOException {
+        URL url;
+        if (loc.startsWith(CLASSPATH_PREFIX)) {
+            String path = loc.substring(CLASSPATH_PREFIX.length());
+            url = ResourceUtils.getClasspathResourceURL(path, ResourceUtils.class, bus);
+        } else {
+            try {
+                url = new URL(loc);
+            } catch (Exception ex) {
+                // it can be either a classpath or file resource without a scheme
+                url = ResourceUtils.getClasspathResourceURL(loc, ResourceUtils.class, bus);
+                if (url == null) {
+                    File file = new File(loc);
+                    if (file.exists()) {
+                        url = file.toURI().toURL();
+                    }
+                }
+            }
+        }
+        if (url == null) {
+            LOG.warning("No resource " + loc + " is available");
+        }
+        return url;
+    }
+
+    public static InputStream getClasspathResourceStream(String path, Class<?> callingClass, Bus bus) {
+        InputStream is = ClassLoaderUtils.getResourceAsStream(path, callingClass);
+        return is == null ? getResource(path, InputStream.class, bus) : is;
+    }
+
+    public static URL getClasspathResourceURL(String path, Class<?> callingClass, Bus bus) {
+        URL url = ClassLoaderUtils.getResource(path, callingClass);
+        return url == null ? getResource(path, URL.class, bus) : url;
+    }
+
+    public static <T> T getResource(String path, Class<T> resourceClass, Bus bus) {
+        if (bus != null) {
+            ResourceManager rm = bus.getExtension(ResourceManager.class);
+            if (rm != null) {
+                return rm.resolveResource(path, resourceClass);
+            }
+        }
+        return null;
+    }
+
+    public static Properties loadProperties(String propertiesLocation, Bus bus) throws IOException {
+        Properties props = new Properties();
+        try (InputStream is = getResourceStream(propertiesLocation, bus)) {
+            props.load(is);
+        }
+        return props;
+    }
+
+    public static List<UserResource> getUserResources(String loc) {
+        return getUserResources(loc, BusFactory.getThreadDefaultBus());
+    }
+
+    public static List<UserResource> getUserResources(InputStream is) throws Exception {
+        Document doc = StaxUtils.read(new InputStreamReader(is, StandardCharsets.UTF_8));
+        return getResourcesFromElement(doc.getDocumentElement());
+    }
+
+    public static List<UserResource> getResourcesFromElement(Element modelEl) {
+        List<UserResource> resources = new ArrayList<>();
+        List<Element> resourceEls =
+            DOMUtils.findAllElementsByTagNameNS(modelEl,
+                                                "http://cxf.apache.org/jaxrs", "resource");
+        for (Element e : resourceEls) {
+            resources.add(getResourceFromElement(e));
+        }
+        return resources;
+    }
+
+
+    public static ResourceTypes getAllRequestResponseTypes(List<ClassResourceInfo> cris,
+                                                           boolean jaxbOnly) {
+        return getAllRequestResponseTypes(cris, jaxbOnly, null);
+    }
+
+    public static ResourceTypes getAllRequestResponseTypes(List<ClassResourceInfo> cris,
+                                                           boolean jaxbOnly,
+                                                           MessageBodyWriter<?> jaxbWriter) {
+        ResourceTypes types = new ResourceTypes();
+        for (ClassResourceInfo resource : cris) {
+            getAllTypesForResource(resource, types, jaxbOnly, jaxbWriter);
+        }
+        return types;
+    }
+
+    public static Class<?> getActualJaxbType(Class<?> type, Method resourceMethod, boolean inbound) {
+        ElementClass element = resourceMethod.getAnnotation(ElementClass.class);
+        if  (element != null) {
+            Class<?> cls = inbound ? element.request() : element.response();
+            if (cls != Object.class) {
+                return cls;
+            }
+        }
+        return type;
+    }
+
+    private static void getAllTypesForResource(ClassResourceInfo resource,
+                                               ResourceTypes types,
+                                               boolean jaxbOnly,
+                                               MessageBodyWriter<?> jaxbWriter) {
+        Class<?> jaxbElement = null;
+        try {
+            jaxbElement = ClassLoaderUtils.loadClass("javax.xml.bind.JAXBElement", ResourceUtils.class);
+        } catch (final ClassNotFoundException e) {
+            // no-op
+        }
+
+        for (OperationResourceInfo ori : resource.getMethodDispatcher().getOperationResourceInfos()) {
+            Method method = ori.getAnnotatedMethod() == null ? ori.getMethodToInvoke() : ori.getAnnotatedMethod();
+            Class<?> realReturnType = method.getReturnType();
+            Class<?> cls = realReturnType;
+            if (cls == Response.class || ori.isAsync()) {
+                cls = getActualJaxbType(cls, method, false);
+            }
+            Type type = method.getGenericReturnType();
+            if (jaxbOnly) {
+                checkJaxbType(resource.getServiceClass(), cls, realReturnType == Response.class || ori.isAsync()
+                    ? cls : type, types, method.getAnnotations(), jaxbWriter, jaxbElement);
+            } else {
+                types.getAllTypes().put(cls, type);
+            }
+
+            for (Parameter pm : ori.getParameters()) {
+                if (pm.getType() == ParameterType.REQUEST_BODY) {
+                    Class<?> inType = method.getParameterTypes()[pm.getIndex()];
+                    if (inType != AsyncResponse.class) {
+                        Type paramType = method.getGenericParameterTypes()[pm.getIndex()];
+                        if (jaxbOnly) {
+                            checkJaxbType(resource.getServiceClass(), inType, paramType, types,
+                                          method.getParameterAnnotations()[pm.getIndex()], jaxbWriter, jaxbElement);
+                        } else {
+                            types.getAllTypes().put(inType, paramType);
+                        }
+                    }
+                }
+            }
+
+        }
+
+        for (ClassResourceInfo sub : resource.getSubResources()) {
+            if (!isRecursiveSubResource(resource, sub)) {
+                getAllTypesForResource(sub, types, jaxbOnly, jaxbWriter);
+            }
+        }
+    }
+
+    private static boolean isRecursiveSubResource(ClassResourceInfo parent, ClassResourceInfo sub) {
+        if (parent == null) {
+            return false;
+        }
+        if (parent == sub) {
+            return true;
+        }
+        return isRecursiveSubResource(parent.getParent(), sub);
+    }
+
+    private static void checkJaxbType(Class<?> serviceClass,
+                                      Class<?> type,
+                                      Type genericType,
+                                      ResourceTypes types,
+                                      Annotation[] anns,
+                                      MessageBodyWriter<?> jaxbWriter,
+                                      Class<?> jaxbElement) {
+        boolean isCollection = false;
+        if (InjectionUtils.isSupportedCollectionOrArray(type)) {
+            type = InjectionUtils.getActualType(genericType);
+            isCollection = true;
+        }
+        if (type == Object.class && !(genericType instanceof Class)
+            || genericType instanceof TypeVariable) {
+            Type theType = InjectionUtils.processGenericTypeIfNeeded(serviceClass,
+                                                      Object.class,
+                                                      genericType);
+            type = InjectionUtils.getActualType(theType);
+        }
+        if (type == null
+            || InjectionUtils.isPrimitive(type)
+            || (jaxbElement != null && jaxbElement.isAssignableFrom(type))
+            || Response.class.isAssignableFrom(type)
+            || type.isInterface()) {
+            return;
+        }
+
+        MessageBodyWriter<?> writer = jaxbWriter;
+        if (writer == null) {
+            JAXBElementProvider<Object> defaultWriter = new JAXBElementProvider<>();
+            defaultWriter.setMarshallAsJaxbElement(true);
+            defaultWriter.setXmlTypeAsJaxbElementOnly(true);
+            writer = defaultWriter;
+        }
+        if (writer.isWriteable(type, type, anns, MediaType.APPLICATION_XML_TYPE)) {
+            types.getAllTypes().put(type, type);
+            Class<?> genCls = InjectionUtils.getActualType(genericType);
+            if (genCls != type && genCls != null && genCls != Object.class
+                && !InjectionUtils.isSupportedCollectionOrArray(genCls)) {
+                types.getAllTypes().put(genCls, genCls);
+            }
+
+            XMLName name = AnnotationUtils.getAnnotation(anns, XMLName.class);
+            QName qname = name != null ? JAXRSUtils.convertStringToQName(name.value()) : null;
+            if (isCollection) {
+                types.getCollectionMap().put(type, qname);
+            } else {
+                types.getXmlNameMap().put(type, qname);
+            }
+        }
+    }
+
+    private static UserResource getResourceFromElement(Element e) {
+        UserResource resource = new UserResource();
+        resource.setName(e.getAttribute("name"));
+        resource.setPath(e.getAttribute("path"));
+        resource.setConsumes(e.getAttribute("consumes"));
+        resource.setProduces(e.getAttribute("produces"));
+        List<Element> operEls =
+            DOMUtils.findAllElementsByTagNameNS(e,
+                 "http://cxf.apache.org/jaxrs", "operation");
+        List<UserOperation> opers = new ArrayList<>(operEls.size());
+        for (Element operEl : operEls) {
+            opers.add(getOperationFromElement(operEl));
+        }
+        resource.setOperations(opers);
+        return resource;
+    }
+
+    private static UserOperation getOperationFromElement(Element e) {
+        UserOperation op = new UserOperation();
+        op.setName(e.getAttribute("name"));
+        op.setVerb(e.getAttribute("verb"));
+        op.setPath(e.getAttribute("path"));
+        op.setOneway(Boolean.parseBoolean(e.getAttribute("oneway")));
+        op.setConsumes(e.getAttribute("consumes"));
+        op.setProduces(e.getAttribute("produces"));
+        List<Element> paramEls =
+            DOMUtils.findAllElementsByTagNameNS(e,
+                 "http://cxf.apache.org/jaxrs", "param");
+        List<Parameter> params = new ArrayList<>(paramEls.size());
+        for (int i = 0; i < paramEls.size(); i++) {
+            Element paramEl = paramEls.get(i);
+            Parameter p = new Parameter(paramEl.getAttribute("type"), i, paramEl.getAttribute("name"));
+            p.setEncoded(Boolean.valueOf(paramEl.getAttribute("encoded")));
+            p.setDefaultValue(paramEl.getAttribute("defaultValue"));
+            String pClass = paramEl.getAttribute("class");
+            if (!StringUtils.isEmpty(pClass)) {
+                try {
+                    p.setJavaType(ClassLoaderUtils.loadClass(pClass, ResourceUtils.class));
+                } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+            params.add(p);
+        }
+        op.setParameters(params);
+        return op;
+    }
+
+    public static Object[] createConstructorArguments(Constructor<?> c,
+                                                      Message m,
+                                                      boolean perRequest) {
+        return createConstructorArguments(c, m, perRequest, null);
+    }
+
+    public static Object[] createConstructorArguments(Constructor<?> c,
+                                                      Message m,
+                                                      boolean perRequest,
+                                                      Map<Class<?>, Object> contextValues) {
+        Class<?>[] params = c.getParameterTypes();
+        Annotation[][] anns = c.getParameterAnnotations();
+        Type[] genericTypes = c.getGenericParameterTypes();
+        return createConstructorArguments(c, m, perRequest, contextValues, params, anns, genericTypes);
+    }
+
+    public static Object[] createConstructorArguments(Constructor<?> c,
+                                                      Message m,
+                                                      boolean perRequest,
+                                                      Map<Class<?>,
+                                                      Object> contextValues,
+                                                      Class<?>[] params,
+                                                      Annotation[][] anns,
+                                                      Type[] genericTypes) {
+        if (m == null) {
+            m = new MessageImpl();
+        }
+        @SuppressWarnings("unchecked")
+        MultivaluedMap<String, String> templateValues =
+            (MultivaluedMap<String, String>)m.get(URITemplate.TEMPLATE_PARAMETERS);
+        Object[] values = new Object[params.length];
+        for (int i = 0; i < params.length; i++) {
+            if (AnnotationUtils.getAnnotation(anns[i], Context.class) != null) {
+                Object contextValue = contextValues != null ? contextValues.get(params[i]) : null;
+                if (contextValue == null) {
+                    if (perRequest || InjectionUtils.VALUE_CONTEXTS.contains(params[i].getName())) {
+                        values[i] = JAXRSUtils.createContextValue(m, genericTypes[i], params[i]);
+                    } else {
+                        values[i] = InjectionUtils.createThreadLocalProxy(params[i]);
+                    }
+                } else {
+                    values[i] = contextValue;
+                }
+            } else {
+                // this branch won't execute for singletons given that the found constructor
+                // is guaranteed to have only Context parameters, if any, for singletons
+                Parameter p = ResourceUtils.getParameter(i, anns[i], params[i]);
+                values[i] = JAXRSUtils.createHttpParameterValue(
+                                p, params[i], genericTypes[i], anns[i], m, templateValues, null);
+            }
+        }
+        return values;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static JAXRSServerFactoryBean createApplication(Application app,
+                                                           boolean ignoreAppPath,
+                                                           boolean staticSubresourceResolution,
+                                                           boolean useSingletonResourceProvider,
+                                                           Bus bus) {
+
+        Set<Object> singletons = app.getSingletons();
+        verifySingletons(singletons);
+
+        List<Class<?>> resourceClasses = new ArrayList<>();
+        List<Object> providers = new ArrayList<>();
+        List<Feature> features = new ArrayList<>();
+        Map<Class<?>, ResourceProvider> map = new HashMap<>();
+
+        // Note, app.getClasses() returns a list of per-request classes
+        // or singleton provider classes
+        for (Class<?> cls : app.getClasses()) {
+            if (isValidApplicationClass(cls, singletons)) {
+                if (isValidProvider(cls)) {
+                    providers.add(createProviderInstance(cls));
+                } else if (Feature.class.isAssignableFrom(cls)) {
+                    features.add(createFeatureInstance((Class<? extends Feature>) cls));
+                } else {
+                    resourceClasses.add(cls);
+                    if (useSingletonResourceProvider) {
+                        map.put(cls, new SingletonResourceProvider(createProviderInstance(cls)));
+                    } else {
+                        map.put(cls, new PerRequestResourceProvider(cls));
+                    }
+                }
+            }
+        }
+
+        // we can get either a provider or resource class here
+        for (Object o : singletons) {
+            if (isValidProvider(o.getClass())) {
+                providers.add(o);
+            } else if (o instanceof Feature) {
+                features.add((Feature) o);
+            } else {
+                resourceClasses.add(o.getClass());
+                map.put(o.getClass(), new SingletonResourceProvider(o));
+            }
+        }
+
+        JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean();
+        if (bus != null) {
+            bean.setBus(bus);
+        }
+
+        String address = "/";
+        if (!ignoreAppPath) {
+            ApplicationPath appPath = locateApplicationPath(app.getClass());
+            if (appPath != null) {
+                address = appPath.value();
+            }
+        }
+        if (!address.startsWith("/")) {
+            address = "/" + address;
+        }
+        bean.setAddress(address);
+        bean.setStaticSubresourceResolution(staticSubresourceResolution);
+        bean.setResourceClasses(resourceClasses);
+        bean.setProviders(providers);
+        bean.getFeatures().addAll(features);
+        for (Map.Entry<Class<?>, ResourceProvider> entry : map.entrySet()) {
+            bean.setResourceProvider(entry.getKey(), entry.getValue());
+        }
+        Map<String, Object> appProps = app.getProperties();
+        if (appProps != null) {
+            bean.getProperties(true).putAll(appProps);
+        }
+        bean.setApplication(app);
+        return bean;
+    }
+
+    public static Object createProviderInstance(Class<?> cls) {
+        try {
+            Constructor<?> c = ResourceUtils.findResourceConstructor(cls, false);
+            if (c != null && c.getParameterTypes().length == 0) {
+                return c.newInstance();
+            }
+            return c;
+        } catch (Throwable ex) {
+            throw new RuntimeException("Provider " + cls.getName() + " can not be created", ex);
+        }
+    }
+
+    public static Feature createFeatureInstance(Class<? extends Feature> cls) {
+        try {
+            Constructor<?> c = ResourceUtils.findResourceConstructor(cls, false);
+
+            if (c == null) {
+                throw new RuntimeException("No valid constructor found for " + cls.getName());
+            }
+
+            return (Feature) c.newInstance();
+        } catch (Throwable ex) {
+            throw new RuntimeException("Feature " + cls.getName() + " can not be created", ex);
+        }
+    }
+
+    private static boolean isValidProvider(Class<?> c) {
+        if (c == null || c == Object.class) {
+            return false;
+        }
+        if (c.getAnnotation(Provider.class) != null) {
+            return true;
+        }
+        for (Class<?> itf : c.getInterfaces()) {
+            if (SERVER_PROVIDER_CLASS_NAMES.contains(itf.getName())) {
+                return true;
+            }
+        }
+        return isValidProvider(c.getSuperclass());
+    }
+
+    private static void verifySingletons(Set<Object> singletons) {
+        if (singletons.isEmpty()) {
+            return;
+        }
+        Set<String> map = new HashSet<>();
+        for (Object s : singletons) {
+            if (map.contains(s.getClass().getName())) {
+                throw new RuntimeException("More than one instance of the same singleton class "
+                                           + s.getClass().getName() + " is available");
+            }
+            map.add(s.getClass().getName());
+        }
+    }
+
+    public static boolean isValidResourceClass(Class<?> c) {
+        if (c.isInterface() || Modifier.isAbstract(c.getModifiers())) {
+            LOG.info("Ignoring invalid resource class " + c.getName());
+            return false;
+        }
+        return true;
+    }
+
+    public static ApplicationPath locateApplicationPath(Class<?> appClass) {
+        ApplicationPath appPath = appClass.getAnnotation(ApplicationPath.class);
+        if (appPath == null && appClass.getSuperclass() != Application.class) {
+            return locateApplicationPath(appClass.getSuperclass());
+        }
+        return appPath;
+    }
+
+    private static boolean isValidApplicationClass(Class<?> c, Set<Object> singletons) {
+        if (!isValidResourceClass(c)) {
+            return false;
+        }
+        for (Object s : singletons) {
+            if (c == s.getClass()) {
+                LOG.info("Ignoring per-request resource class " + c.getName()
+                         + " as it is also registered as singleton");
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/message/MessageUtils.java b/transform/src/patch/java/org/apache/cxf/message/MessageUtils.java
new file mode 100644
index 0000000..e7f7523
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/message/MessageUtils.java
@@ -0,0 +1,261 @@
+/**
+ * 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.cxf.message;
+
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Node;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.service.invoker.MethodDispatcher;
+import org.apache.cxf.service.model.BindingOperationInfo;
+
+
+/**
+ * Holder for utility methods relating to messages.
+ */
+public final class MessageUtils {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(MessageUtils.class);
+
+    /**
+     * Prevents instantiation.
+     */
+    private MessageUtils() {
+    }
+
+    /**
+     * Determine if message is outbound.
+     *
+     * @param message the current Message
+     * @return true if the message direction is outbound
+     */
+    public static boolean isOutbound(Message message) {
+        if (message == null) {
+            return false;
+        }
+
+        Exchange exchange = message.getExchange();
+        return exchange != null
+               && (message == exchange.getOutMessage() || message == exchange.getOutFaultMessage());
+    }
+
+    /**
+     * Determine if message is fault.
+     *
+     * @param message the current Message
+     * @return true if the message is a fault
+     */
+    public static boolean isFault(Message message) {
+        return message != null
+               && message.getExchange() != null
+               && (message == message.getExchange().getInFaultMessage() || message == message.getExchange()
+                   .getOutFaultMessage());
+    }
+
+    /**
+     * Determine the fault mode for the underlying (fault) message
+     * (for use on server side only).
+     *
+     * @param message the fault message
+     * @return the FaultMode
+     */
+    public static FaultMode getFaultMode(Message message) {
+        if (message != null
+            && message.getExchange() != null
+            && message == message.getExchange().getOutFaultMessage()) {
+            FaultMode mode = message.get(FaultMode.class);
+            if (null != mode) {
+                return mode;
+            }
+            return FaultMode.RUNTIME_FAULT;
+        }
+        return null;
+    }
+
+    /**
+     * Determine if current messaging role is that of requestor.
+     *
+     * @param message the current Message
+     * @return true if the current messaging role is that of requestor
+     */
+    public static boolean isRequestor(Message message) {
+        if (message != null) {
+            Boolean requestor = (Boolean) message.get(Message.REQUESTOR_ROLE);
+            return requestor != null && requestor;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the current message is a partial response.
+     *
+     * @param message the current message
+     * @return true if the current messags is a partial response
+     */
+    public static boolean isPartialResponse(Message message) {
+        return message != null && Boolean.TRUE.equals(message.get(Message.PARTIAL_RESPONSE_MESSAGE));
+    }
+
+    /**
+     * Determines if the current message is an empty partial response, which
+     * is a partial response with an empty content.
+     *
+     * @param message the current message
+     * @return true if the current messags is a partial empty response
+     */
+    public static boolean isEmptyPartialResponse(Message message) {
+        return message != null && Boolean.TRUE.equals(message.get(Message.EMPTY_PARTIAL_RESPONSE_MESSAGE));
+    }
+
+    /**
+     * Returns true if a value is either the String "true" (regardless of case)  or Boolean.TRUE.
+     * @param value
+     * @return true if value is either the String "true" or Boolean.TRUE
+     * @deprecated replaced by {@link #PropertyUtils#isTrue(Object)}
+     */
+    @Deprecated
+    public static boolean isTrue(Object value) {
+        return PropertyUtils.isTrue(value);
+    }
+
+    public static boolean getContextualBoolean(Message m, String key) {
+        return getContextualBoolean(m, key, false);
+    }
+    public static boolean getContextualBoolean(Message m, String key, boolean defaultValue) {
+        if (m != null) {
+            Object o = m.getContextualProperty(key);
+            if (o != null) {
+                return PropertyUtils.isTrue(o);
+            }
+        }
+        return defaultValue;
+    }
+
+    public static int getContextualInteger(Message m, String key, int defaultValue) {
+        if (m != null) {
+            Object o = m.getContextualProperty(key);
+            if (o instanceof String) {
+                try {
+                    int i = Integer.parseInt((String)o);
+                    if (i > 0) {
+                        return i;
+                    }
+                } catch (NumberFormatException ex) {
+                    LOG.warning("Incorrect integer value of " + o + " specified for: " + key);
+                }
+            }
+        }
+        return defaultValue;
+    }
+
+    public static Object getContextualProperty(Message m, String propPreferred, String propDefault) {
+        Object prop = null;
+        if (m != null) {
+            prop = m.getContextualProperty(propPreferred);
+            if (prop == null && propDefault != null) {
+                prop = m.getContextualProperty(propDefault);
+            }
+        }
+        return prop;
+    }
+
+    /**
+     * Returns true if the underlying content format is a W3C DOM or a SAAJ message.
+     */
+    public static boolean isDOMPresent(Message m) {
+        return m != null && m.getContent(Node.class) != null;
+        /*
+        for (Class c : m.getContentFormats()) {
+            if (c.equals(Node.class) || "javax.xml.soap.SOAPMessage".equals(c.getName())) {
+                return true;
+            }
+        }
+        return false;
+        */
+    }
+
+    public static Optional<Method> getTargetMethod(Message m) {
+        Method method;
+        BindingOperationInfo bop = m.getExchange().getBindingOperationInfo();
+        if (bop != null) {
+            MethodDispatcher md = (MethodDispatcher) m.getExchange().getService().get(MethodDispatcher.class.getName());
+            method = md.getMethod(bop);
+        } else {
+            // See please JAXRSInInterceptor#RESOURCE_METHOD for the reference
+            method = (Method) m.get("org.apache.cxf.resource.method");
+        }
+        return Optional.ofNullable(method);
+    }
+    
+    /**
+     * Gets the response code from the message and tries to deduct one if it 
+     * is not set yet. 
+     * @param message message to get response code from
+     * @return response code (or deducted value assuming success)
+     */
+    public static int getReponseCodeFromMessage(Message message) {
+        Integer i = (Integer)message.get(Message.RESPONSE_CODE);
+        if (i != null) {
+            return i.intValue();
+        }
+        int code = hasNoResponseContent(message) ? HttpURLConnection.HTTP_ACCEPTED : HttpURLConnection.HTTP_OK;
+        // put the code in the message so that others can get it
+        message.put(Message.RESPONSE_CODE, code);
+        return code;
+    }
+
+    /**
+     * Determines if the current message has no response content.
+     * The message has no response content if either:
+     *  - the request is oneway and the current message is no partial
+     *    response or an empty partial response.
+     *  - the request is not oneway but the current message is an empty partial
+     *    response.
+     * @param message
+     * @return
+     */
+    public static boolean hasNoResponseContent(Message message) {
+        final boolean ow = isOneWay(message);
+        final boolean pr = MessageUtils.isPartialResponse(message);
+        final boolean epr = MessageUtils.isEmptyPartialResponse(message);
+
+        //REVISIT may need to provide an option to choose other behavior?
+        // old behavior not suppressing any responses  => ow && !pr
+        // suppress empty responses for oneway calls   => ow && (!pr || epr)
+        // suppress additionally empty responses for decoupled twoway calls =>
+        return (ow && !pr) || epr;
+    }
+    
+    /**
+     * Checks if the message is oneway or not
+     * @param message the message under consideration
+     * @return true if the message has been marked as oneway
+     */
+    public static boolean isOneWay(Message message) {
+        final Exchange ex = message.getExchange();
+        return ex != null && ex.isOneWay();
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/phase/PhaseChainCache.java b/transform/src/patch/java/org/apache/cxf/phase/PhaseChainCache.java
new file mode 100644
index 0000000..ccd12d2
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/phase/PhaseChainCache.java
@@ -0,0 +1,137 @@
+/**
+ * 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.cxf.phase;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.SortedSet;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.cxf.common.util.ModCountCopyOnWriteArrayList;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.message.Message;
+
+/**
+ * The PhaseChainCache provides default interceptor chains for SOAP requests
+ * and responses, both from the client and web service side.  The list of
+ * phases supplied in the get() methods of this class are defined by default
+ * within org.apache.cxf.phase.PhaseManagerImpl.  For an example of this class
+ * in use, check the sourcecode of org.apache.cxf.endpoint.ClientImpl.
+ */
+public final class PhaseChainCache {
+    AtomicReference<ChainHolder> lastData = new AtomicReference<>();
+
+    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
+                                     List<Interceptor<? extends Message>> p1) {
+        return getChain(lastData, phaseList, p1);
+    }
+
+    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
+                                     List<Interceptor<? extends Message>> p1,
+                                     List<Interceptor<? extends Message>> p2) {
+        return getChain(lastData, phaseList, p1, p2);
+    }
+    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
+                                     List<Interceptor<? extends Message>> p1,
+                                     List<Interceptor<? extends Message>> p2,
+                                     List<Interceptor<? extends Message>> p3) {
+        return getChain(lastData, phaseList, p1, p2, p3);
+    }
+    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
+                                     List<Interceptor<? extends Message>> p1,
+                                     List<Interceptor<? extends Message>> p2,
+                                     List<Interceptor<? extends Message>> p3,
+                                     List<Interceptor<? extends Message>> p4) {
+        return getChain(lastData, phaseList, p1, p2, p3, p4);
+    }
+    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
+                                     List<Interceptor<? extends Message>> p1,
+                                     List<Interceptor<? extends Message>> p2,
+                                     List<Interceptor<? extends Message>> p3,
+                                     List<Interceptor<? extends Message>> p4,
+                                     List<Interceptor<? extends Message>> p5) {
+        return getChain(lastData, phaseList, p1, p2, p3, p4, p5);
+    }
+
+    @SafeVarargs
+    static PhaseInterceptorChain getChain(AtomicReference<ChainHolder> lastData,
+                                          SortedSet<Phase> phaseList,
+                                         List<Interceptor<? extends Message>> ... providers) {
+        ChainHolder last = lastData.get();
+
+        if (last == null
+            || !last.matches(providers)) {
+
+            PhaseInterceptorChain chain = new PhaseInterceptorChain(phaseList);
+            List<ModCountCopyOnWriteArrayList<Interceptor<? extends Message>>> copy
+                = new ArrayList<>(providers.length);
+            for (List<Interceptor<? extends Message>> p : providers) {
+                copy.add(new ModCountCopyOnWriteArrayList<>(p));
+                chain.add(p);
+            }
+            last = new ChainHolder(chain, copy);
+            lastData.set(last);
+        }
+
+
+        return last.chain.cloneChain();
+    }
+
+    private static class ChainHolder {
+        List<ModCountCopyOnWriteArrayList<Interceptor<? extends Message>>> lists;
+        PhaseInterceptorChain chain;
+
+        ChainHolder(PhaseInterceptorChain c,
+                    List<ModCountCopyOnWriteArrayList<Interceptor<? extends Message>>> l) {
+            lists = l;
+            chain = c;
+        }
+
+        @SafeVarargs
+        final boolean matches(List<Interceptor<? extends Message>> ... providers) {
+            if (lists.size() == providers.length) {
+                for (int x = 0; x < providers.length; x++) {
+                    if (lists.get(x).size() != providers[x].size()) {
+                        return false;
+                    }
+
+                    if (providers[x].getClass() == ModCountCopyOnWriteArrayList.class) {
+                        if (((ModCountCopyOnWriteArrayList<?>)providers[x]).getModCount()
+                            != lists.get(x).getModCount()) {
+                            return false;
+                        }
+                    } else {
+                        ListIterator<Interceptor<? extends Message>> i1 = lists.get(x).listIterator();
+                        ListIterator<Interceptor<? extends Message>> i2 = providers[x].listIterator();
+
+                        while (i1.hasNext()) {
+                            if (i1.next() != i2.next()) {
+                                return false;
+                            }
+                        }
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/phase/PhaseInterceptorChain.java b/transform/src/patch/java/org/apache/cxf/phase/PhaseInterceptorChain.java
new file mode 100644
index 0000000..c8a52a8
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/phase/PhaseInterceptorChain.java
@@ -0,0 +1,857 @@
+/**
+ * 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.cxf.phase;
+
+import java.lang.ref.WeakReference;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.continuations.SuspendedInvocationException;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.interceptor.InterceptorChain;
+import org.apache.cxf.interceptor.ServiceInvokerInterceptor;
+import org.apache.cxf.logging.FaultListener;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.FaultMode;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.model.BindingOperationInfo;
+import org.apache.cxf.service.model.OperationInfo;
+import org.apache.cxf.transport.MessageObserver;
+
+/**
+ * A PhaseInterceptorChain orders Interceptors according to the phase they
+ * participate in and also according to the before & after properties on an
+ * Interceptor.
+ * <p>
+ * A List of phases is supplied to the PhaseInterceptorChain in the constructor.
+ * This class is typically instantiated from the PhaseChainCache class in this
+ * package. Interceptors that are added to the chain are ordered by phase.
+ * Within a phase, interceptors can order themselves. Each PhaseInterceptor
+ * has an ID. PhaseInterceptors can supply a Collection of IDs which they
+ * should run before or after, supplying fine grained ordering.
+ * <p>
+ *
+ */
+public class PhaseInterceptorChain implements InterceptorChain {
+    public static final String PREVIOUS_MESSAGE = PhaseInterceptorChain.class.getName() + ".PREVIOUS_MESSAGE";
+
+    private static final Logger LOG = LogUtils.getL7dLogger(PhaseInterceptorChain.class);
+
+    private static final ThreadLocal<Message> CURRENT_MESSAGE = new ThreadLocal<>();
+
+    private final Map<String, Integer> nameMap;
+    private final Phase[] phases;
+
+    // heads[phase] refers to the first interceptor of the given phase
+    private InterceptorHolder[] heads;
+    // tails[phase] refers to the last interceptor of the given phase
+    private InterceptorHolder[] tails;
+    // hasAfters[phase] indicates that the given phase has already inserted
+    // interceptors that may need to be placed after future to-be-inserted
+    // interceptors.  This flag is used to activate ordering of interceptors
+    // when new ones are added to the list for this phase.
+    // Note no hasBefores[] is needed because implementation adds subsequent
+    // interceptors to the end of the list by default.
+    private boolean[] hasAfters;
+
+
+    private State state;
+    private Message pausedMessage;
+    private MessageObserver faultObserver;
+    private PhaseInterceptorIterator iterator;
+    private final boolean isFineLogging;
+
+    // currently one chain for one request/response, use below as signal
+    // to avoid duplicate fault processing on nested calling of
+    // doIntercept(), which will throw same fault multi-times
+    private boolean faultOccurred;
+    private boolean chainReleased;
+
+
+    private PhaseInterceptorChain(PhaseInterceptorChain src) {
+        isFineLogging = LOG.isLoggable(Level.FINE);
+
+        //only used for clone
+        state = State.EXECUTING;
+
+        //immutable, just repoint
+        nameMap = src.nameMap;
+        phases = src.phases;
+
+        int length = phases.length;
+        hasAfters = new boolean[length];
+        System.arraycopy(src.hasAfters, 0, hasAfters, 0, length);
+
+        heads = new InterceptorHolder[length];
+        tails = new InterceptorHolder[length];
+
+        InterceptorHolder last = null;
+        for (int x = 0; x < length; x++) {
+            InterceptorHolder ih = src.heads[x];
+            while (ih != null
+                && ih.phaseIdx == x) {
+                InterceptorHolder ih2 = new InterceptorHolder(ih);
+                ih2.prev = last;
+                if (last != null) {
+                    last.next = ih2;
+                }
+                if (heads[x] == null) {
+                    heads[x] = ih2;
+                }
+                tails[x] = ih2;
+                last = ih2;
+                ih = ih.next;
+            }
+        }
+    }
+
+    public PhaseInterceptorChain(SortedSet<Phase> ps) {
+        state = State.EXECUTING;
+        isFineLogging = LOG.isLoggable(Level.FINE);
+
+        int numPhases = ps.size();
+        phases = new Phase[numPhases];
+        nameMap = new HashMap<>();
+
+        heads = new InterceptorHolder[numPhases];
+        tails = new InterceptorHolder[numPhases];
+        hasAfters = new boolean[numPhases];
+
+        int idx = 0;
+        for (Phase phase : ps) {
+            phases[idx] = phase;
+            nameMap.put(phase.getName(), idx);
+            ++idx;
+        }
+    }
+
+    public static Message getCurrentMessage() {
+        return CURRENT_MESSAGE.get();
+    }
+
+    public static boolean setCurrentMessage(PhaseInterceptorChain chain, Message m) {
+        if (getCurrentMessage() == m) {
+            return false;
+        }
+        if (chain.iterator.hasPrevious()) {
+            chain.iterator.previous();
+            if (chain.iterator.next() instanceof ServiceInvokerInterceptor) {
+                CURRENT_MESSAGE.set(m);
+                return true;
+            }
+            String error = "Only ServiceInvokerInterceptor can update the current chain message";
+            LOG.warning(error);
+            throw new IllegalStateException(error);
+        }
+        return false;
+
+    }
+
+    public synchronized State getState() {
+        return state;
+    }
+
+    public synchronized void releaseAndAcquireChain() {
+        while (!chainReleased) {
+            try {
+                this.wait();
+            } catch (InterruptedException ex) {
+                // ignore
+            }
+        }
+        chainReleased = false;
+    }
+
+    public synchronized void releaseChain() {
+        this.chainReleased = true;
+        this.notifyAll();
+    }
+
+    public PhaseInterceptorChain cloneChain() {
+        return new PhaseInterceptorChain(this);
+    }
+
+    private void updateIterator() {
+        if (iterator == null) {
+            iterator = new PhaseInterceptorIterator(heads);
+            outputChainToLog(false);
+        }
+    }
+
+    public void add(Collection<Interceptor<? extends Message>> newhandlers) {
+        add(newhandlers, false);
+    }
+
+    public void add(Collection<Interceptor<? extends Message>> newhandlers, boolean force) {
+        if (newhandlers == null) {
+            return;
+        }
+
+        for (Interceptor<? extends Message> handler : newhandlers) {
+            add(handler, force);
+        }
+    }
+
+    public void add(Interceptor<? extends Message> i) {
+        add(i, false);
+    }
+
+    public void add(Interceptor<? extends Message> i, boolean force) {
+        PhaseInterceptor<? extends Message> pi = (PhaseInterceptor<? extends Message>)i;
+
+        String phaseName = pi.getPhase();
+        Integer phase = nameMap.get(phaseName);
+
+        if (phase == null) {
+            LOG.warning("Skipping interceptor " + i.getClass().getName()
+                + ((phaseName == null) ? ": Phase declaration is missing."
+                : ": Phase " + phaseName + " specified does not exist."));
+        } else {
+            if (isFineLogging) {
+                LOG.fine("Adding interceptor " + i + " to phase " + phaseName);
+            }
+
+            insertInterceptor(phase, pi, force);
+        }
+        Collection<PhaseInterceptor<? extends Message>> extras
+            = pi.getAdditionalInterceptors();
+        if (extras != null) {
+            for (PhaseInterceptor<? extends Message> p : extras) {
+                add(p, force);
+            }
+        }
+    }
+
+    public synchronized void pause() {
+        state = State.PAUSED;
+        pausedMessage = CURRENT_MESSAGE.get();
+    }
+    public synchronized void unpause() {
+        if (state == State.PAUSED || state == State.SUSPENDED) {
+            state = State.EXECUTING;
+            pausedMessage = null;
+        }
+    }
+
+    public synchronized void suspend() {
+        state = State.SUSPENDED;
+        pausedMessage = CURRENT_MESSAGE.get();
+    }
+
+    public synchronized void resume() {
+        if (state == State.PAUSED || state == State.SUSPENDED) {
+            state = State.EXECUTING;
+            Message m = pausedMessage;
+            pausedMessage = null;
+            doIntercept(m);
+        }
+    }
+
+    /**
+     * Intercept a message, invoking each phase's handlers in turn.
+     *
+     * @param message the message
+     * @throws Exception
+     */
+    @SuppressWarnings("unchecked")
+    public synchronized boolean doIntercept(Message message) {
+        updateIterator();
+
+        Message oldMessage = CURRENT_MESSAGE.get();
+        try {
+            CURRENT_MESSAGE.set(message);
+            if (oldMessage != null
+                && !message.containsKey(PREVIOUS_MESSAGE)
+                && message != oldMessage
+                && message.getExchange() != oldMessage.getExchange()) {
+                message.put(PREVIOUS_MESSAGE, new WeakReference<Message>(oldMessage));
+            }
+            while (state == State.EXECUTING && iterator.hasNext()) {
+                try {
+                    Interceptor<Message> currentInterceptor = (Interceptor<Message>)iterator.next();
+                    if (isFineLogging) {
+                        LOG.fine("Invoking handleMessage on interceptor " + currentInterceptor);
+                    }
+                    //System.out.println("-----------" + currentInterceptor);
+                    currentInterceptor.handleMessage(message);
+                    if (state == State.SUSPENDED) {
+                         // throw the exception to make sure thread exit without interrupt
+                        throw new SuspendedInvocationException();
+                    }
+
+                } catch (SuspendedInvocationException ex) {
+
+                    // Moving the chain iterator to the previous interceptor is needed
+                    // for the invocation to be resumed from the same interceptor which
+                    // suspended the invocation.
+                    // If "suspend.chain.on.current.interceptor" is set to true then
+                    // the chain will be resumed from the interceptor which follows
+                    // the interceptor which suspended the invocation.
+                    Object suspendProp = message.remove("suspend.chain.on.current.interceptor");
+                    if ((suspendProp == null || PropertyUtils.isFalse(suspendProp))
+                        && iterator.hasPrevious()) {
+                        iterator.previous();
+                    }
+                    pause();
+                    throw ex;
+                } catch (RuntimeException ex) {
+                    if (!faultOccurred) {
+                        faultOccurred = true;
+                        wrapExceptionAsFault(message, ex);
+                    }
+                    state = State.ABORTED;
+                }
+            }
+            if (state == State.EXECUTING) {
+                state = State.COMPLETE;
+            }
+            return state == State.COMPLETE;
+        } finally {
+            CURRENT_MESSAGE.set(oldMessage);
+        }
+    }
+
+    private void wrapExceptionAsFault(Message message, RuntimeException ex) {
+        String description = getServiceInfo(message);
+
+        message.setContent(Exception.class, ex);
+        unwind(message);
+        Exception ex2 = message.getContent(Exception.class);
+        if (ex2 == null) {
+            ex2 = ex;
+        }
+
+        FaultListener flogger = (FaultListener)
+                message.getContextualProperty(FaultListener.class.getName());
+        boolean useDefaultLogging = true;
+        if (flogger != null) {
+            useDefaultLogging = flogger.faultOccurred(ex2, description, message);
+        }
+        if (useDefaultLogging) {
+            doDefaultLogging(message, ex2, description);
+        }
+
+        if (message.getExchange() != null && message.getContent(Exception.class) != null) {
+            message.getExchange().put(Exception.class, ex2);
+        }
+
+        if (faultObserver != null && !isOneWay(message)) {
+            // CXF-5629. when exchange is one way and robust, it becomes req-resp in order to
+            // send the fault
+            message.getExchange().setOneWay(false);
+            faultObserver.onMessage(message);
+        }
+    }
+
+    private String getServiceInfo(Message message) {
+        StringBuilder description = new StringBuilder();
+        if (message.getExchange() != null) {
+            Exchange exchange = message.getExchange();
+            Service service = exchange.getService();
+            if (service != null) {
+                description.append('\'');
+                description.append(service.getName());
+                BindingOperationInfo boi = exchange.getBindingOperationInfo();
+                OperationInfo opInfo = boi != null ? boi.getOperationInfo() : null;
+                if (opInfo != null) {
+                    description.append('#').append(opInfo.getName());
+                }
+                description.append("\' ");
+            }
+        }
+        return description.toString();
+    }
+
+    private void doDefaultLogging(Message message, Exception ex, String description) {
+        FaultMode mode = message.get(FaultMode.class);
+        if (mode == FaultMode.CHECKED_APPLICATION_FAULT) {
+            if (isFineLogging) {
+                LogUtils.log(LOG, Level.FINE,
+                             "Application " + description
+                             + "has thrown exception, unwinding now", ex);
+            } else if (LOG.isLoggable(Level.INFO)) {
+                Throwable t = ex;
+                if (ex instanceof Fault
+                    && ex.getCause() != null) {
+                    t = ex.getCause();
+                }
+
+                LogUtils.log(LOG, Level.INFO,
+                             "Application " + description
+                             + "has thrown exception, unwinding now: "
+                             + t.getClass().getName()
+                             + ": " + ex.getMessage());
+            }
+        } else if (LOG.isLoggable(Level.WARNING)) {
+            if (mode == FaultMode.UNCHECKED_APPLICATION_FAULT) {
+                LogUtils.log(LOG, Level.WARNING,
+                             "Application " + description
+                             + "has thrown exception, unwinding now", ex);
+            } else {
+                LogUtils.log(LOG, Level.WARNING,
+                             "Interceptor for " + description
+                             + "has thrown exception, unwinding now", ex);
+            }
+        }
+    }
+
+    private boolean isOneWay(Message message) {
+        return (message.getExchange() != null) && message.getExchange().isOneWay() && !isRobustOneWay(message);
+    }
+
+    private boolean isRobustOneWay(Message message) {
+        return MessageUtils.getContextualBoolean(message, Message.ROBUST_ONEWAY, false);
+    }
+
+    /**
+     * Intercept a message, invoking each phase's handlers in turn,
+     * starting after the specified interceptor.
+     *
+     * @param message the message
+     * @param startingAfterInterceptorID the id of the interceptor
+     * @throws Exception
+     */
+    public synchronized boolean doInterceptStartingAfter(Message message,
+                                                         String startingAfterInterceptorID) {
+        updateIterator();
+        while (state == State.EXECUTING && iterator.hasNext()) {
+            PhaseInterceptor<? extends Message> currentInterceptor
+                = (PhaseInterceptor<? extends Message>)iterator.next();
+            if (currentInterceptor.getId().equals(startingAfterInterceptorID)) {
+                break;
+            }
+        }
+        return doIntercept(message);
+    }
+
+    /**
+     * Intercept a message, invoking each phase's handlers in turn,
+     * starting at the specified interceptor.
+     *
+     * @param message the message
+     * @param startingAtInterceptorID the id of the interceptor
+     * @throws Exception
+     */
+    public synchronized boolean doInterceptStartingAt(Message message,
+                                                         String startingAtInterceptorID) {
+        updateIterator();
+        while (state == State.EXECUTING && iterator.hasNext()) {
+            PhaseInterceptor<? extends Message> currentInterceptor
+                = (PhaseInterceptor<? extends Message>)iterator.next();
+            if (currentInterceptor.getId().equals(startingAtInterceptorID)) {
+                iterator.previous();
+                break;
+            }
+        }
+        return doIntercept(message);
+    }
+
+    public synchronized void reset() {
+        updateIterator();
+        if (state == State.COMPLETE) {
+            state = State.EXECUTING;
+            iterator.reset();
+        } else {
+            iterator.reset();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void unwind(Message message) {
+        while (iterator.hasPrevious()) {
+            Interceptor<Message> currentInterceptor = (Interceptor<Message>)iterator.previous();
+            if (isFineLogging) {
+                LOG.fine("Invoking handleFault on interceptor " + currentInterceptor);
+            }
+            try {
+                currentInterceptor.handleFault(message);
+            } catch (RuntimeException e) {
+                LOG.log(Level.WARNING, "Exception in handleFault on interceptor " + currentInterceptor, e);
+                throw e;
+            } catch (Exception e) {
+                LOG.log(Level.WARNING, "Exception in handleFault on interceptor " + currentInterceptor, e);
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public void remove(Interceptor<? extends Message> i) {
+        PhaseInterceptorIterator it = new PhaseInterceptorIterator(heads);
+        while (it.hasNext()) {
+            InterceptorHolder holder = it.nextInterceptorHolder();
+            if (holder.interceptor == i) {
+                remove(holder);
+                return;
+            }
+        }
+    }
+
+    public synchronized void abort() {
+        this.state = InterceptorChain.State.ABORTED;
+    }
+
+    public Iterator<Interceptor<? extends Message>> iterator() {
+        return getIterator();
+    }
+    public ListIterator<Interceptor<? extends Message>> getIterator() {
+        return new PhaseInterceptorIterator(heads);
+    }
+
+    private void remove(InterceptorHolder i) {
+        if (i.prev != null) {
+            i.prev.next = i.next;
+        }
+        if (i.next != null) {
+            i.next.prev = i.prev;
+        }
+        int ph = i.phaseIdx;
+        if (heads[ph] == i) {
+            if (i.next != null
+                && i.next.phaseIdx == ph) {
+                heads[ph] = i.next;
+            } else {
+                heads[ph] = null;
+                tails[ph] = null;
+            }
+        }
+        if (tails[ph] == i) {
+            if (i.prev != null
+                && i.prev.phaseIdx == ph) {
+                tails[ph] = i.prev;
+            } else {
+                heads[ph] = null;
+                tails[ph] = null;
+            }
+        }
+    }
+
+    private void insertInterceptor(int phase, PhaseInterceptor<? extends Message> interc, boolean force) {
+        InterceptorHolder ih = new InterceptorHolder(interc, phase);
+        if (heads[phase] == null) {
+            // no interceptors yet in this phase
+            heads[phase] = ih;
+            tails[phase] = ih;
+            hasAfters[phase] = !interc.getAfter().isEmpty();
+
+            int idx = phase - 1;
+            while (idx >= 0) {
+                if (tails[idx] != null) {
+                    break;
+                }
+                --idx;
+            }
+            if (idx >= 0) {
+                //found something before us, in an earlier phase
+                ih.prev = tails[idx];
+                ih.next = tails[idx].next;
+                if (ih.next != null) {
+                    ih.next.prev = ih;
+                }
+                tails[idx].next = ih;
+            } else {
+                //did not find something before us, try after
+                idx = phase + 1;
+                while (idx < heads.length) {
+                    if (heads[idx] != null) {
+                        break;
+                    }
+                    ++idx;
+                }
+
+                if (idx != heads.length) {
+                    //found something after us
+                    ih.next = heads[idx];
+                    heads[idx].prev = ih;
+                }
+            }
+        } else { // this phase already has interceptors attached
+
+            // list of interceptors that the new interceptor should precede
+            Set<String> beforeList = interc.getBefore();
+
+            // list of interceptors that the new interceptor should be after
+            Set<String> afterList = interc.getAfter();
+
+            // firstBefore will hold the first interceptor of a given phase
+            // that the interceptor to be added must precede
+            InterceptorHolder firstBefore = null;
+
+            // lastAfter will hold the last interceptor of a given phase
+            // that the interceptor to be added must come after
+            InterceptorHolder lastAfter = null;
+
+            String id = interc.getId();
+            if (hasAfters[phase] || !beforeList.isEmpty()) {
+
+                InterceptorHolder ih2 = heads[phase];
+                while (ih2 != tails[phase].next) {
+                    PhaseInterceptor<? extends Message> cmp = ih2.interceptor;
+                    String cmpId = cmp.getId();
+                    if (cmpId != null && firstBefore == null
+                        && (beforeList.contains(cmpId)
+                            || cmp.getAfter().contains(id))) {
+                        firstBefore = ih2;
+                    }
+                    if (cmp.getBefore().contains(id)
+                        || (cmpId != null && afterList.contains(cmpId))) {
+                        lastAfter = ih2;
+                    }
+                    if (!force && cmpId.equals(id)) {
+                        // interceptor is already in chain
+                        return;
+                    }
+                    ih2 = ih2.next;
+                }
+                if (lastAfter == null && beforeList.contains("*")) {
+                    firstBefore = heads[phase];
+                }
+                
+            } else if (!force) {
+                // skip interceptor if already in chain
+                InterceptorHolder ih2 = heads[phase];
+                while (ih2 != tails[phase].next) {
+                    if (ih2.interceptor.getId().equals(id)) {
+                        return;
+                    }
+                    ih2 = ih2.next;
+                }
+
+            }
+            hasAfters[phase] |= !afterList.isEmpty();
+
+            if (firstBefore == null
+                && lastAfter == null
+                && !beforeList.isEmpty()
+                && afterList.isEmpty()) {
+                //if this interceptor has stuff it MUST be before,
+                //but nothing it must be after, just
+                //stick it at the beginning
+                firstBefore = heads[phase];
+            }
+
+            if (firstBefore == null) {
+                //just add new interceptor at the end
+                ih.prev = tails[phase];
+                ih.next = tails[phase].next;
+                tails[phase].next = ih;
+
+                if (ih.next != null) {
+                    ih.next.prev = ih;
+                }
+                tails[phase] = ih;
+            } else {
+                ih.prev = firstBefore.prev;
+                if (ih.prev != null) {
+                    ih.prev.next = ih;
+                }
+                ih.next = firstBefore;
+                firstBefore.prev = ih;
+
+                if (heads[phase] == firstBefore) {
+                    heads[phase] = ih;
+                }
+            }
+        }
+        if (iterator != null) {
+            outputChainToLog(true);
+        }
+    }
+
+    public String toString() {
+        return toString("");
+    }
+    private String toString(String message) {
+        StringBuilder chain = new StringBuilder(128);
+
+        chain.append("Chain ")
+            .append(super.toString())
+            .append(message)
+            .append(". Current flow:\n");
+
+        for (int x = 0; x < phases.length; x++) {
+            if (heads[x] != null) {
+                chain.append("  ");
+                printPhase(x, chain);
+            }
+        }
+        return chain.toString();
+    }
+    private void printPhase(int ph, StringBuilder chain) {
+
+        chain.append(phases[ph].getName())
+            .append(" [");
+        InterceptorHolder i = heads[ph];
+        boolean first = true;
+        while (i != tails[ph].next) {
+            if (first) {
+                first = false;
+            } else {
+                chain.append(", ");
+            }
+            String nm = i.interceptor.getClass().getSimpleName();
+            if (StringUtils.isEmpty(nm)) {
+                nm = i.interceptor.getId();
+            }
+            chain.append(nm);
+            i = i.next;
+        }
+        chain.append("]\n");
+    }
+
+    private void outputChainToLog(boolean modified) {
+        if (isFineLogging) {
+            if (modified) {
+                LOG.fine(toString(" was modified"));
+            } else {
+                LOG.fine(toString(" was created"));
+            }
+        }
+    }
+
+    public MessageObserver getFaultObserver() {
+        return faultObserver;
+    }
+
+    public void setFaultObserver(MessageObserver faultObserver) {
+        this.faultObserver = faultObserver;
+    }
+
+    static final class PhaseInterceptorIterator implements ListIterator<Interceptor<? extends Message>> {
+        InterceptorHolder[] heads;
+        InterceptorHolder prev;
+        InterceptorHolder first;
+
+        PhaseInterceptorIterator(InterceptorHolder[] h) {
+            heads = h;
+            first = findFirst();
+        }
+
+        public void reset() {
+            prev = null;
+            first = findFirst();
+        }
+
+        private InterceptorHolder findFirst() {
+            for (int x = 0; x < heads.length; x++) {
+                if (heads[x] != null) {
+                    return heads[x];
+                }
+            }
+            return null;
+        }
+
+
+        public boolean hasNext() {
+            if (prev == null) {
+                return first != null;
+            }
+            return prev.next != null;
+        }
+
+        public Interceptor<? extends Message> next() {
+            if (prev == null) {
+                if (first == null) {
+                    throw new NoSuchElementException();
+                }
+                prev = first;
+            } else {
+                if (prev.next == null) {
+                    throw new NoSuchElementException();
+                }
+                prev = prev.next;
+            }
+            return prev.interceptor;
+        }
+        public InterceptorHolder nextInterceptorHolder() {
+            if (prev == null) {
+                if (first == null) {
+                    throw new NoSuchElementException();
+                }
+                prev = first;
+            } else {
+                if (prev.next == null) {
+                    throw new NoSuchElementException();
+                }
+                prev = prev.next;
+            }
+            return prev;
+        }
+
+        public boolean hasPrevious() {
+            return prev != null;
+        }
+        public Interceptor<? extends Message> previous() {
+            if (prev == null) {
+                throw new NoSuchElementException();
+            }
+            InterceptorHolder tmp = prev;
+            prev = prev.prev;
+            return tmp.interceptor;
+        }
+
+        public int nextIndex() {
+            throw new UnsupportedOperationException();
+        }
+        public int previousIndex() {
+            throw new UnsupportedOperationException();
+        }
+        public void add(Interceptor<? extends Message> o) {
+            throw new UnsupportedOperationException();
+        }
+        public void set(Interceptor<? extends Message> o) {
+            throw new UnsupportedOperationException();
+        }
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+
+    static final class InterceptorHolder {
+        PhaseInterceptor<? extends Message> interceptor;
+        InterceptorHolder next;
+        InterceptorHolder prev;
+        int phaseIdx;
+
+        InterceptorHolder(PhaseInterceptor<? extends Message> i, int p) {
+            interceptor = i;
+            phaseIdx = p;
+        }
+        InterceptorHolder(InterceptorHolder p) {
+            interceptor = p.interceptor;
+            phaseIdx = p.phaseIdx;
+        }
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/service/factory/FactoryBeanListener.java b/transform/src/patch/java/org/apache/cxf/service/factory/FactoryBeanListener.java
new file mode 100644
index 0000000..687f211
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/service/factory/FactoryBeanListener.java
@@ -0,0 +1,145 @@
+/**
+ * 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.cxf.service.factory;
+
+/**
+ *
+ */
+public interface FactoryBeanListener {
+    enum Event {
+        /**
+         * Event fired at the very start of processing.  No parameters.  Useful
+         * for setting up any state the listener may need to maintain.
+         */
+        START_CREATE,
+
+        /**
+         * Event fired at the very end of processing.   One parameter is passed
+         * in which is the Service object that was created.
+         */
+        END_CREATE,
+
+        /**
+         * Called at the start of processing when it detects that the service
+         * is to be created based on a wsdl contract.   One String parameter
+         * of the URL of the wsdl.
+         */
+        CREATE_FROM_WSDL,
+
+        /**
+         * Called at the start of processing when it detects that the service
+         * is to be created based on a Java class.  One Class<?> parameter
+         * of the class that is being analyzed.
+         */
+        CREATE_FROM_CLASS,
+
+        /**
+         * Called after the wsdl is loaded/parsed.   Single parameter of the
+         * WSS4J Definition of the WSDL.
+         */
+        WSDL_LOADED,
+
+        /**
+         * Called after the Service is set into the Factory after which the getService()
+         * call will return a valid value.  One parameter of the Service object.
+         */
+        SERVICE_SET,
+
+
+        /**
+         * OperationInfo, Method
+         */
+        INTERFACE_OPERATION_BOUND,
+
+        /**
+         * OperationInfo, Method, MessageInfo
+         */
+        OPERATIONINFO_IN_MESSAGE_SET,
+        OPERATIONINFO_OUT_MESSAGE_SET,
+
+        /**
+         * OperationInfo, Class<? extends Throwable>, FaultInfo
+         */
+        OPERATIONINFO_FAULT,
+
+        /**
+         * InterfaceInfo, Class<?>
+         */
+        INTERFACE_CREATED,
+
+        /**
+         * DataBinding
+         */
+        DATABINDING_INITIALIZED,
+
+        /**
+         * EndpointInfo, Endpoint, Class
+         */
+        ENDPOINT_CREATED,
+
+        /**
+         * Server, targetObject, Class
+         */
+        PRE_SERVER_CREATE,
+
+        /**
+         * Server, targetObject, Class
+         */
+        SERVER_CREATED,
+
+        /**
+         * BindingInfo, BindingOperationInfo, Implementation Method
+         */
+        BINDING_OPERATION_CREATED,
+
+        /**
+         * BindingInfo
+         */
+        BINDING_CREATED,
+
+        /**
+         * Endpoint
+         */
+        PRE_CLIENT_CREATE,
+
+        /**
+         * Endpoint, Client
+         */
+        CLIENT_CREATED,
+
+        /**
+         * EndpointInfo, Endpoint, SEI Class, Class
+         */
+        ENDPOINT_SELECTED,
+
+        /**
+         * EndpointInfo
+         */
+        ENDPOINTINFO_CREATED,
+
+        /**
+         * Class[], InvokationHandler, Proxy
+         */
+        PROXY_CREATED,
+    }
+
+
+    void handleEvent(Event ev, AbstractServiceFactoryBean factory, Object ... args);
+}
diff --git a/transform/src/patch/java/org/apache/cxf/service/invoker/FactoryInvoker.java b/transform/src/patch/java/org/apache/cxf/service/invoker/FactoryInvoker.java
new file mode 100644
index 0000000..465046b
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/service/invoker/FactoryInvoker.java
@@ -0,0 +1,70 @@
+/**
+ * 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.cxf.service.invoker;
+
+import java.util.ResourceBundle;
+
+import org.apache.cxf.common.i18n.BundleUtils;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Exchange;
+
+/**
+ * This invoker implementation calls a Factory to create the service object.
+ *
+ */
+public class FactoryInvoker extends AbstractInvoker {
+    static final ResourceBundle BUNDLE = BundleUtils.getBundle(FactoryInvoker.class);
+
+    protected Factory factory;
+
+    /**
+     * Create a FactoryInvoker object.
+     *
+     * @param factory the factory used to create service object.
+     */
+    public FactoryInvoker(Factory factory) {
+        this.factory = factory;
+    }
+    public FactoryInvoker() {
+    }
+    public void setFactory(Factory f) {
+        this.factory = f;
+    }
+
+    public Object getServiceObject(Exchange ex) {
+        try {
+            return factory.create(ex);
+        } catch (Fault e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new Fault(new Message("CREATE_SERVICE_OBJECT_EXC", BUNDLE), e);
+        }
+    }
+
+    @Override
+    public void releaseServiceObject(final Exchange ex, Object obj) {
+        factory.release(ex, obj);
+    }
+
+    public boolean isSingletonFactory() {
+        return factory instanceof SingletonFactory;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/service/model/AbstractPropertiesHolder.java b/transform/src/patch/java/org/apache/cxf/service/model/AbstractPropertiesHolder.java
new file mode 100644
index 0000000..d80e02d
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/service/model/AbstractPropertiesHolder.java
@@ -0,0 +1,271 @@
+/**
+ * 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.cxf.service.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.xml.namespace.QName;
+
+public abstract class AbstractPropertiesHolder implements Extensible {
+    private AbstractPropertiesHolder delegate;
+    private boolean delegateProperties;
+
+    private AtomicReference<Map<String, Object>> propertyMap = new AtomicReference<>();
+    private AtomicReference<Object[]> extensors = new AtomicReference<>();
+    private Map<QName, Object> extensionAttributes;
+    private String documentation;
+
+
+    public final void setDelegate(AbstractPropertiesHolder p, boolean props) {
+        delegate = p;
+        delegateProperties = props;
+        if (delegate == null) {
+            return;
+        }
+        if (documentation != null) {
+            delegate.setDocumentation(documentation);
+            documentation = null;
+        }
+        if (extensionAttributes != null) {
+            delegate.setExtensionAttributes(extensionAttributes);
+            extensionAttributes = null;
+        }
+        if (extensors.get() != null) {
+            for (Object el : extensors.get()) {
+                delegate.addExtensor(el);
+            }
+            extensors.set(null);
+        }
+        if (delegateProperties && propertyMap.get() != null) {
+            for (Map.Entry<String, Object> p2 : propertyMap.get().entrySet()) {
+                delegate.setProperty(p2.getKey(), p2.getValue());
+            }
+            propertyMap.set(null);
+        }
+    }
+
+    public String getDocumentation() {
+        if (delegate != null) {
+            return delegate.getDocumentation();
+        }
+        return documentation;
+    }
+    public void setDocumentation(String s) {
+        if (delegate != null) {
+            delegate.setDocumentation(s);
+        } else {
+            documentation = s;
+        }
+    }
+    public Map<String, Object> getProperties() {
+        if (delegate != null && delegateProperties) {
+            return delegate.getProperties();
+        }
+        return propertyMap.get();
+    }
+    public Object getProperty(String name) {
+        if (delegate != null && delegateProperties) {
+            return delegate.getProperty(name);
+        }
+        if (null == propertyMap.get()) {
+            return null;
+        }
+        return propertyMap.get().get(name);
+    }
+    public Object removeProperty(String name) {
+        if (delegate != null && delegateProperties) {
+            delegate.removeProperty(name);
+        }
+        if (null == propertyMap.get()) {
+            return null;
+        }
+        return propertyMap.get().remove(name);
+    }
+
+    public <T> T getProperty(String name, Class<T> cls) {
+        return cls.cast(getProperty(name));
+    }
+    public boolean hasProperty(String name) {
+        if (delegate != null && delegateProperties) {
+            return delegate.hasProperty(name);
+        }
+        Map<String, Object> map = propertyMap.get();
+        if (map != null) {
+            return map.containsKey(name);
+        }
+        return false;
+    }
+
+    public void setProperty(String name, Object v) {
+        if (delegate != null && delegateProperties) {
+            delegate.setProperty(name, v);
+            return;
+        }
+        if (null == propertyMap.get()) {
+            propertyMap.compareAndSet(null, new ConcurrentHashMap<>(4, 0.75f, 2));
+        }
+        if (v == null) {
+            propertyMap.get().remove(name);
+        } else {
+            propertyMap.get().put(name, v);
+        }
+    }
+
+    public boolean containsExtensor(Object el) {
+        if (delegate != null) {
+            return delegate.containsExtensor(el);
+        }
+
+        Object[] exts = extensors.get();
+        if (exts != null) {
+            for (Object o : exts) {
+                if (o == el) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    public void addExtensor(Object el) {
+        if (delegate != null) {
+            delegate.addExtensor(el);
+            return;
+        }
+        Object[] exts = extensors.get();
+        Object[] exts2;
+        if (exts == null) {
+            exts2 = new Object[1];
+        } else {
+            exts2 = new Object[exts.length + 1];
+            System.arraycopy(exts, 0, exts2, 0, exts.length);
+        }
+        exts2[exts2.length - 1] = el;
+        if (!extensors.compareAndSet(exts, exts2)) {
+            //keep trying
+            addExtensor(el);
+        }
+    }
+
+    public <T> T getExtensor(Class<T> cls) {
+        if (delegate != null) {
+            return delegate.getExtensor(cls);
+        }
+        Object[] exts = extensors.get();
+        if (exts == null) {
+            return null;
+        }
+        for (int x = 0; x < exts.length; x++) {
+            if (cls.isInstance(exts[x])) {
+                return cls.cast(exts[x]);
+            }
+        }
+        return null;
+    }
+    public <T> List<T> getExtensors(Class<T> cls) {
+        if (delegate != null) {
+            return delegate.getExtensors(cls);
+        }
+
+        Object[] exts = extensors.get();
+        if (exts == null) {
+            return null;
+        }
+        List<T> list = new ArrayList<>(exts.length);
+        for (int x = 0; x < exts.length; x++) {
+            if (cls.isInstance(exts[x])) {
+                list.add(cls.cast(exts[x]));
+            }
+        }
+        return list;
+    }
+
+    public AtomicReference<Object[]> getExtensors() {
+        if (delegate != null) {
+            return delegate.getExtensors();
+        }
+        return extensors;
+    }
+
+
+    public Object getExtensionAttribute(QName name) {
+        if (delegate != null) {
+            return delegate.getExtensionAttribute(name);
+        }
+        return null == extensionAttributes ? null : extensionAttributes.get(name);
+    }
+
+    public Map<QName, Object> getExtensionAttributes() {
+        if (delegate != null) {
+            return delegate.getExtensionAttributes();
+        }
+        return extensionAttributes;
+    }
+
+    public void addExtensionAttribute(QName name, Object attr) {
+        if (delegate != null) {
+            delegate.addExtensionAttribute(name, attr);
+            return;
+        }
+        if (null == extensionAttributes) {
+            extensionAttributes = new HashMap<>();
+        }
+        extensionAttributes.put(name, attr);
+    }
+
+    public void setExtensionAttributes(Map<QName, Object> attrs) {
+        if (delegate != null) {
+            delegate.setExtensionAttributes(attrs);
+            return;
+        }
+        extensionAttributes = attrs;
+    }
+
+    /**
+     * Lookup a configuration value. This may be found in the properties holder supplied
+     * (i.e. an EndpointInfo or ServiceInfo), or it may be a property on the Bus itself.
+     * If no value is found, the defaultValue is returned.
+     *
+     * @param defaultValue the default value
+     * @param type the extensor type
+     * @return the configuration value or the default
+     */
+    public <T> T getTraversedExtensor(T defaultValue, Class<T> type) {
+        if (delegate != null) {
+            return delegate.getTraversedExtensor(defaultValue, type);
+        }
+        T extensor = getExtensor(type);
+        if (extensor == null) {
+            return defaultValue;
+        }
+        return extensor;
+    }
+
+
+    protected static final boolean equals(Object o1, Object o2) {
+        return Objects.equals(o1, o2);
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/service/model/FaultInfo.java b/transform/src/patch/java/org/apache/cxf/service/model/FaultInfo.java
new file mode 100644
index 0000000..f2f240f
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/service/model/FaultInfo.java
@@ -0,0 +1,61 @@
+/**
+ * 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.cxf.service.model;
+
+import javax.xml.namespace.QName;
+
+public class FaultInfo extends AbstractMessageContainer {
+    private QName faultName;
+
+    public FaultInfo(QName fname, QName mname, OperationInfo info) {
+        super(info, mname);
+        faultName = fname;
+    }
+
+    public QName getFaultName() {
+        return faultName;
+    }
+    public void setFaultName(QName fname) {
+        faultName = fname;
+    }
+
+
+
+    @Override
+    public int hashCode() {
+        return faultName == null ? -1 : faultName.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (!(o instanceof FaultInfo)) {
+            return false;
+        }
+        FaultInfo oi = (FaultInfo)o;
+        return equals(faultName, oi.faultName)
+            && super.equals(o);
+    }
+
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/service/model/InterfaceInfo.java b/transform/src/patch/java/org/apache/cxf/service/model/InterfaceInfo.java
new file mode 100644
index 0000000..a5c3f26
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/service/model/InterfaceInfo.java
@@ -0,0 +1,124 @@
+/**
+ * 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.cxf.service.model;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+
+public class InterfaceInfo extends AbstractDescriptionElement implements NamedItem {
+    private static final Logger LOG = LogUtils.getL7dLogger(InterfaceInfo.class);
+
+    QName name;
+    ServiceInfo service;
+
+    Map<QName, OperationInfo> operations = new ConcurrentHashMap<>(4, 0.75f, 2);
+
+    public InterfaceInfo(ServiceInfo info, QName q) {
+        name = q;
+        service = info;
+        info.setInterface(this);
+    }
+    public DescriptionInfo getDescription() {
+        if (service == null) {
+            return null;
+        }
+        return service.getDescription();
+    }
+
+    public ServiceInfo getService() {
+        return service;
+    }
+
+    public void setName(QName n) {
+        name = n;
+    }
+    public QName getName() {
+        return name;
+    }
+
+
+    /**
+     * Adds an operation to this service.
+     *
+     * @param oname the qualified name of the operation.
+     * @return the operation.
+     */
+    public OperationInfo addOperation(QName oname) {
+        if (oname == null) {
+            throw new NullPointerException(
+                new Message("OPERATION.NAME.NOT.NULL", LOG).toString());
+        }
+        if (operations.containsKey(oname)) {
+            throw new IllegalArgumentException(
+                new Message("DUPLICATED.OPERATION.NAME", LOG, oname).toString());
+        }
+
+        OperationInfo operation = new OperationInfo(this, oname);
+        addOperation(operation);
+        return operation;
+    }
+
+    /**
+     * Adds an operation to this service.
+     *
+     * @param operation the operation.
+     */
+    void addOperation(OperationInfo operation) {
+        operations.put(operation.getName(), operation);
+    }
+
+    /**
+     * Removes an operation from this service.
+     *
+     * @param operation the operation.
+     */
+    public void removeOperation(OperationInfo operation) {
+        operations.remove(operation.getName());
+    }
+
+    /**
+     * Returns the operation info with the given name, if found.
+     *
+     * @param oname the name.
+     * @return the operation; or <code>null</code> if not found.
+     */
+    public OperationInfo getOperation(QName oname) {
+        return operations.get(oname);
+    }
+
+    /**
+     * Returns all operations for this service.
+     *
+     * @return all operations.
+     */
+    public Collection<OperationInfo> getOperations() {
+        return Collections.unmodifiableCollection(operations.values());
+    }
+
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/service/model/OperationInfo.java b/transform/src/patch/java/org/apache/cxf/service/model/OperationInfo.java
new file mode 100644
index 0000000..d5fe4d3
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/service/model/OperationInfo.java
@@ -0,0 +1,242 @@
+/**
+ * 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.cxf.service.model;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+
+public class OperationInfo extends AbstractPropertiesHolder implements NamedItem {
+    private static final Logger LOG = LogUtils.getL7dLogger(OperationInfo.class);
+    InterfaceInfo intf;
+    QName opName;
+    String inName;
+    MessageInfo inputMessage;
+    String outName;
+    MessageInfo outputMessage;
+    Map<QName, FaultInfo> faults;
+    OperationInfo unwrappedOperation;
+    List<String> parameterOrdering;
+
+    public OperationInfo() {
+    }
+
+    OperationInfo(InterfaceInfo it, QName n) {
+        intf = it;
+        setName(n);
+    }
+    OperationInfo(OperationInfo op) {
+        intf = op.getInterface();
+        setName(op.getName());
+    }
+
+    /**
+     * Returns the name of the Operation.
+     * @return the name of the Operation
+     */
+    public QName getName() {
+        return opName;
+    }
+    /**
+     * Sets the name of the operation.
+     * @param name the new name of the operation
+     */
+    public final void setName(QName name) {
+        if (name == null) {
+            throw new NullPointerException("Operation Name cannot be null.");
+        }
+        opName = name;
+    }
+    public InterfaceInfo getInterface() {
+        return intf;
+    }
+
+
+    public MessageInfo createMessage(QName nm, MessageInfo.Type type) {
+        return new MessageInfo(this, type, nm);
+    }
+
+    public MessageInfo getOutput() {
+        return outputMessage;
+    }
+    public String getOutputName() {
+        return outName;
+    }
+    public void setOutput(String nm, MessageInfo out) {
+        outName = nm;
+        outputMessage = out;
+        if (unwrappedOperation != null && unwrappedOperation.getOutput() != null) {
+            unwrappedOperation.getOutput().setDelegate(out, false);
+        }
+    }
+    public boolean hasOutput() {
+        return outputMessage != null;
+    }
+
+    public MessageInfo getInput() {
+        return inputMessage;
+    }
+    public String getInputName() {
+        return inName;
+    }
+    public void setInput(String nm, MessageInfo in) {
+        inName = nm;
+        inputMessage = in;
+        if (unwrappedOperation != null && unwrappedOperation.getInput() != null) {
+            unwrappedOperation.getInput().setDelegate(in, false);
+        }
+    }
+    public boolean hasInput() {
+        return inputMessage != null;
+    }
+
+    public boolean isOneWay() {
+        return inputMessage != null && outputMessage == null;
+    }
+
+    public boolean isUnwrappedCapable() {
+        return unwrappedOperation != null;
+    }
+
+    public OperationInfo getUnwrappedOperation() {
+        return unwrappedOperation;
+    }
+    public void setUnwrappedOperation(OperationInfo op) {
+        unwrappedOperation = op;
+    }
+    public boolean isUnwrapped() {
+        return false;
+    }
+
+
+    /**
+     * Adds an fault to this operation.
+     *
+     * @param name the fault name.
+     */
+    public FaultInfo addFault(QName name, QName message) {
+        if (name == null) {
+            throw new NullPointerException(new Message("FAULT.NAME.NOT.NULL", LOG).toString());
+        }
+        if (faults != null && faults.containsKey(name)) {
+            throw new IllegalArgumentException(
+                new Message("DUPLICATED.FAULT.NAME", LOG, name).toString());
+        }
+        FaultInfo fault = new FaultInfo(name, message, this);
+        addFault(fault);
+        return fault;
+    }
+
+    /**
+     * Adds a fault to this operation.
+     *
+     * @param fault the fault.
+     */
+    public synchronized void addFault(FaultInfo fault) {
+        if (faults == null) {
+            faults = new ConcurrentHashMap<>(4, 0.75f, 2);
+        }
+        faults.put(fault.getFaultName(), fault);
+    }
+
+    /**
+     * Removes a fault from this operation.
+     *
+     * @param name the qualified fault name.
+     */
+    public void removeFault(QName name) {
+        if (faults != null) {
+            faults.remove(name);
+        }
+    }
+
+    /**
+     * Returns the fault with the given name, if found.
+     *
+     * @param name the name.
+     * @return the fault; or <code>null</code> if not found.
+     */
+    public FaultInfo getFault(QName name) {
+        if (faults != null) {
+            return faults.get(name);
+        }
+        return null;
+    }
+
+    public boolean hasFaults() {
+        return faults != null && !faults.isEmpty();
+    }
+
+    /**
+     * Returns all faults for this operation.
+     *
+     * @return all faults.
+     */
+    public Collection<FaultInfo> getFaults() {
+        if (faults == null) {
+            return Collections.emptyList();
+        }
+        return Collections.unmodifiableCollection(faults.values());
+    }
+
+    public void setParameterOrdering(List<String> o) {
+        this.parameterOrdering = o;
+    }
+
+    public List<String> getParameterOrdering() {
+        return parameterOrdering;
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder("[OperationInfo: ")
+            .append(opName)
+            .append(']').toString();
+    }
+
+    public int hashCode() {
+        return opName == null ? -1 : opName.hashCode();
+    }
+
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (!(o instanceof OperationInfo)) {
+            return false;
+        }
+        OperationInfo oi = (OperationInfo)o;
+        return equals(opName, oi.opName)
+            && equals(inputMessage, oi.inputMessage)
+            && equals(outputMessage, oi.outputMessage)
+            && equals(faults, oi.faults)
+            && equals(intf.getName(), oi.intf.getName());
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/service/model/UnwrappedOperationInfo.java b/transform/src/patch/java/org/apache/cxf/service/model/UnwrappedOperationInfo.java
new file mode 100644
index 0000000..31ed72c
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/service/model/UnwrappedOperationInfo.java
@@ -0,0 +1,72 @@
+/**
+ * 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.cxf.service.model;
+
+import java.util.Collection;
+
+import javax.xml.namespace.QName;
+
+public class UnwrappedOperationInfo extends OperationInfo {
+    OperationInfo wrappedOp;
+
+    public UnwrappedOperationInfo(OperationInfo op) {
+        super(op);
+        wrappedOp = op;
+        setDelegate(wrappedOp, true);
+    }
+
+    public OperationInfo getWrappedOperation() {
+        return wrappedOp;
+    }
+
+    @Override
+    public boolean isUnwrapped() {
+        return true;
+    }
+
+    @Override
+    public FaultInfo addFault(QName name, QName message) {
+        return wrappedOp.addFault(name, message);
+    }
+
+    @Override
+    public FaultInfo getFault(QName name) {
+        return wrappedOp.getFault(name);
+    }
+
+    @Override
+    public Collection<FaultInfo> getFaults() {
+        return wrappedOp.getFaults();
+    }
+
+
+    @Override
+    public void setOutput(String nm, MessageInfo out) {
+        super.setOutput(nm, out);
+        out.setDelegate(wrappedOp.getOutput(), false);
+    }
+
+    @Override
+    public void setInput(String nm, MessageInfo in) {
+        super.setInput(nm, in);
+        in.setDelegate(wrappedOp.getInput(), false);
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/staxutils/StaxUtils.java b/transform/src/patch/java/org/apache/cxf/staxutils/StaxUtils.java
new file mode 100644
index 0000000..440968c
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/staxutils/StaxUtils.java
@@ -0,0 +1,2222 @@
+/**
+ * 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.cxf.staxutils;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.Location;
+import javax.xml.stream.StreamFilter;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.DTD;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.StartDocument;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stax.StAXSource;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.w3c.dom.UserDataHandler;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.common.util.SystemPropertyAction;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.message.Message;
+
+public final class StaxUtils {
+    // System properties for defaults, but also contextual properties usable
+    // for StaxInInterceptor
+    public static final String MAX_CHILD_ELEMENTS =
+        "org.apache.cxf.stax.maxChildElements";
+    public static final String MAX_ELEMENT_DEPTH =
+        "org.apache.cxf.stax.maxElementDepth";
+    public static final String MAX_ATTRIBUTE_COUNT =
+        "org.apache.cxf.stax.maxAttributeCount";
+    public static final String MAX_ATTRIBUTE_SIZE =
+        "org.apache.cxf.stax.maxAttributeSize";
+    public static final String MAX_TEXT_LENGTH =
+        "org.apache.cxf.stax.maxTextLength";
+    public static final String MIN_TEXT_SEGMENT =
+        "org.apache.cxf.stax.minTextSegment";
+    public static final String MAX_ELEMENT_COUNT =
+        "org.apache.cxf.stax.maxElementCount";
+    public static final String MAX_XML_CHARACTERS =
+        "org.apache.cxf.stax.maxXMLCharacters";
+
+    public static final String ALLOW_INSECURE_PARSER =
+        "org.apache.cxf.stax.allowInsecureParser";
+
+    private static final String INNER_ELEMENT_COUNT_SYSTEM_PROP =
+        "org.apache.cxf.staxutils.innerElementCountThreshold";
+    private static final String INNER_ELEMENT_LEVEL_SYSTEM_PROP =
+        "org.apache.cxf.staxutils.innerElementLevelThreshold";
+    private static final String AUTO_CLOSE_INPUT_SOURCE_PROP =
+        "org.apache.cxf.staxutils.autoCloseInputSource";
+
+    private static final Logger LOG = LogUtils.getL7dLogger(StaxUtils.class);
+
+    private static final Queue<XMLInputFactory> NS_AWARE_INPUT_FACTORY_POOL;
+    private static final XMLInputFactory SAFE_INPUT_FACTORY;
+    private static final Queue<XMLOutputFactory> OUTPUT_FACTORY_POOL;
+    private static final XMLOutputFactory SAFE_OUTPUT_FACTORY;
+
+    private static final String XML_NS = "http://www.w3.org/2000/xmlns/";
+    private static final String[] DEF_PREFIXES = new String[] {
+        "ns1".intern(), "ns2".intern(), "ns3".intern(),
+        "ns4".intern(), "ns5".intern(), "ns6".intern(),
+        "ns7".intern(), "ns8".intern(), "ns9".intern()
+    };
+
+    private static final int MAX_ATTR_COUNT_VAL =
+            getInteger(MAX_ATTRIBUTE_COUNT, 500);
+    private static final int MAX_ATTR_SIZE_VAL =
+            getInteger(MAX_ATTRIBUTE_SIZE, 64 * 1024); //64K per attribute, likely just "list" will hit
+    private static final int MAX_TEXT_LENGTH_VAL =
+            getInteger(MAX_TEXT_LENGTH, 128 * 1024 * 1024);  //128M - more than this should DEFINITELY use MTOM
+    private static final int MIN_TEXT_SEGMENT_VAL =
+            getInteger(MIN_TEXT_SEGMENT, 64); // Same default as woodstox
+    private static final long MAX_ELEMENT_COUNT_VAL =
+            getLong(MAX_ELEMENT_COUNT, Long.MAX_VALUE);
+    private static final long MAX_XML_CHARS_VAL =
+            getLong(MAX_XML_CHARACTERS, Long.MAX_VALUE);
+    private static final int PARSER_POOL_SIZE_VAL =
+            getInteger("org.apache.cxf.staxutils.pool-size", 20);
+    private static final boolean ALLOW_INSECURE_PARSER_VAL;
+    private static final boolean AUTO_CLOSE_INPUT_SOURCE;
+
+    // Here we check old names first and then new names for the threshold properties
+    private static final int MAX_ELEMENT_DEPTH_VAL =
+            getInteger(MAX_ELEMENT_DEPTH, getInteger(INNER_ELEMENT_LEVEL_SYSTEM_PROP, 100));
+    private static final int MAX_CHILD_ELEMENTS_VAL =
+            getInteger(MAX_CHILD_ELEMENTS, getInteger(INNER_ELEMENT_COUNT_SYSTEM_PROP, 50000));
+
+    // Variables from Woodstox
+    private static final String P_MAX_ATTRIBUTES_PER_ELEMENT = "com.ctc.wstx.maxAttributesPerElement";
+    private static final String P_MAX_ATTRIBUTE_SIZE = "com.ctc.wstx.maxAttributeSize";
+    private static final String P_MAX_TEXT_LENGTH = "com.ctc.wstx.maxTextLength";
+    private static final String P_MAX_ELEMENT_COUNT = "com.ctc.wstx.maxElementCount";
+    private static final String P_MAX_CHARACTERS = "com.ctc.wstx.maxCharacters";
+    private static final String P_MAX_ELEMENT_DEPTH = "com.ctc.wstx.maxElementDepth";
+    private static final String P_MAX_CHILDREN_PER_ELEMENT = "com.ctc.wstx.maxChildrenPerElement";
+    private static final String P_MIN_TEXT_SEGMENT = "com.ctc.wstx.minTextSegment";
+
+
+    static {
+        NS_AWARE_INPUT_FACTORY_POOL = new ArrayBlockingQueue<>(PARSER_POOL_SIZE_VAL);
+        OUTPUT_FACTORY_POOL = new ArrayBlockingQueue<>(PARSER_POOL_SIZE_VAL);
+
+        String allowInsecureParser = SystemPropertyAction.getPropertyOrNull(ALLOW_INSECURE_PARSER);
+        if (!StringUtils.isEmpty(allowInsecureParser)) {
+            ALLOW_INSECURE_PARSER_VAL = "1".equals(allowInsecureParser) || Boolean.parseBoolean(allowInsecureParser);
+        } else {
+            ALLOW_INSECURE_PARSER_VAL = false;
+        }
+        
+        String autoCloseInputSource = SystemPropertyAction.getPropertyOrNull(AUTO_CLOSE_INPUT_SOURCE_PROP);
+        if (!StringUtils.isEmpty(autoCloseInputSource)) {
+            AUTO_CLOSE_INPUT_SOURCE = "1".equals(autoCloseInputSource) || Boolean.parseBoolean(autoCloseInputSource);
+        } else {
+            AUTO_CLOSE_INPUT_SOURCE = false; /* set 'false' by default */
+        }
+
+        XMLInputFactory xif = null;
+        try {
+            xif = createXMLInputFactory(true);
+            String xifClassName = xif.getClass().getName();
+            if (!xifClassName.contains("ctc.wstx") && !xifClassName.contains("xml.xlxp")
+                    && !xifClassName.contains("xml.xlxp2") && !xifClassName.contains("bea.core")) {
+                xif = null;
+            }
+        } catch (Throwable t) {
+            //ignore, can always drop down to the pooled factories
+        }
+        SAFE_INPUT_FACTORY = xif;
+
+        XMLOutputFactory xof = null;
+        try {
+            xof = XMLOutputFactory.newInstance();
+            String xofClassName = xof.getClass().getName();
+            if (!xofClassName.contains("ctc.wstx") && !xofClassName.contains("xml.xlxp")
+                && !xofClassName.contains("xml.xlxp2") && !xofClassName.contains("bea.core")) {
+                xof = null;
+            }
+        } catch (Throwable t) {
+            //ignore, can always drop down to the pooled factories
+        }
+        SAFE_OUTPUT_FACTORY = xof;
+
+    }
+
+    private StaxUtils() {
+    }
+    private static int getInteger(String prop, int def) {
+        try {
+            String s = SystemPropertyAction.getPropertyOrNull(prop);
+            if (StringUtils.isEmpty(s)) {
+                return def;
+            }
+            int i = Integer.parseInt(s);
+            if (i < 0) {
+                i = def;
+            }
+            return i;
+        } catch (Throwable t) {
+            //ignore
+        }
+        return def;
+    }
+    private static long getLong(String prop, long def) {
+        try {
+            String s = SystemPropertyAction.getPropertyOrNull(prop);
+            if (StringUtils.isEmpty(s)) {
+                return def;
+            }
+            long i = Long.parseLong(s);
+            if (i < 0) {
+                i = def;
+            }
+            return i;
+        } catch (Throwable t) {
+            //ignore
+        }
+        return def;
+    }
+
+    /**
+     * Return a cached, namespace-aware, factory.
+     */
+    private static XMLInputFactory getXMLInputFactory() {
+        if (SAFE_INPUT_FACTORY != null) {
+            return SAFE_INPUT_FACTORY;
+        }
+        XMLInputFactory f = NS_AWARE_INPUT_FACTORY_POOL.poll();
+        if (f == null) {
+            f = createXMLInputFactory(true);
+        }
+        return f;
+    }
+
+    private static void returnXMLInputFactory(XMLInputFactory factory) {
+        if (SAFE_INPUT_FACTORY != factory) {
+            NS_AWARE_INPUT_FACTORY_POOL.offer(factory);
+        }
+    }
+
+    private static XMLOutputFactory getXMLOutputFactory() {
+        if (SAFE_OUTPUT_FACTORY != null) {
+            return SAFE_OUTPUT_FACTORY;
+        }
+        XMLOutputFactory f = OUTPUT_FACTORY_POOL.poll();
+        if (f == null) {
+            f = XMLOutputFactory.newInstance();
+        }
+        return f;
+    }
+
+    private static void returnXMLOutputFactory(XMLOutputFactory factory) {
+        if (SAFE_OUTPUT_FACTORY != factory) {
+            OUTPUT_FACTORY_POOL.offer(factory);
+        }
+    }
+
+    /**
+     * Return a new factory so that the caller can set sticky parameters.
+     * @param nsAware
+     * @throws XMLStreamException
+     */
+    public static XMLInputFactory createXMLInputFactory(boolean nsAware) {
+        XMLInputFactory factory = null;
+        try {
+            factory = XMLInputFactory.newInstance();
+        } catch (Throwable t) {
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.log(Level.FINE, "XMLInputFactory.newInstance() failed with: ", t);
+            }
+        }
+        if (factory == null || !setRestrictionProperties(factory)) {
+            try {
+                factory = createWoodstoxFactory();
+            } catch (Throwable t) {
+                if (LOG.isLoggable(Level.FINE)) {
+                    LOG.log(Level.FINE, "Cannot create Woodstox XMLInputFactory: ", t);
+                }
+            }
+
+            if (factory == null) {
+                throw new RuntimeException("Failed to create XMLInputFactory.");
+            }
+
+            if (!setRestrictionProperties(factory)) {
+                if (ALLOW_INSECURE_PARSER_VAL) {
+                    LOG.log(Level.WARNING, "INSECURE_PARSER_DETECTED", factory.getClass().getName());
+                } else {
+                    throw new RuntimeException("Cannot create a secure XMLInputFactory, "
+                        + "you should either add woodstox or set " + ALLOW_INSECURE_PARSER
+                        + " system property to true if an unsafe mode is acceptable.");
+                }
+            }
+        }
+        setProperty(factory, XMLInputFactory.IS_NAMESPACE_AWARE, nsAware);
+        setProperty(factory, XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
+        setProperty(factory, XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE);
+        setProperty(factory, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
+        factory.setXMLResolver(new XMLResolver() {
+            public Object resolveEntity(String publicID, String systemID,
+                                        String baseURI, String namespace)
+                throws XMLStreamException {
+                throw new XMLStreamException("Reading external entities is disabled");
+            }
+        });
+
+        return factory;
+    }
+
+    private static XMLInputFactory createWoodstoxFactory() {
+        return WoodstoxHelper.createInputFactory();
+    }
+
+    public static XMLEventFactory createWoodstoxEventFactory() {
+        return WoodstoxHelper.createEventFactory();
+    }
+
+    private static boolean setRestrictionProperties(XMLInputFactory factory) {
+        //For now, we can only support Woodstox 4.2.x and newer as none of the other
+        //stax parsers support these settings
+        final boolean wstxMaxs = setProperty(factory, P_MAX_ATTRIBUTES_PER_ELEMENT, MAX_ATTR_COUNT_VAL)
+                    && setProperty(factory, P_MAX_ATTRIBUTE_SIZE, MAX_ATTR_SIZE_VAL)
+                    && setProperty(factory, P_MAX_CHILDREN_PER_ELEMENT, MAX_CHILD_ELEMENTS_VAL)
+                    && setProperty(factory, P_MAX_ELEMENT_COUNT, MAX_ELEMENT_COUNT_VAL)
+                    && setProperty(factory, P_MAX_ELEMENT_DEPTH, MAX_ELEMENT_DEPTH_VAL)
+                    && setProperty(factory, P_MAX_CHARACTERS, MAX_XML_CHARS_VAL)
+                    && setProperty(factory, P_MAX_TEXT_LENGTH, MAX_TEXT_LENGTH_VAL);
+        return wstxMaxs
+            && setProperty(factory, P_MIN_TEXT_SEGMENT, MIN_TEXT_SEGMENT_VAL);
+    }
+
+    private static boolean setProperty(XMLInputFactory f, String p, Object o) {
+        try {
+            f.setProperty(p,  o);
+            return true;
+        } catch (Throwable t) {
+            //ignore
+        }
+        return false;
+    }
+
+
+
+    public static XMLStreamWriter createXMLStreamWriter(Writer out) {
+        XMLOutputFactory factory = getXMLOutputFactory();
+        try {
+            return factory.createXMLStreamWriter(out);
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Cant' create XMLStreamWriter", e);
+        } finally {
+            returnXMLOutputFactory(factory);
+        }
+    }
+
+    public static XMLStreamWriter createXMLStreamWriter(OutputStream out) {
+        return createXMLStreamWriter(out, null);
+    }
+
+    public static XMLStreamWriter createXMLStreamWriter(OutputStream out, String encoding) {
+        XMLOutputFactory factory = getXMLOutputFactory();
+        try {
+            return factory.createXMLStreamWriter(out, encoding != null ? encoding : StandardCharsets.UTF_8.name());
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Cant' create XMLStreamWriter", e);
+        } finally {
+            returnXMLOutputFactory(factory);
+        }
+    }
+
+    public static XMLStreamWriter createXMLStreamWriter(Result r) {
+        if (r instanceof DOMResult) {
+            //use our own DOM writer to avoid issues with Sun's
+            //version that doesn't support getNamespaceContext
+            DOMResult dr = (DOMResult)r;
+            Node nd = dr.getNode();
+            if (nd instanceof Document) {
+                return new W3CDOMStreamWriter((Document)nd);
+            } else if (nd instanceof Element) {
+                return new W3CDOMStreamWriter((Element)nd);
+            } else if (nd instanceof DocumentFragment) {
+                return new W3CDOMStreamWriter((DocumentFragment)nd);
+            }
+        }
+        XMLOutputFactory factory = getXMLOutputFactory();
+        try {
+            return factory.createXMLStreamWriter(r);
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Cant' create XMLStreamWriter", e);
+        } finally {
+            returnXMLOutputFactory(factory);
+        }
+    }
+
+    public static XMLStreamReader createFilteredReader(XMLStreamReader reader, StreamFilter filter) {
+        XMLInputFactory factory = getXMLInputFactory();
+        try {
+            return factory.createFilteredReader(reader, filter);
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Cant' create XMLStreamReader", e);
+        } finally {
+            returnXMLInputFactory(factory);
+        }
+    }
+
+
+    public static void nextEvent(XMLStreamReader dr) {
+        try {
+            dr.next();
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Couldn't parse stream.", e);
+        }
+    }
+
+    public static boolean toNextText(DepthXMLStreamReader reader) {
+        if (reader.getEventType() == XMLStreamConstants.CHARACTERS) {
+            return true;
+        }
+
+        try {
+            int depth = reader.getDepth();
+            int event = reader.getEventType();
+            while (reader.getDepth() >= depth && reader.hasNext()) {
+                if (event == XMLStreamConstants.CHARACTERS && reader.getDepth() == depth + 1) {
+                    return true;
+                }
+                event = reader.next();
+            }
+            return false;
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Couldn't parse stream.", e);
+        }
+    }
+    public static boolean toNextTag(XMLStreamReader reader) {
+        try {
+            // advance to first tag.
+            int x = reader.getEventType();
+            while (x != XMLStreamConstants.START_ELEMENT
+                && x != XMLStreamConstants.END_ELEMENT
+                && reader.hasNext()) {
+                x = reader.next();
+            }
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Couldn't parse stream.", e);
+        }
+        return true;
+    }
+
+    public static boolean toNextTag(DepthXMLStreamReader reader, QName endTag) {
+        try {
+            int depth = reader.getDepth();
+            int event = reader.getEventType();
+            while (reader.getDepth() >= depth && reader.hasNext()) {
+                if (event == XMLStreamConstants.START_ELEMENT && reader.getName().equals(endTag)
+                    && reader.getDepth() == depth + 1) {
+                    return true;
+                }
+                event = reader.next();
+            }
+            return false;
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Couldn't parse stream.", e);
+        }
+    }
+
+    public static void writeStartElement(XMLStreamWriter writer, String prefix, String name, String namespace)
+        throws XMLStreamException {
+        if (prefix == null) {
+            prefix = "";
+        }
+
+        if (!namespace.isEmpty()) {
+            writer.writeStartElement(prefix, name, namespace);
+            if (!prefix.isEmpty()) {
+                writer.writeNamespace(prefix, namespace);
+                writer.setPrefix(prefix, namespace);
+            } else {
+                writer.writeDefaultNamespace(namespace);
+                writer.setDefaultNamespace(namespace);
+            }
+        } else {
+            writer.writeStartElement(name);
+            writer.writeDefaultNamespace("");
+            writer.setDefaultNamespace("");
+        }
+    }
+
+    /**
+     * Returns true if currently at the start of an element, otherwise move
+     * forwards to the next element start and return true, otherwise false is
+     * returned if the end of the stream is reached.
+     */
+    public static boolean skipToStartOfElement(XMLStreamReader in) throws XMLStreamException {
+        for (int code = in.getEventType(); code != XMLStreamConstants.END_DOCUMENT; code = in.next()) {
+            if (code == XMLStreamConstants.START_ELEMENT) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean toNextElement(DepthXMLStreamReader dr) {
+        if (dr.getEventType() == XMLStreamConstants.START_ELEMENT) {
+            return true;
+        }
+        if (dr.getEventType() == XMLStreamConstants.END_ELEMENT) {
+            return false;
+        }
+        try {
+            int depth = dr.getDepth();
+
+            for (int event = dr.getEventType(); dr.getDepth() >= depth && dr.hasNext(); event = dr.next()) {
+                if (event == XMLStreamConstants.START_ELEMENT && dr.getDepth() == depth + 1) {
+                    return true;
+                } else if (event == XMLStreamConstants.END_ELEMENT) {
+                    depth--;
+                }
+            }
+
+            return false;
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Couldn't parse stream.", e);
+        }
+    }
+
+    public static boolean skipToStartOfElement(DepthXMLStreamReader in) throws XMLStreamException {
+        for (int code = in.getEventType(); code != XMLStreamConstants.END_DOCUMENT; code = in.next()) {
+            if (code == XMLStreamConstants.START_ELEMENT) {
+                return true;
+            }
+        }
+        return false;
+    }
+    public static void copy(Source source, OutputStream os) throws XMLStreamException {
+        XMLStreamWriter writer = createXMLStreamWriter(os);
+        try {
+            copy(source, writer);
+        } finally {
+            try {
+                writer.flush();
+            } catch (XMLStreamException ex) {
+                //ignore
+            }
+            StaxUtils.close(writer);
+        }
+    }
+    public static void copy(Source source, XMLStreamWriter writer) throws XMLStreamException {
+        if (source instanceof StaxSource) {
+            StaxSource ss = (StaxSource)source;
+            if (ss.getXMLStreamReader() == null) {
+                return;
+            }
+        } else if (source instanceof StAXSource) {
+            StAXSource ss = (StAXSource)source;
+            if (ss.getXMLStreamReader() == null) {
+                return;
+            }
+        } else if (source instanceof SAXSource) {
+            SAXSource ss = (SAXSource)source;
+            InputSource src = ss.getInputSource();
+            if (src == null || (src.getSystemId() == null && src.getPublicId() == null)) {
+                if (ss.getXMLReader() != null) {
+                    //OK - reader is OK.  We'll use that out
+                    StreamWriterContentHandler ch = new StreamWriterContentHandler(writer);
+                    XMLReader reader = ((SAXSource)source).getXMLReader();
+                    reader.setContentHandler(ch);
+                    try {
+                        try {
+                            reader.setFeature("http://xml.org/sax/features/namespaces", true);
+                        } catch (Throwable t) {
+                            //ignore
+                        }
+                        try {
+                            reader.setProperty("http://xml.org/sax/properties/lexical-handler", ch);
+                        } catch (Throwable t) {
+                            //ignore
+                        }
+                        reader.parse(((SAXSource)source).getInputSource());
+                        return;
+                    } catch (Exception e) {
+                        throw new XMLStreamException(e.getMessage(), e);
+                    }
+                } else if (ss.getInputSource() == null) {
+                    //nothing to copy, just return
+                    return;
+                }
+            }
+
+        } else if (source instanceof StreamSource) {
+            StreamSource ss = (StreamSource)source;
+            if (ss.getInputStream() == null
+                && ss.getReader() == null
+                && ss.getSystemId() == null) {
+                //nothing to copy, just return
+                return;
+            }
+        }
+        XMLStreamReader reader = createXMLStreamReader(source);
+        copy(reader, writer);
+        reader.close();
+    }
+
+    public static Document copy(Document doc)
+        throws XMLStreamException, ParserConfigurationException {
+
+        XMLStreamReader reader = createXMLStreamReader(doc);
+        W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
+        copy(reader, writer);
+        Document d = writer.getDocument();
+        try {
+            d.setDocumentURI(doc.getDocumentURI());
+        } catch (Exception ex) {
+            //ignore - probably not DOM level 3
+        }
+        return d;
+    }
+    public static void copy(Document doc, XMLStreamWriter writer) throws XMLStreamException {
+        XMLStreamReader reader = createXMLStreamReader(doc);
+        copy(reader, writer);
+    }
+    public static void copy(Element node, XMLStreamWriter writer) throws XMLStreamException {
+        XMLStreamReader reader = createXMLStreamReader(node);
+        copy(reader, writer);
+    }
+
+    public static void copy(XMLStreamReader reader, OutputStream os)
+        throws XMLStreamException {
+        XMLStreamWriter xsw = StaxUtils.createXMLStreamWriter(os);
+        StaxUtils.copy(reader, xsw);
+        xsw.close();
+    }
+
+    public static void writeTo(Node node, OutputStream os) throws XMLStreamException {
+        copy(new DOMSource(node), os);
+    }
+    public static void writeTo(Node node, OutputStream os, int indent) throws XMLStreamException {
+        if (indent > 0) {
+            XMLStreamWriter writer = new PrettyPrintXMLStreamWriter(createXMLStreamWriter(os), indent);
+            try {
+                copy(new DOMSource(node), writer);
+            } finally {
+                writer.close();
+            }
+        } else {
+            copy(new DOMSource(node), os);
+        }
+    }
+    public static void writeTo(Node node, Writer os) throws XMLStreamException {
+        writeTo(node, os, 0);
+    }
+    public static void writeTo(Node node, Writer os, int indent) throws XMLStreamException {
+        XMLStreamWriter writer = createXMLStreamWriter(os);
+        if (indent > 0) {
+            writer = new PrettyPrintXMLStreamWriter(writer, indent);
+        }
+        try {
+            copy(new DOMSource(node), writer);
+        } finally {
+            writer.close();
+        }
+    }
+
+
+    /**
+     * Copies the reader to the writer. The start and end document methods must
+     * be handled on the writer manually.
+     *
+     * @param reader
+     * @param writer
+     * @throws XMLStreamException
+     */
+    public static void copy(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+        copy(reader, writer, false, false);
+    }
+    public static void copy(XMLStreamReader reader, XMLStreamWriter writer, boolean fragment)
+        throws XMLStreamException {
+        copy(reader, writer, fragment, false);
+    }
+    public static void copy(XMLStreamReader reader,
+                            XMLStreamWriter writer,
+                            boolean fragment,
+                            boolean isThreshold) throws XMLStreamException {
+        // number of elements read in
+        int read = 0;
+        int elementCount = 0;
+        final Deque<Integer> countStack = new ArrayDeque<>();
+        int event = reader.getEventType();
+
+        while (reader.hasNext()) {
+            switch (event) {
+            case XMLStreamConstants.START_ELEMENT:
+                read++;
+                if (isThreshold) {
+                    elementCount++;
+
+                    if (MAX_ELEMENT_DEPTH_VAL != -1 && read >= MAX_ELEMENT_DEPTH_VAL) {
+                        throw new DepthExceededStaxException("reach the innerElementLevelThreshold:"
+                                                   + MAX_ELEMENT_DEPTH_VAL);
+                    }
+                    if (MAX_CHILD_ELEMENTS_VAL != -1 && elementCount >= MAX_CHILD_ELEMENTS_VAL) {
+                        throw new DepthExceededStaxException("reach the innerElementCountThreshold:"
+                                                   + MAX_CHILD_ELEMENTS_VAL);
+                    }
+                    countStack.push(elementCount);
+                    elementCount = 0;
+                }
+                writeStartElement(reader, writer);
+                break;
+            case XMLStreamConstants.END_ELEMENT:
+                if (read > 0) {
+                    writer.writeEndElement();
+                }
+                read--;
+                if (read < 0 && fragment) {
+                    return;
+                }
+                if (isThreshold && !countStack.isEmpty()) {
+                    elementCount = countStack.pop();
+                }
+                break;
+            case XMLStreamConstants.CHARACTERS:
+            case XMLStreamConstants.SPACE:
+                String s = reader.getText();
+                if (s != null) {
+                    writer.writeCharacters(s);
+                }
+                break;
+            case XMLStreamConstants.COMMENT:
+                writer.writeComment(reader.getText());
+                break;
+            case XMLStreamConstants.CDATA:
+                writer.writeCData(reader.getText());
+                break;
+            case XMLStreamConstants.START_DOCUMENT:
+            case XMLStreamConstants.END_DOCUMENT:
+            case XMLStreamConstants.ATTRIBUTE:
+            case XMLStreamConstants.NAMESPACE:
+                break;
+            default:
+                break;
+            }
+            event = reader.next();
+        }
+    }
+
+    private static void writeStartElement(XMLStreamReader reader, XMLStreamWriter writer)
+        throws XMLStreamException {
+        String uri = reader.getNamespaceURI();
+        String prefix = reader.getPrefix();
+        String local = reader.getLocalName();
+
+        if (prefix == null) {
+            prefix = "";
+        }
+
+        boolean writeElementNS = false;
+
+        if (uri != null) {
+            writeElementNS = true;
+            Iterator<String> it = CastUtils.cast(writer.getNamespaceContext().getPrefixes(uri));
+            if (!it.hasNext() && StringUtils.isEmpty(prefix) && StringUtils.isEmpty(uri)
+                && StringUtils.isEmpty(writer.getNamespaceContext().getNamespaceURI(""))) {
+                writeElementNS = false;
+            }
+            while (it.hasNext()) {
+                String s = it.next();
+                if (s == null) {
+                    s = "";
+                }
+                if (s.equals(prefix)) {
+                    writeElementNS = false;
+                }
+            }
+        }
+
+        // Write out the element name
+        if (uri != null) {
+            if (prefix.isEmpty() && StringUtils.isEmpty(uri)) {
+                writer.writeStartElement(local);
+            } else {
+                writer.writeStartElement(prefix, local, uri);
+            }
+        } else {
+            writer.writeStartElement(local);
+        }
+
+        // Write out the namespaces
+        for (int i = 0; i < reader.getNamespaceCount(); i++) {
+            String nsURI = reader.getNamespaceURI(i);
+            String nsPrefix = reader.getNamespacePrefix(i);
+            if (nsPrefix == null) {
+                nsPrefix = "";
+            }
+            if (nsURI == null) {
+                nsURI = "";
+            }
+            if (nsPrefix.isEmpty()) {
+                writer.writeDefaultNamespace(nsURI);
+                writer.setDefaultNamespace(nsURI);
+            } else {
+                writer.writeNamespace(nsPrefix, nsURI);
+                writer.setPrefix(nsPrefix, nsURI);
+            }
+
+            if (nsURI.equals(uri) && nsPrefix.equals(prefix)) {
+                writeElementNS = false;
+            }
+        }
+
+        // Check if the namespace still needs to be written.
+        // We need this check because namespace writing works
+        // different on Woodstox and the RI.
+        if (writeElementNS) {
+            if (prefix.isEmpty()) {
+                writer.writeDefaultNamespace(uri);
+                writer.setDefaultNamespace(uri);
+            } else {
+                writer.writeNamespace(prefix, uri);
+                writer.setPrefix(prefix, uri);
+            }
+        }
+
+        // Write out attributes
+        for (int i = 0; i < reader.getAttributeCount(); i++) {
+            String ns = reader.getAttributeNamespace(i);
+            String nsPrefix = reader.getAttributePrefix(i);
+            if (ns == null || ns.isEmpty()) {
+                writer.writeAttribute(reader.getAttributeLocalName(i), reader.getAttributeValue(i));
+            } else if (nsPrefix == null || nsPrefix.isEmpty()) {
+                writer.writeAttribute(reader.getAttributeNamespace(i), reader.getAttributeLocalName(i),
+                                      reader.getAttributeValue(i));
+            } else {
+                Iterator<String> it = CastUtils.cast(writer.getNamespaceContext().getPrefixes(ns));
+                boolean writeNs = true;
+                while (it != null && it.hasNext()) {
+                    String s = it.next();
+                    if (s == null) {
+                        s = "";
+                    }
+                    if (s.equals(nsPrefix)) {
+                        writeNs = false;
+                    }
+                }
+                if (writeNs) {
+                    writer.writeNamespace(nsPrefix, ns);
+                    writer.setPrefix(nsPrefix, ns);
+                }
+                writer.writeAttribute(reader.getAttributePrefix(i), reader.getAttributeNamespace(i), reader
+                    .getAttributeLocalName(i), reader.getAttributeValue(i));
+            }
+
+        }
+    }
+
+    public static void writeDocument(Document d, XMLStreamWriter writer, boolean repairing)
+        throws XMLStreamException {
+        writeDocument(d, writer, true, repairing);
+    }
+
+    public static void writeDocument(Document d, XMLStreamWriter writer, boolean writeProlog,
+                                     boolean repairing) throws XMLStreamException {
+        if (writeProlog) {
+            writer.writeStartDocument();
+        }
+
+        Node node = d.getFirstChild();
+        while (node != null) {
+            if (writeProlog || node.getNodeType() == Node.ELEMENT_NODE) {
+                writeNode(node, writer, repairing);
+            }
+            node = node.getNextSibling();
+        }
+
+        if (writeProlog) {
+            writer.writeEndDocument();
+        }
+    }
+
+    /**
+     * Writes an Element to an XMLStreamWriter. The writer must already have
+     * started the document (via writeStartDocument()). Also, this probably
+     * won't work with just a fragment of a document. The Element should be the
+     * root element of the document.
+     *
+     * @param e
+     * @param writer
+     * @throws XMLStreamException
+     */
+    public static void writeElement(Element e, XMLStreamWriter writer, boolean repairing)
+        throws XMLStreamException {
+        writeElement(e, writer, repairing, true);
+    }
+
+    /**
+     * Writes an Element to an XMLStreamWriter. The writer must already have
+     * started the document (via writeStartDocument()). Also, this probably
+     * won't work with just a fragment of a document. The Element should be the
+     * root element of the document.
+     *
+     * @param e
+     * @param writer
+     * @param endElement true if the element should be ended
+     * @throws XMLStreamException
+     */
+    public static void writeElement(Element e,
+                                    XMLStreamWriter writer,
+                                    boolean repairing,
+                                    boolean endElement)
+        throws XMLStreamException {
+        String prefix = e.getPrefix();
+        String ns = e.getNamespaceURI();
+        String localName = e.getLocalName();
+
+        if (prefix == null) {
+            prefix = "";
+        }
+        if (localName == null) {
+            localName = e.getNodeName();
+
+            if (localName == null) {
+                throw new IllegalStateException("Element's local name cannot be null!");
+            }
+        }
+
+        String decUri = writer.getNamespaceContext().getNamespaceURI(prefix);
+        boolean declareNamespace = decUri == null || !decUri.equals(ns);
+
+        if (ns == null || ns.isEmpty()) {
+            writer.writeStartElement(localName);
+            if (StringUtils.isEmpty(decUri)) {
+                declareNamespace = false;
+            }
+        } else {
+            writer.writeStartElement(prefix, localName, ns);
+        }
+
+        for (Node attr : sortElementAttributes(e.getAttributes())) {
+
+            String name = attr.getLocalName();
+            String attrPrefix = attr.getPrefix();
+            if (attrPrefix == null) {
+                attrPrefix = "";
+            }
+            if (name == null) {
+                name = attr.getNodeName();
+            }
+
+            if ("xmlns".equals(attrPrefix)) {
+                writer.writeNamespace(name, attr.getNodeValue());
+                writer.setPrefix(name, attr.getNodeValue());
+                if (name.equals(prefix) && attr.getNodeValue().equals(ns)) {
+                    declareNamespace = false;
+                }
+            } else {
+                if ("xmlns".equals(name) && "".equals(attrPrefix)) {
+                    writer.writeDefaultNamespace(attr.getNodeValue());
+                    writer.setDefaultNamespace(attr.getNodeValue());
+                    if (attr.getNodeValue().equals(ns)) {
+                        declareNamespace = false;
+                    } else if (StringUtils.isEmpty(attr.getNodeValue())
+                        && StringUtils.isEmpty(ns)) {
+                        declareNamespace = false;
+                    }
+                } else {
+                    String attns = attr.getNamespaceURI();
+                    String value = attr.getNodeValue();
+                    if (attns == null || attns.isEmpty()) {
+                        writer.writeAttribute(name, value);
+                    } else if (attrPrefix.isEmpty()) {
+                        writer.writeAttribute(attns, name, value);
+                    } else {
+                        if (repairing && writer.getNamespaceContext().getNamespaceURI(attrPrefix) == null) {
+                            writer.writeNamespace(attrPrefix, attns);
+                        }
+                        writer.writeAttribute(attrPrefix, attns, name, value);
+                    }
+                }
+            }
+        }
+
+        if (declareNamespace && repairing) {
+            if (ns == null) {
+                writer.writeNamespace(prefix, "");
+                writer.setPrefix(prefix, "");
+            } else {
+                writer.writeNamespace(prefix, ns);
+                writer.setPrefix(prefix, ns);
+            }
+        }
+
+        Node nd = e.getFirstChild();
+        while (nd != null) {
+            writeNode(nd, writer, repairing);
+            nd = nd.getNextSibling();
+        }
+
+        if (endElement) {
+            writer.writeEndElement();
+        }
+    }
+
+    private static List<Node> sortElementAttributes(NamedNodeMap attrs) {
+        if (attrs.getLength() == 0) {
+            return Collections.<Node> emptyList();
+        }
+        List<Node> sortedAttrs = new ArrayList<>(attrs.getLength());
+        for (int i = 0; i < attrs.getLength(); i++) {
+            Node attr = attrs.item(i);
+            String name = attr.getLocalName();
+            if (name == null) {
+                name = attr.getNodeName();
+            }
+            if ("xmlns".equals(attr.getPrefix()) || "xmlns".equals(name)) {
+                sortedAttrs.add(0, attr);
+            } else {
+                sortedAttrs.add(attr);
+            }
+        }
+
+        return sortedAttrs;
+    }
+
+    public static void writeNode(Node n, XMLStreamWriter writer, boolean repairing)
+        throws XMLStreamException {
+
+        switch (n.getNodeType()) {
+        case Node.ELEMENT_NODE:
+            writeElement((Element)n, writer, repairing);
+            break;
+        case Node.TEXT_NODE:
+            writer.writeCharacters(((Text)n).getNodeValue());
+            break;
+        case Node.COMMENT_NODE:
+            writer.writeComment(((Comment)n).getData());
+            break;
+        case Node.CDATA_SECTION_NODE:
+            writer.writeCData(((CDATASection)n).getData());
+            break;
+        case Node.ENTITY_REFERENCE_NODE:
+            writer.writeEntityRef(((EntityReference)n).getNodeValue());
+            break;
+        case Node.PROCESSING_INSTRUCTION_NODE:
+            ProcessingInstruction pi = (ProcessingInstruction)n;
+            writer.writeProcessingInstruction(pi.getTarget(), pi.getData());
+            break;
+        case Node.DOCUMENT_NODE:
+            writeDocument((Document)n, writer, repairing);
+            break;
+        case Node.DOCUMENT_FRAGMENT_NODE: {
+            DocumentFragment frag = (DocumentFragment)n;
+            Node child = frag.getFirstChild();
+            while (child != null) {
+                writeNode(child, writer, repairing);
+                child = child.getNextSibling();
+            }
+            break;
+        }
+        case Node.DOCUMENT_TYPE_NODE:
+            try {
+                if (((DocumentType)n).getTextContent() != null) {
+                    writer.writeDTD(((DocumentType)n).getTextContent());
+                }
+            } catch (UnsupportedOperationException ex) {
+                //can we ignore?  DOM writers really don't allow this
+                //as there isn't a way to write a DTD in dom
+            }
+            break;
+        default:
+            throw new IllegalStateException("Found type: " + n.getClass().getName());
+        }
+    }
+
+    public static Document read(Source s) throws XMLStreamException {
+        XMLStreamReader reader = createXMLStreamReader(s);
+        try {
+            return read(reader);
+        } finally {
+            try {
+                reader.close();
+            } catch (Exception ex) {
+                //ignore
+            }
+        }
+    }
+    public static Document read(InputStream s) throws XMLStreamException {
+        XMLStreamReader reader = createXMLStreamReader(s);
+        try {
+            return read(reader);
+        } finally {
+            try {
+                reader.close();
+            } catch (Exception ex) {
+                //ignore
+            }
+        }
+    }
+    public static Document read(Reader s) throws XMLStreamException {
+        XMLStreamReader reader = createXMLStreamReader(s);
+        try {
+            return read(reader);
+        } finally {
+            try {
+                reader.close();
+            } catch (Exception ex) {
+                //ignore
+            }
+        }
+    }
+    public static Document read(File is) throws XMLStreamException, IOException {
+        try (InputStream fin = Files.newInputStream(is.toPath())) {
+            return read(fin);
+        }
+    }
+    public static Document read(InputSource s) throws XMLStreamException {
+        XMLStreamReader reader = null;
+        try {
+            reader = createXMLStreamReader(s);
+            return read(reader);
+        } finally {
+            StaxUtils.close(reader);
+        }
+    }
+    public static Document read(XMLStreamReader reader) throws XMLStreamException {
+        return read(reader, false);
+    }
+    public static Document read(XMLStreamReader reader, boolean recordLoc) throws XMLStreamException {
+        Document doc = DOMUtils.createDocument();
+        if (reader.getLocation().getSystemId() != null) {
+            try {
+                doc.setDocumentURI(reader.getLocation().getSystemId());
+            } catch (Exception e) {
+                //ignore - probably not DOM level 3
+            }
+        }
+        readDocElements(doc, doc, reader, true, recordLoc);
+        return doc;
+    }
+
+    public static Document read(DocumentBuilder builder, XMLStreamReader reader, boolean repairing)
+        throws XMLStreamException {
+
+        Document doc = builder == null ? DOMUtils.createDocument() : builder.newDocument();
+        if (reader.getLocation().getSystemId() != null) {
+            try {
+                doc.setDocumentURI(reader.getLocation().getSystemId());
+            } catch (Exception e) {
+                //ignore - probably not DOM level 3
+            }
+        }
+        readDocElements(doc, reader, repairing);
+        return doc;
+    }
+
+    /**
+     * @param parent
+     */
+    private static Document getDocument(Node parent) {
+        return (parent instanceof Document) ? (Document)parent : parent.getOwnerDocument();
+    }
+
+    private static boolean isDeclared(Element e, String namespaceURI, String prefix) {
+        while (e != null) {
+            Attr att;
+            if (prefix != null && !prefix.isEmpty()) {
+                att = e.getAttributeNodeNS(XML_NS, prefix);
+            } else {
+                att = e.getAttributeNode("xmlns");
+            }
+
+            if (att != null && att.getNodeValue().equals(namespaceURI)) {
+                return true;
+            }
+
+            if (e.getParentNode() instanceof Element) {
+                e = (Element)e.getParentNode();
+            } else if (StringUtils.isEmpty(prefix) && StringUtils.isEmpty(namespaceURI)) {
+                //A document that probably doesn't have any namespace qualifies elements
+                return true;
+            } else {
+                break;
+            }
+        }
+        return false;
+    }
+
+    public static void readDocElements(Node parent, XMLStreamReader reader, boolean repairing)
+        throws XMLStreamException {
+        Document doc = getDocument(parent);
+        readDocElements(doc, parent, reader, repairing, false);
+    }
+
+    public static void readDocElements(Node parent, XMLStreamReader reader, boolean repairing,
+                                       boolean isThreshold)
+        throws XMLStreamException {
+        Document doc = getDocument(parent);
+        readDocElements(doc, parent, reader, repairing, false, isThreshold);
+    }
+
+    /**
+     * @param parent
+     * @param reader
+     * @throws XMLStreamException
+     */
+    public static void readDocElements(Document doc, Node parent,
+                                       XMLStreamReader reader, boolean repairing, boolean recordLoc)
+        throws XMLStreamException {
+        readDocElements(doc, parent, reader, repairing, recordLoc, false);
+    }
+
+    /**
+     * @param parent
+     * @param reader
+     * @throws XMLStreamException
+     */
+    public static void readDocElements(Document doc, Node parent,
+                                       XMLStreamReader reader, boolean repairing, boolean recordLoc,
+                                       boolean isThreshold)
+        throws XMLStreamException {
+        final Deque<Node> stack = new ArrayDeque<>();
+        int event = reader.getEventType();
+        int elementCount = 0;
+        while (reader.hasNext()) {
+            switch (event) {
+            case XMLStreamConstants.START_ELEMENT: {
+                elementCount++;
+                Element e;
+                if (!StringUtils.isEmpty(reader.getPrefix())) {
+                    e = doc.createElementNS(reader.getNamespaceURI(),
+                                            reader.getPrefix() + ':' + reader.getLocalName());
+                } else {
+                    e = doc.createElementNS(reader.getNamespaceURI(), reader.getLocalName());
+                }
+                e = (Element)parent.appendChild(e);
+                recordLoc = addLocation(doc, e, reader, recordLoc);
+
+                for (int ns = 0; ns < reader.getNamespaceCount(); ns++) {
+                    String uri = reader.getNamespaceURI(ns);
+                    String prefix = reader.getNamespacePrefix(ns);
+
+                    declare(e, uri, prefix);
+                }
+
+                for (int att = 0; att < reader.getAttributeCount(); att++) {
+                    String name = reader.getAttributeLocalName(att);
+                    String prefix = reader.getAttributePrefix(att);
+                    if (prefix != null && !prefix.isEmpty()) {
+                        name = prefix + ':' + name;
+                    }
+
+                    Attr attr = doc.createAttributeNS(reader.getAttributeNamespace(att), name);
+                    attr.setValue(reader.getAttributeValue(att));
+                    e.setAttributeNode(attr);
+                }
+
+                if (repairing && !isDeclared(e, reader.getNamespaceURI(), reader.getPrefix())) {
+                    declare(e, reader.getNamespaceURI(), reader.getPrefix());
+                }
+                stack.push(parent);
+                if (isThreshold && MAX_ELEMENT_DEPTH_VAL != -1
+                    && stack.size() >= MAX_ELEMENT_DEPTH_VAL) {
+                    throw new DepthExceededStaxException("reach the innerElementLevelThreshold:"
+                                               + MAX_ELEMENT_DEPTH_VAL);
+                }
+                if (isThreshold && MAX_CHILD_ELEMENTS_VAL != -1
+                    && elementCount >= MAX_CHILD_ELEMENTS_VAL) {
+                    throw new DepthExceededStaxException("reach the innerElementCountThreshold:"
+                                               + MAX_CHILD_ELEMENTS_VAL);
+                }
+                parent = e;
+                break;
+            }
+            case XMLStreamConstants.END_ELEMENT:
+                if (stack.isEmpty()) {
+                    return;
+                }
+                parent = stack.pop();
+                if (parent instanceof Document || parent instanceof DocumentFragment) {
+                    return;
+                }
+                break;
+            case XMLStreamConstants.NAMESPACE:
+                break;
+            case XMLStreamConstants.ATTRIBUTE:
+                break;
+            case XMLStreamConstants.CHARACTERS:
+                if (parent != null) {
+                    recordLoc = addLocation(doc,
+                                            parent.appendChild(doc.createTextNode(reader.getText())),
+                                            reader, recordLoc);
+                }
+                break;
+            case XMLStreamConstants.COMMENT:
+                if (parent != null) {
+                    parent.appendChild(doc.createComment(reader.getText()));
+                }
+                break;
+            case XMLStreamConstants.CDATA:
+                recordLoc = addLocation(doc,
+                                        parent.appendChild(doc.createCDATASection(reader.getText())),
+                                        reader, recordLoc);
+                break;
+            case XMLStreamConstants.PROCESSING_INSTRUCTION:
+                parent.appendChild(doc.createProcessingInstruction(reader.getPITarget(), reader.getPIData()));
+                break;
+            case XMLStreamConstants.ENTITY_REFERENCE:
+                parent.appendChild(doc.createProcessingInstruction(reader.getPITarget(), reader.getPIData()));
+                break;
+            default:
+                break;
+            }
+
+            if (reader.hasNext()) {
+                event = reader.next();
+            }
+        }
+    }
+
+    public static class StreamToDOMContext {
+        private final Deque<Node> stack = new ArrayDeque<>();
+        private int elementCount;
+        private boolean repairing;
+        private boolean recordLoc;
+        private boolean threshold;
+
+        public StreamToDOMContext(boolean repairing, boolean recordLoc, boolean threshold) {
+            this.repairing = repairing;
+            this.recordLoc = recordLoc;
+            this.threshold = threshold;
+        }
+
+        public void setRecordLoc(boolean recordLoc) {
+            this.recordLoc = recordLoc;
+        }
+
+        public boolean isRecordLoc() {
+            return this.recordLoc;
+        }
+
+        public boolean isRepairing() {
+            return this.repairing;
+        }
+
+        public boolean isThreshold() {
+            return this.threshold;
+        }
+
+        public int incrementCount() {
+            return ++elementCount;
+        }
+
+        public int decreaseCount() {
+            return --elementCount;
+        }
+
+        public int getCount() {
+            return elementCount;
+        }
+
+        public void pushToStack(Node node) {
+            stack.push(node);
+        }
+
+        public Node popFromStack() {
+            return stack.pop();
+        }
+
+        public int getStackSize() {
+            return stack.size();
+        }
+
+        public boolean isStackEmpty() {
+            return stack.isEmpty();
+        }
+    }
+
+    public static void readDocElements(Document doc, Node parent, XMLStreamReader reader, StreamToDOMContext context)
+        throws XMLStreamException {
+        int event = reader.getEventType();
+        while (reader.hasNext()) {
+            switch (event) {
+            case XMLStreamConstants.START_ELEMENT: {
+                context.incrementCount();
+                Element e;
+                if (!StringUtils.isEmpty(reader.getPrefix())) {
+                    e = doc.createElementNS(reader.getNamespaceURI(),
+                                            reader.getPrefix() + ":" + reader.getLocalName());
+                } else {
+                    e = doc.createElementNS(reader.getNamespaceURI(), reader.getLocalName());
+                }
+                e = (Element)parent.appendChild(e);
+                if (context.isRecordLoc()) {
+                    context.setRecordLoc(addLocation(doc, e, reader.getLocation(), context.isRecordLoc()));
+                }
+
+                for (int ns = 0; ns < reader.getNamespaceCount(); ns++) {
+                    String uri = reader.getNamespaceURI(ns);
+                    String prefix = reader.getNamespacePrefix(ns);
+
+                    declare(e, uri, prefix);
+                }
+
+                for (int att = 0; att < reader.getAttributeCount(); att++) {
+                    String name = reader.getAttributeLocalName(att);
+                    String prefix = reader.getAttributePrefix(att);
+                    if (prefix != null && prefix.length() > 0) {
+                        name = prefix + ":" + name;
+                    }
+
+                    Attr attr = doc.createAttributeNS(reader.getAttributeNamespace(att), name);
+                    attr.setValue(reader.getAttributeValue(att));
+                    e.setAttributeNode(attr);
+                }
+
+                if (context.isRepairing() && !isDeclared(e, reader.getNamespaceURI(), reader.getPrefix())) {
+                    declare(e, reader.getNamespaceURI(), reader.getPrefix());
+                }
+                context.pushToStack(parent);
+                if (context.isThreshold() && MAX_ELEMENT_DEPTH_VAL != -1
+                    && context.getStackSize() >= MAX_ELEMENT_DEPTH_VAL) {
+                    throw new DepthExceededStaxException("reach the innerElementLevelThreshold:"
+                                               + MAX_ELEMENT_DEPTH_VAL);
+                }
+                if (context.isThreshold() && MAX_CHILD_ELEMENTS_VAL != -1
+                    && context.getCount() >= MAX_CHILD_ELEMENTS_VAL) {
+                    throw new DepthExceededStaxException("reach the innerElementCountThreshold:"
+                                               + MAX_CHILD_ELEMENTS_VAL);
+                }
+                parent = e;
+                break;
+            }
+            case XMLStreamConstants.END_ELEMENT:
+                if (context.isStackEmpty()) {
+                    return;
+                }
+                parent = context.popFromStack();
+                if (parent instanceof Document || parent instanceof DocumentFragment) {
+                    return;
+                }
+                break;
+            case XMLStreamConstants.NAMESPACE:
+                break;
+            case XMLStreamConstants.ATTRIBUTE:
+                break;
+            case XMLStreamConstants.CHARACTERS:
+                if (parent != null) {
+                    context.setRecordLoc(addLocation(doc,
+                                                     parent.appendChild(doc.createTextNode(reader.getText())),
+                                                     reader.getLocation(), context.isRecordLoc()));
+                }
+                break;
+            case XMLStreamConstants.COMMENT:
+                if (parent != null) {
+                    parent.appendChild(doc.createComment(reader.getText()));
+                }
+                break;
+            case XMLStreamConstants.CDATA:
+                context.setRecordLoc(addLocation(doc,
+                                        parent.appendChild(doc.createCDATASection(reader.getText())),
+                                        reader.getLocation(), context.isRecordLoc()));
+                break;
+            case XMLStreamConstants.PROCESSING_INSTRUCTION:
+                parent.appendChild(doc.createProcessingInstruction(reader.getPITarget(), reader.getPIData()));
+                break;
+            case XMLStreamConstants.ENTITY_REFERENCE:
+                parent.appendChild(doc.createProcessingInstruction(reader.getPITarget(), reader.getPIData()));
+                break;
+            default:
+                break;
+            }
+
+            if (reader.hasNext()) {
+                event = reader.next();
+            }
+        }
+    }
+
+    public static Node readDocElement(Document doc, Node parent, XMLEvent ev, StreamToDOMContext context)
+        throws XMLStreamException {
+        switch (ev.getEventType()) {
+        case XMLStreamConstants.START_ELEMENT: {
+            context.incrementCount();
+            Element e;
+            StartElement startElem = ev.asStartElement();
+            QName name = startElem.getName();
+            if (!StringUtils.isEmpty(name.getPrefix())) {
+                e = doc.createElementNS(name.getNamespaceURI(),
+                                        name.getPrefix() + ":" + name.getLocalPart());
+            } else {
+                e = doc.createElementNS(name.getNamespaceURI(), name.getLocalPart());
+            }
+            e = (Element)parent.appendChild(e);
+            if (context.isRecordLoc()) {
+                context.setRecordLoc(addLocation(doc, e, startElem.getLocation(), context.isRecordLoc()));
+            }
+
+            if (context.isRepairing() && !isDeclared(e, name.getNamespaceURI(), name.getPrefix())) {
+                declare(e, name.getNamespaceURI(), name.getPrefix());
+            }
+            context.pushToStack(parent);
+            if (context.isThreshold() && MAX_ELEMENT_DEPTH_VAL != -1
+                && context.getStackSize() >= MAX_ELEMENT_DEPTH_VAL) {
+                throw new DepthExceededStaxException("reach the innerElementLevelThreshold:"
+                                           + MAX_ELEMENT_DEPTH_VAL);
+            }
+            if (context.isThreshold() && MAX_CHILD_ELEMENTS_VAL != -1
+                && context.getCount() >= MAX_CHILD_ELEMENTS_VAL) {
+                throw new DepthExceededStaxException("reach the innerElementCountThreshold:"
+                                           + MAX_CHILD_ELEMENTS_VAL);
+            }
+            parent = e;
+            break;
+        }
+        case XMLStreamConstants.END_ELEMENT:
+            if (context.isStackEmpty()) {
+                return parent;
+            }
+            parent = context.popFromStack();
+            if (parent instanceof Document || parent instanceof DocumentFragment) {
+                return parent;
+            }
+            break;
+        case XMLStreamConstants.NAMESPACE:
+            Namespace ns = (Namespace)ev;
+            declare((Element)parent, ns.getNamespaceURI(), ns.getPrefix());
+            break;
+        case XMLStreamConstants.ATTRIBUTE:
+            Attribute at = (Attribute)ev;
+            QName qname = at.getName();
+            String attName = qname.getLocalPart();
+            String attPrefix = qname.getPrefix();
+            if (attPrefix != null && attPrefix.length() > 0) {
+                attName = attPrefix + ":" + attName;
+            }
+            Attr attr = doc.createAttributeNS(qname.getNamespaceURI(), attName);
+            attr.setValue(at.getValue());
+            ((Element)parent).setAttributeNode(attr);
+            break;
+        case XMLStreamConstants.CHARACTERS:
+            Characters characters = ev.asCharacters();
+            context.setRecordLoc(addLocation(doc,
+                                             parent.appendChild(doc.createTextNode(characters.getData())),
+                                             characters.getLocation(), context.isRecordLoc()));
+            break;
+        case XMLStreamConstants.COMMENT:
+            parent.appendChild(doc.createComment(((javax.xml.stream.events.Comment)ev).getText()));
+            break;
+        case XMLStreamConstants.CDATA:
+            Characters cdata = ev.asCharacters();
+            context.setRecordLoc(addLocation(doc,
+                                             parent.appendChild(doc.createCDATASection(cdata.getData())),
+                                             cdata.getLocation(), context.isRecordLoc()));
+            break;
+        case XMLStreamConstants.PROCESSING_INSTRUCTION:
+            parent.appendChild(doc.createProcessingInstruction(((ProcessingInstruction)ev).getTarget(),
+                                                               ((ProcessingInstruction)ev).getData()));
+            break;
+        case XMLStreamConstants.ENTITY_REFERENCE:
+            javax.xml.stream.events.EntityReference er = (javax.xml.stream.events.EntityReference)ev;
+            parent.appendChild(doc.createEntityReference(er.getName()));
+            break;
+        default:
+            break;
+        }
+        return parent;
+    }
+
+    private static boolean addLocation(Document doc, Node node,
+                                       Location loc,
+                                       boolean recordLoc) {
+        if (recordLoc && loc != null && (loc.getColumnNumber() != 0 || loc.getLineNumber() != 0)) {
+            try {
+                final int charOffset = loc.getCharacterOffset();
+                final int colNum = loc.getColumnNumber();
+                final int linNum = loc.getLineNumber();
+                final String pubId = loc.getPublicId() == null ? doc.getDocumentURI() : loc.getPublicId();
+                final String sysId = loc.getSystemId() == null ? doc.getDocumentURI() : loc.getSystemId();
+                Location loc2 = new Location() {
+                    public int getCharacterOffset() {
+                        return charOffset;
+                    }
+                    public int getColumnNumber() {
+                        return colNum;
+                    }
+                    public int getLineNumber() {
+                        return linNum;
+                    }
+                    public String getPublicId() {
+                        return pubId;
+                    }
+                    public String getSystemId() {
+                        return sysId;
+                    }
+                };
+                node.setUserData("location", loc2, LocationUserDataHandler.INSTANCE);
+            } catch (Throwable ex) {
+                //possibly not DOM level 3, won't be able to record this then
+                return false;
+            }
+        }
+        return recordLoc;
+    }
+
+    private static boolean addLocation(Document doc, Node node,
+                                    XMLStreamReader reader,
+                                    boolean recordLoc) {
+        return addLocation(doc, node, reader.getLocation(), recordLoc);
+    }
+
+    private static class LocationUserDataHandler implements UserDataHandler {
+        public static final LocationUserDataHandler INSTANCE = new LocationUserDataHandler();
+
+        public void handle(short operation, String key, Object data, Node src, Node dst) {
+            if (operation == NODE_CLONED) {
+                dst.setUserData(key, data, this);
+            }
+        }
+    }
+
+    private static void declare(Element node, String uri, String prefix) {
+        String qualname;
+        if (prefix != null && prefix.length() > 0) {
+            qualname = "xmlns:" + prefix;
+        } else {
+            qualname = "xmlns";
+        }
+        Attr attr = node.getOwnerDocument().createAttributeNS(XML_NS, qualname);
+        attr.setValue(uri);
+        node.setAttributeNodeNS(attr);
+    }
+    public static XMLStreamReader createXMLStreamReader(InputSource src) {
+        String sysId = src.getSystemId() == null ? null : src.getSystemId();
+        String pubId = src.getPublicId() == null ? null : src.getPublicId();
+        if (src.getByteStream() != null) {
+            final InputStream is = src.getByteStream();
+
+            if (src.getEncoding() == null) {
+                final StreamSource ss = new StreamSource(is, sysId);
+                ss.setPublicId(pubId);
+                
+                final XMLStreamReader xmlStreamReader = createXMLStreamReader(ss);
+                if (AUTO_CLOSE_INPUT_SOURCE) {
+                    return new AutoCloseableXMLStreamReader(xmlStreamReader, is);
+                } else {
+                    return xmlStreamReader;
+                }
+            }
+            
+            return new AutoCloseableXMLStreamReader(createXMLStreamReader(is, src.getEncoding()), is);
+        } else if (src.getCharacterStream() != null) {
+            final Reader reader = src.getCharacterStream();
+            final StreamSource ss = new StreamSource(reader, sysId);
+            ss.setPublicId(pubId);
+            final XMLStreamReader xmlStreamReader = createXMLStreamReader(ss);
+            if (AUTO_CLOSE_INPUT_SOURCE) {
+                return new AutoCloseableXMLStreamReader(xmlStreamReader, reader);
+            } else {
+                return xmlStreamReader;
+            }
+        } else {
+            try {
+                final URL url = new URL(sysId);
+                final InputStream is = url.openStream();
+                final StreamSource ss = new StreamSource(is, sysId);
+                ss.setPublicId(pubId);
+                return new AutoCloseableXMLStreamReader(createXMLStreamReader(ss), is);
+            } catch (Exception ex) {
+                //ignore - not a valid URL
+            }
+        }
+        throw new IllegalArgumentException("InputSource must have a ByteStream or CharacterStream");
+    }
+    /**
+     * @param in
+     * @param encoding
+     */
+    public static XMLStreamReader createXMLStreamReader(InputStream in, String encoding) {
+        XMLInputFactory factory = getXMLInputFactory();
+        try {
+            return factory.createXMLStreamReader(in, encoding != null ? encoding : StandardCharsets.UTF_8.name());
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Couldn't parse stream.", e);
+        } finally {
+            returnXMLInputFactory(factory);
+        }
+    }
+
+    /**
+     * @param in
+     */
+    public static XMLStreamReader createXMLStreamReader(InputStream in) {
+        XMLInputFactory factory = getXMLInputFactory();
+        try {
+            return factory.createXMLStreamReader(in);
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Couldn't parse stream.", e);
+        } finally {
+            returnXMLInputFactory(factory);
+        }
+    }
+    public static XMLStreamReader createXMLStreamReader(String systemId, InputStream in) {
+        XMLInputFactory factory = getXMLInputFactory();
+        try {
+            return factory.createXMLStreamReader(systemId, in);
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Couldn't parse stream.", e);
+        } finally {
+            returnXMLInputFactory(factory);
+        }
+    }
+
+    public static XMLStreamReader createXMLStreamReader(Element el) {
+        return new W3CDOMStreamReader(el);
+    }
+    public static XMLStreamReader createXMLStreamReader(Document doc) {
+        return new W3CDOMStreamReader(doc.getDocumentElement());
+    }
+    public static XMLStreamReader createXMLStreamReader(Element el, String sysId) {
+        return new W3CDOMStreamReader(el, sysId);
+    }
+    public static XMLStreamReader createXMLStreamReader(Document doc, String sysId) {
+        return new W3CDOMStreamReader(doc.getDocumentElement(), sysId);
+    }
+
+    public static XMLStreamReader createXMLStreamReader(Source source) {
+        try {
+            if (source instanceof DOMSource) {
+                DOMSource ds = (DOMSource)source;
+                Node nd = ds.getNode();
+                Element el = null;
+                if (nd instanceof Document) {
+                    el = ((Document)nd).getDocumentElement();
+                } else if (nd instanceof Element) {
+                    el = (Element)nd;
+                }
+
+                if (null != el) {
+                    return new W3CDOMStreamReader(el, source.getSystemId());
+                }
+            } else if (source instanceof StAXSource) {
+                return ((StAXSource)source).getXMLStreamReader();
+            } else if (source instanceof StaxSource) {
+                return ((StaxSource)source).getXMLStreamReader();
+            } else if (source instanceof SAXSource) {
+                SAXSource ss = (SAXSource)source;
+                if (ss.getXMLReader() == null) {
+                    return createXMLStreamReader(((SAXSource)source).getInputSource());
+                }
+            }
+
+            XMLInputFactory factory = getXMLInputFactory();
+            try {
+                XMLStreamReader reader = null;
+
+                try {
+                    reader = factory.createXMLStreamReader(source);
+                } catch (UnsupportedOperationException e) {
+                    //ignore
+                }
+                if (reader == null && source instanceof StreamSource) {
+                    //createXMLStreamReader from Source is optional, we'll try and map it
+                    StreamSource ss = (StreamSource)source;
+                    if (ss.getInputStream() != null) {
+                        reader = factory.createXMLStreamReader(ss.getSystemId(),
+                                                               ss.getInputStream());
+                    } else {
+                        reader = factory.createXMLStreamReader(ss.getSystemId(),
+                                                               ss.getReader());
+                    }
+                }
+                return reader;
+            } finally {
+                returnXMLInputFactory(factory);
+            }
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Couldn't parse stream.", e);
+        }
+    }
+
+    /**
+     * @param reader
+     */
+    public static XMLStreamReader createXMLStreamReader(Reader reader) {
+        XMLInputFactory factory = getXMLInputFactory();
+        try {
+            return factory.createXMLStreamReader(reader);
+        } catch (XMLStreamException e) {
+            throw new RuntimeException("Couldn't parse stream.", e);
+        } finally {
+            returnXMLInputFactory(factory);
+        }
+    }
+
+    /**
+     * Reads a QName from the element text. Reader must be positioned at the
+     * start tag.
+     */
+    public static QName readQName(XMLStreamReader reader) throws XMLStreamException {
+        String value = reader.getElementText();
+        if (value == null) {
+            return null;
+        }
+        value = value.trim();
+
+        int index = value.indexOf(':');
+
+        if (index == -1) {
+            return new QName(value);
+        }
+
+        String prefix = value.substring(0, index);
+        String localName = value.substring(index + 1);
+        String ns = reader.getNamespaceURI(prefix);
+
+        if (!StringUtils.isEmpty(prefix) && ns == null) {
+            throw new RuntimeException("Invalid QName in mapping: " + value);
+        }
+
+        if (ns == null) {
+            return new QName(localName);
+        }
+
+        return new QName(ns, localName, prefix);
+    }
+
+    /**
+     * Create a unique namespace uri/prefix combination.
+     *
+     * @return The namespace with the specified URI. If one doesn't exist, one
+     *         is created.
+     * @throws XMLStreamException
+     */
+    public static String getUniquePrefix(XMLStreamWriter writer, String namespaceURI, boolean declare)
+        throws XMLStreamException {
+        String prefix = writer.getPrefix(namespaceURI);
+        if (prefix == null) {
+            prefix = getUniquePrefix(writer);
+
+            if (declare) {
+                writer.setPrefix(prefix, namespaceURI);
+                writer.writeNamespace(prefix, namespaceURI);
+            }
+        }
+        return prefix;
+    }
+    public static String getUniquePrefix(XMLStreamWriter writer, String namespaceURI)
+        throws XMLStreamException {
+        return getUniquePrefix(writer, namespaceURI, false);
+    }
+    public static String getUniquePrefix(XMLStreamWriter writer) {
+        NamespaceContext nc = writer.getNamespaceContext();
+        if (nc == null) {
+            return DEF_PREFIXES[0];
+        }
+        for (String t : DEF_PREFIXES) {
+            String uri = nc.getNamespaceURI(t);
+            if (StringUtils.isEmpty(uri)) {
+                return t;
+            }
+        }
+
+        int n = 10;
+        while (true) {
+            String nsPrefix = "ns" + n;
+            String uri = nc.getNamespaceURI(nsPrefix);
+            if (StringUtils.isEmpty(uri)) {
+                return nsPrefix;
+            }
+            n++;
+        }
+    }
+
+
+    public static void printXmlFragment(XMLStreamReader reader) {
+        try {
+            StringWriter sw = new StringWriter(1024);
+            XMLStreamWriter writer = null;
+            try {
+                writer = new PrettyPrintXMLStreamWriter(createXMLStreamWriter(sw), 4);
+                copy(reader, writer);
+                writer.flush();
+            } finally {
+                StaxUtils.close(writer);
+            }
+            LOG.info(sw.toString());
+        } catch (XMLStreamException e) {
+            LOG.severe(e.getMessage());
+        }
+    }
+
+
+    private static void writeStartElementEvent(XMLEvent event, XMLStreamWriter writer)
+        throws XMLStreamException {
+        StartElement start = event.asStartElement();
+        QName name = start.getName();
+        String nsURI = name.getNamespaceURI();
+        String localName = name.getLocalPart();
+        String prefix = name.getPrefix();
+
+        if (prefix != null) {
+            writer.writeStartElement(prefix, localName, nsURI);
+        } else if (nsURI != null) {
+            writer.writeStartElement(localName, nsURI);
+        } else {
+            writer.writeStartElement(localName);
+        }
+        Iterator<XMLEvent> it = CastUtils.cast(start.getNamespaces());
+        while (it != null && it.hasNext()) {
+            writeEvent(it.next(), writer);
+        }
+
+        it = CastUtils.cast(start.getAttributes());
+        while (it != null && it.hasNext()) {
+            writeAttributeEvent(it.next(), writer);
+        }
+    }
+    private static void writeAttributeEvent(XMLEvent event, XMLStreamWriter writer)
+        throws XMLStreamException {
+
+        Attribute attr = (Attribute)event;
+        QName name = attr.getName();
+        String nsURI = name.getNamespaceURI();
+        String localName = name.getLocalPart();
+        String prefix = name.getPrefix();
+        String value = attr.getValue();
+
+        if (prefix != null) {
+            writer.writeAttribute(prefix, nsURI, localName, value);
+        } else if (nsURI != null) {
+            writer.writeAttribute(nsURI, localName, value);
+        } else {
+            writer.writeAttribute(localName, value);
+        }
+    }
+
+    public static void writeEvent(XMLEvent event, XMLStreamWriter writer)
+        throws XMLStreamException {
+
+        switch (event.getEventType()) {
+        case XMLStreamConstants.START_ELEMENT:
+            writeStartElementEvent(event, writer);
+            break;
+        case XMLStreamConstants.END_ELEMENT:
+            writer.writeEndElement();
+            break;
+        case XMLStreamConstants.ATTRIBUTE:
+            writeAttributeEvent(event, writer);
+            break;
+        case XMLStreamConstants.ENTITY_REFERENCE:
+            writer.writeEntityRef(((javax.xml.stream.events.EntityReference)event).getName());
+            break;
+        case XMLStreamConstants.DTD:
+            writer.writeDTD(((DTD)event).getDocumentTypeDeclaration());
+            break;
+        case XMLStreamConstants.PROCESSING_INSTRUCTION:
+            if (((javax.xml.stream.events.ProcessingInstruction)event).getData() != null) {
+                writer.writeProcessingInstruction(
+                    ((javax.xml.stream.events.ProcessingInstruction)event).getTarget(),
+                    ((javax.xml.stream.events.ProcessingInstruction)event).getData());
+            } else {
+                writer.writeProcessingInstruction(
+                    ((javax.xml.stream.events.ProcessingInstruction)event).getTarget());
+            }
+            break;
+        case XMLStreamConstants.NAMESPACE:
+            if (((Namespace)event).isDefaultNamespaceDeclaration()) {
+                writer.writeDefaultNamespace(((Namespace)event).getNamespaceURI());
+                writer.setDefaultNamespace(((Namespace)event).getNamespaceURI());
+            } else {
+                writer.writeNamespace(((Namespace)event).getPrefix(),
+                                      ((Namespace)event).getNamespaceURI());
+                writer.setPrefix(((Namespace)event).getPrefix(),
+                                 ((Namespace)event).getNamespaceURI());
+            }
+            break;
+        case XMLStreamConstants.COMMENT:
+            writer.writeComment(((javax.xml.stream.events.Comment)event).getText());
+            break;
+        case XMLStreamConstants.CHARACTERS:
+        case XMLStreamConstants.SPACE:
+            writer.writeCharacters(event.asCharacters().getData());
+            break;
+        case XMLStreamConstants.CDATA:
+            writer.writeCData(event.asCharacters().getData());
+            break;
+        case XMLStreamConstants.START_DOCUMENT:
+            if (((StartDocument)event).encodingSet()) {
+                writer.writeStartDocument(((StartDocument)event).getCharacterEncodingScheme(),
+                                          ((StartDocument)event).getVersion());
+
+            } else {
+                writer.writeStartDocument(((StartDocument)event).getVersion());
+            }
+            break;
+        case XMLStreamConstants.END_DOCUMENT:
+            writer.writeEndDocument();
+            break;
+        default:
+            //shouldn't get here
+        }
+    }
+    public static void print(Node node) {
+        XMLStreamWriter writer = null;
+        try {
+            writer = createXMLStreamWriter(System.out);
+            copy(new DOMSource(node), writer);
+            writer.flush();
+        } catch (XMLStreamException e) {
+            throw new RuntimeException(e);
+        } finally {
+            StaxUtils.close(writer);
+        }
+    }
+
+    public static String toString(Source src) {
+        StringWriter sw = new StringWriter(1024);
+        XMLStreamWriter writer = null;
+        try {
+            writer = createXMLStreamWriter(sw);
+            copy(src, writer);
+            writer.flush();
+        } catch (XMLStreamException e) {
+            throw new RuntimeException(e);
+        } finally {
+            StaxUtils.close(writer);
+        }
+        return sw.toString();
+    }
+    public static String toString(Node src) {
+        return toString(new DOMSource(src));
+    }
+    public static String toString(Document doc) {
+        StringWriter sw = new StringWriter(1024);
+        XMLStreamWriter writer = null;
+        try {
+            writer = createXMLStreamWriter(sw);
+            copy(doc, writer);
+            writer.flush();
+        } catch (XMLStreamException e) {
+            throw new RuntimeException(e);
+        } finally {
+            StaxUtils.close(writer);
+        }
+        return sw.toString();
+    }
+    public static String toString(Element el) {
+        return toString(el, 0);
+    }
+    public static String toString(Element el, int indent) {
+        StringWriter sw = new StringWriter(1024);
+        XMLStreamWriter writer = null;
+        try {
+            writer = createXMLStreamWriter(sw);
+            if (indent > 0) {
+                writer = new PrettyPrintXMLStreamWriter(writer, indent);
+            }
+            copy(el, writer);
+            writer.flush();
+        } catch (XMLStreamException e) {
+            throw new RuntimeException(e);
+        } finally {
+            StaxUtils.close(writer);
+        }
+        return sw.toString();
+    }
+    public static void close(XMLStreamReader reader) throws XMLStreamException {
+        if (reader != null) {
+            reader.close();
+        }
+    }
+
+    public static void close(XMLStreamWriter writer) {
+        if (writer != null) {
+            try {
+                writer.close();
+            } catch (Exception e) {
+                //ignore
+            }
+        }
+    }
+
+    public static boolean isSecureReader(XMLStreamReader reader, Message message) {
+        if (reader instanceof DocumentDepthProperties) {
+            return true;
+        }
+        try {
+            if (reader.getProperty(P_MAX_CHILDREN_PER_ELEMENT) != null) {
+                return true;
+            }
+        } catch (Exception ex) {
+            //ignore
+        }
+        return false;
+    }
+
+    public static XMLStreamReader configureReader(XMLStreamReader xreader, Message message) throws XMLStreamException {
+        Integer messageMaxChildElements = PropertyUtils.getInteger(message, MAX_CHILD_ELEMENTS);
+        Integer messageMaxElementDepth = PropertyUtils.getInteger(message, MAX_ELEMENT_DEPTH);
+        Integer messageMaxAttributeCount = PropertyUtils.getInteger(message, MAX_ATTRIBUTE_COUNT);
+        Integer messageMaxAttributeSize = PropertyUtils.getInteger(message, MAX_ATTRIBUTE_SIZE);
+        Integer messageMaxTextLength = PropertyUtils.getInteger(message, MAX_TEXT_LENGTH);
+        Long messageMaxElementCount = PropertyUtils.getLong(message, MAX_ELEMENT_COUNT);
+        Long messageMaxXMLCharacters = PropertyUtils.getLong(message, MAX_XML_CHARACTERS);
+        return configureReader(xreader, messageMaxChildElements, messageMaxElementDepth,
+                               messageMaxAttributeCount, messageMaxAttributeSize, messageMaxTextLength,
+                               messageMaxElementCount, messageMaxXMLCharacters);
+    }
+
+    //CHECKSTYLE:OFF - lots of params to configure
+    public static XMLStreamReader configureReader(XMLStreamReader reader, Integer maxChildElements,
+                                       Integer maxElementDepth, Integer maxAttributeCount,
+                                       Integer maxAttributeSize, Integer maxTextLength,
+                                       Long maxElementCount, Long maxXMLCharacters)
+        throws XMLStreamException {
+        //CHECKSTYLE:ON
+
+        // We currently ONLY support Woodstox 4.2.x for most of this other than a few things
+        // that we can handle via a wrapper.
+        try {
+            DocumentDepthProperties p = null;
+            if (maxChildElements != null) {
+                try {
+                    setProperty(reader, P_MAX_CHILDREN_PER_ELEMENT, maxChildElements);
+                } catch (Throwable t) {
+                    //we can handle this via a wrapper
+                    p = new DocumentDepthProperties();
+                    p.setInnerElementCountThreshold(maxChildElements);
+                }
+            }
+            if (maxElementDepth != null) {
+                try {
+                    setProperty(reader, P_MAX_ELEMENT_DEPTH, maxElementDepth);
+                } catch (Throwable t) {
+                    //we can handle this via a wrapper
+                    if (p == null) {
+                        p = new DocumentDepthProperties();
+                    }
+                    p.setInnerElementLevelThreshold(maxElementDepth);
+                }
+            }
+            if (maxAttributeCount != null) {
+                setProperty(reader, P_MAX_ATTRIBUTES_PER_ELEMENT, maxAttributeCount);
+            }
+            if (maxAttributeSize != null) {
+                setProperty(reader, P_MAX_ATTRIBUTE_SIZE, maxAttributeSize);
+            }
+            if (maxTextLength != null) {
+                setProperty(reader, P_MAX_TEXT_LENGTH, maxTextLength);
+            }
+            if (maxElementCount != null) {
+                try {
+                    setProperty(reader, P_MAX_ELEMENT_COUNT, maxElementCount);
+                } catch (Throwable t) {
+                    //we can handle this via a wrapper
+                    if (p == null) {
+                        p = new DocumentDepthProperties();
+                    }
+                    p.setElementCountThreshold(maxElementCount.intValue());
+                }
+            }
+            if (maxXMLCharacters != null) {
+                setProperty(reader, P_MAX_CHARACTERS, maxXMLCharacters);
+            }
+            if (p != null) {
+                reader = new DepthRestrictingStreamReader(reader, p);
+            }
+        } catch (ClassCastException cce) {
+            //not an XMLStreamReader2
+            if (ALLOW_INSECURE_PARSER_VAL) {
+                LOG.warning("INSTANCE_NOT_XMLSTREAMREADER2");
+            } else {
+                throw new XMLStreamException(cce.getMessage(), cce);
+            }
+        } catch (IllegalArgumentException cce) {
+            //not a property supported by this version of woodstox
+            if (ALLOW_INSECURE_PARSER_VAL) {
+                LOG.log(Level.WARNING, "SECURE_PROPERTY_NOT_SUPPORTED", cce.getMessage());
+            } else {
+                throw new XMLStreamException(cce.getMessage(), cce);
+            }
+        }
+        return reader;
+    }
+    private static void setProperty(XMLStreamReader reader, String p, Object v) {
+        WoodstoxHelper.setProperty(reader, p, v);
+    }
+
+    
+}
diff --git a/transform/src/patch/java/org/apache/cxf/staxutils/W3CDOMStreamReader.java b/transform/src/patch/java/org/apache/cxf/staxutils/W3CDOMStreamReader.java
new file mode 100644
index 0000000..03b1992
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/staxutils/W3CDOMStreamReader.java
@@ -0,0 +1,429 @@
+/**
+ * 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.cxf.staxutils;
+
+import java.util.ArrayList;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.w3c.dom.TypeInfo;
+
+import org.apache.cxf.helpers.DOMUtils;
+
+public class W3CDOMStreamReader extends AbstractDOMStreamReader<Node, Node> {
+    private Node content;
+
+    private Document document;
+
+    private W3CNamespaceContext context;
+
+    private String sysId;
+
+    /**
+     * @param element
+     */
+    public W3CDOMStreamReader(Element element) {
+        super(new ElementFrame<Node, Node>(element, null));
+        content = element;
+        newFrame(getCurrentFrame());
+
+        this.document = element.getOwnerDocument();
+    }
+    public W3CDOMStreamReader(Element element, String systemId) {
+        this(element);
+        sysId = systemId;
+    }
+    public W3CDOMStreamReader(Document doc) {
+        super(new ElementFrame<Node, Node>(doc, false) {
+            public boolean isDocument() {
+                return true;
+            }
+        });
+        this.document = doc;
+    }
+    public W3CDOMStreamReader(DocumentFragment docfrag) {
+        super(new ElementFrame<Node, Node>(docfrag, true) {
+            public boolean isDocumentFragment() {
+                return true;
+            }
+        });
+        this.document = docfrag.getOwnerDocument();
+    }
+
+    /**
+     * Get the document associated with this stream.
+     */
+    public Document getDocument() {
+        return document;
+    }
+    public String getSystemId() {
+        try {
+            return sysId == null ? document.getDocumentURI() : sysId;
+        } catch (Throwable ex) {
+            //ignore, probably not DOM level 3
+        }
+        return sysId;
+    }
+    /**
+     * Find name spaces declaration in atrributes and move them to separate
+     * collection.
+     */
+    @Override
+    protected final void newFrame(ElementFrame<Node, Node> frame) {
+        Node element = getCurrentNode();
+        frame.uris = new ArrayList<>();
+        frame.prefixes = new ArrayList<>();
+        frame.attributes = new ArrayList<>();
+
+        if (context == null) {
+            context = new W3CNamespaceContext();
+        }
+        if (element instanceof Element) {
+            context.setElement((Element)element);
+        }
+
+        NamedNodeMap nodes = element.getAttributes();
+
+        if (nodes != null) {
+            for (int i = 0; i < nodes.getLength(); i++) {
+                Node node = nodes.item(i);
+                String prefix = node.getPrefix();
+                String localName = node.getLocalName();
+                String value = node.getNodeValue();
+                String name = node.getNodeName();
+
+                if (prefix == null) {
+                    prefix = "";
+                }
+
+                if ("xmlns".equals(name)) {
+                    frame.uris.add(value);
+                    frame.prefixes.add("");
+                } else if (!prefix.isEmpty() && "xmlns".equals(prefix)) {
+                    frame.uris.add(value);
+                    frame.prefixes.add(localName);
+                } else if (name.startsWith("xmlns:")) {
+                    frame.uris.add(value);
+                    frame.prefixes.add(name.substring(6));
+                } else {
+                    frame.attributes.add(node);
+                }
+            }
+        }
+    }
+
+    public final Node getCurrentNode() {
+        return getCurrentFrame().element;
+    }
+    public final Element getCurrentElement() {
+        return (Element)getCurrentFrame().element;
+    }
+
+    @Override
+    protected ElementFrame<Node, Node> getChildFrame() {
+        return new ElementFrame<Node, Node>(getCurrentFrame().currentChild,
+                                getCurrentFrame());
+    }
+
+    @Override
+    protected boolean hasMoreChildren() {
+        if (getCurrentFrame().currentChild == null) {
+            return getCurrentNode().getFirstChild() != null;
+        }
+        return getCurrentFrame().currentChild.getNextSibling() != null;
+    }
+
+    @Override
+    protected int nextChild() {
+        ElementFrame<Node, Node> frame = getCurrentFrame();
+        if (frame.currentChild == null) {
+            content = getCurrentNode().getFirstChild();
+        } else {
+            content = frame.currentChild.getNextSibling();
+        }
+
+        frame.currentChild = content;
+        switch (content.getNodeType()) {
+        case Node.ELEMENT_NODE:
+            return START_ELEMENT;
+        case Node.TEXT_NODE:
+            return CHARACTERS;
+        case Node.COMMENT_NODE:
+            return COMMENT;
+        case Node.CDATA_SECTION_NODE:
+            return CDATA;
+        case Node.ENTITY_REFERENCE_NODE:
+            return ENTITY_REFERENCE;
+        case Node.PROCESSING_INSTRUCTION_NODE:
+            return PROCESSING_INSTRUCTION;
+        default:
+            throw new IllegalStateException("Found type: " + content.getClass().getName());
+        }
+    }
+
+    @Override
+    public String getElementText() throws XMLStreamException {
+        String result = DOMUtils.getRawContent(content);
+
+        ElementFrame<Node, Node> frame = getCurrentFrame();
+        frame.ended = true;
+        currentEvent = END_ELEMENT;
+        endElement();
+
+        // we should not return null according to the StAx API javadoc
+        return result != null ? result : "";
+    }
+
+    @Override
+    public String getNamespaceURI(String prefix) {
+        ElementFrame<Node, Node> frame = getCurrentFrame();
+
+        while (null != frame) {
+            int index = frame.prefixes.indexOf(prefix);
+            if (index != -1) {
+                return frame.uris.get(index);
+            }
+
+            if (frame.parent == null && frame.getElement() instanceof Element) {
+                return ((Element)frame.getElement()).lookupNamespaceURI(prefix);
+            }
+            frame = frame.parent;
+        }
+
+        return null;
+    }
+
+    public String getAttributeValue(String ns, String local) {
+        Attr at;
+        if (ns == null || ns.isEmpty()) {
+            at = getCurrentElement().getAttributeNode(local);
+        } else {
+            at = getCurrentElement().getAttributeNodeNS(ns, local);
+        }
+
+        if (at == null) {
+            return null;
+        }
+        return at.getNodeValue();
+    }
+
+    public int getAttributeCount() {
+        return getCurrentFrame().attributes.size();
+    }
+
+    Attr getAttribute(int i) {
+        return (Attr)getCurrentFrame().attributes.get(i);
+    }
+
+    private String getLocalName(Attr attr) {
+
+        String name = attr.getLocalName();
+        if (name == null) {
+            name = attr.getNodeName();
+        }
+        return name;
+    }
+
+    public QName getAttributeName(int i) {
+        Attr at = getAttribute(i);
+
+        String prefix = at.getPrefix();
+        String ln = getLocalName(at);
+        // at.getNodeName();
+        String ns = at.getNamespaceURI();
+
+        if (prefix == null) {
+            return new QName(ns, ln);
+        }
+        return new QName(ns, ln, prefix);
+    }
+
+    public String getAttributeNamespace(int i) {
+        return getAttribute(i).getNamespaceURI();
+    }
+
+    public String getAttributeLocalName(int i) {
+        Attr attr = getAttribute(i);
+        return getLocalName(attr);
+    }
+
+    public String getAttributePrefix(int i) {
+        return getAttribute(i).getPrefix();
+    }
+
+    public String getAttributeType(int i) {
+        Attr attr = getAttribute(i);
+        if (attr.isId()) {
+            return "ID";
+        }
+        TypeInfo schemaType = null;
+        try {
+            schemaType = attr.getSchemaTypeInfo();
+        } catch (Throwable t) {
+            //DOM level 2?
+        }
+        return (schemaType == null) ? "CDATA"
+            : schemaType.getTypeName() == null ? "CDATA" : schemaType.getTypeName();
+    }
+
+
+    public String getAttributeValue(int i) {
+        return getAttribute(i).getValue();
+    }
+
+    public boolean isAttributeSpecified(int i) {
+        return getAttribute(i).getValue() != null;
+    }
+
+    public int getNamespaceCount() {
+        return getCurrentFrame().prefixes.size();
+    }
+
+    public String getNamespacePrefix(int i) {
+        return getCurrentFrame().prefixes.get(i);
+    }
+
+    public String getNamespaceURI(int i) {
+        return getCurrentFrame().uris.get(i);
+    }
+
+    public NamespaceContext getNamespaceContext() {
+        return context;
+    }
+
+    public String getText() {
+        if (content instanceof Text) {
+            return ((Text)content).getData();
+        } else if (content instanceof Comment) {
+            return ((Comment)content).getData();
+        }
+        return DOMUtils.getRawContent(getCurrentNode());
+    }
+
+    public char[] getTextCharacters() {
+        return getText().toCharArray();
+    }
+
+    public int getTextStart() {
+        return 0;
+    }
+
+    public int getTextLength() {
+        return getText().length();
+    }
+
+    public String getEncoding() {
+        return null;
+    }
+
+    public QName getName() {
+        Node el = getCurrentNode();
+
+        String prefix = getPrefix();
+        String ln = getLocalName();
+
+        return new QName(el.getNamespaceURI(), ln, prefix);
+    }
+
+    public String getLocalName() {
+        String ln = getCurrentNode().getLocalName();
+        if (ln == null) {
+            ln = getCurrentNode().getNodeName();
+            if (ln.indexOf(':') != -1) {
+                ln = ln.substring(ln.indexOf(':') + 1);
+            }
+        }
+        return ln;
+    }
+
+    public String getNamespaceURI() {
+        String ln = getCurrentNode().getLocalName();
+        if (ln == null) {
+            ln = getCurrentNode().getNodeName();
+            if (ln.indexOf(':') == -1) {
+                ln = getNamespaceURI("");
+            } else {
+                ln = getNamespaceURI(ln.substring(0, ln.indexOf(':')));
+            }
+            return ln;
+        }
+        return getCurrentNode().getNamespaceURI();
+    }
+
+    public String getPrefix() {
+        String prefix = getCurrentNode().getPrefix();
+        if (prefix == null) {
+            String nodeName = getCurrentNode().getNodeName();
+            if (nodeName.indexOf(':') != -1) {
+                prefix = nodeName.substring(0, nodeName.indexOf(':'));
+            }  else {
+                prefix = "";
+            }
+        }
+        return prefix;
+    }
+
+    public String getPITarget() {
+        return ((ProcessingInstruction)content).getTarget();
+    }
+
+    public String getPIData() {
+        return ((ProcessingInstruction)content).getData();
+    }
+    public Location getLocation() {
+        try {
+            Object o = getCurrentNode().getUserData("location");
+            if (o instanceof Location) {
+                return (Location)o;
+            }
+        } catch (Throwable ex) {
+            //ignore, probably not DOM level 3
+        }
+        return super.getLocation();
+    }
+
+    public String toString() {
+        if (document == null) {
+            return "<null>";
+        }
+        if (document.getDocumentElement() == null) {
+            return "<null document element>";
+        }
+        try {
+            return StaxUtils.toString(document);
+        } catch (Throwable t) {
+            t.printStackTrace();
+            return super.toString();
+        }
+    }
+
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/transport/ChainInitiationObserver.java b/transform/src/patch/java/org/apache/cxf/transport/ChainInitiationObserver.java
new file mode 100644
index 0000000..a4b8aa3
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/transport/ChainInitiationObserver.java
@@ -0,0 +1,197 @@
+/**
+ * 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.cxf.transport;
+
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collection;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.binding.Binding;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.classloader.ClassLoaderUtils.ClassLoaderHolder;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.interceptor.InterceptorChain;
+import org.apache.cxf.interceptor.InterceptorProvider;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.PhaseChainCache;
+import org.apache.cxf.phase.PhaseManager;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.model.EndpointInfo;
+
+public class ChainInitiationObserver implements MessageObserver {
+    protected Endpoint endpoint;
+    protected Bus bus;
+    protected ClassLoader loader;
+
+    private PhaseChainCache chainCache = new PhaseChainCache();
+
+    public ChainInitiationObserver(Endpoint endpoint, Bus bus) {
+        super();
+        this.endpoint = endpoint;
+        this.bus = bus;
+        if (bus != null) {
+            loader = bus.getExtension(ClassLoader.class);
+        }
+    }
+
+    public void onMessage(Message m) {
+        Bus origBus = BusFactory.getAndSetThreadDefaultBus(bus);
+        ClassLoaderHolder origLoader = null;
+        try {
+            if (loader != null) {
+                origLoader = ClassLoaderUtils.setThreadContextClassloader(loader);
+            }
+            InterceptorChain phaseChain;
+
+            if (m.getInterceptorChain() != null) {
+                phaseChain = m.getInterceptorChain();
+                // To make sure the phase chain is run by one thread once
+                synchronized (phaseChain) {
+                    if (phaseChain.getState() == InterceptorChain.State.PAUSED
+                        || phaseChain.getState() == InterceptorChain.State.SUSPENDED) {
+                        phaseChain.resume();
+                        return;
+                    }
+                }
+            }
+
+            Message message = getBinding().createMessage(m);
+            Exchange exchange = message.getExchange();
+            if (exchange == null) {
+                exchange = new ExchangeImpl();
+                m.setExchange(exchange);
+            }
+            exchange.setInMessage(message);
+            setExchangeProperties(exchange, message);
+
+            InterceptorProvider dbp = null;
+            if (endpoint.getService().getDataBinding() instanceof InterceptorProvider) {
+                dbp = (InterceptorProvider)endpoint.getService().getDataBinding();
+            }
+            // setup chain
+            if (dbp == null) {
+                phaseChain = chainCache.get(bus.getExtension(PhaseManager.class).getInPhases(),
+                                                             bus.getInInterceptors(),
+                                                             endpoint.getService().getInInterceptors(),
+                                                             endpoint.getInInterceptors(),
+                                                             getBinding().getInInterceptors());
+            } else {
+                phaseChain = chainCache.get(bus.getExtension(PhaseManager.class).getInPhases(),
+                                            bus.getInInterceptors(),
+                                            endpoint.getService().getInInterceptors(),
+                                            endpoint.getInInterceptors(),
+                                            getBinding().getInInterceptors(),
+                                            dbp.getInInterceptors());
+            }
+
+
+
+            message.setInterceptorChain(phaseChain);
+
+            phaseChain.setFaultObserver(endpoint.getOutFaultObserver());
+
+            addToChain(phaseChain, message);
+
+            phaseChain.doIntercept(message);
+
+        } finally {
+            if (origBus != bus) {
+                BusFactory.setThreadDefaultBus(origBus);
+            }
+            if (origLoader != null) {
+                origLoader.reset();
+            }
+        }
+    }
+    private void addToChain(InterceptorChain chain, Message m) {
+        Collection<InterceptorProvider> providers
+            = CastUtils.cast((Collection<?>)m.get(Message.INTERCEPTOR_PROVIDERS));
+        if (providers != null) {
+            for (InterceptorProvider p : providers) {
+                chain.add(p.getInInterceptors());
+            }
+        }
+        Collection<Interceptor<? extends Message>> is
+            = CastUtils.cast((Collection<?>)m.get(Message.IN_INTERCEPTORS));
+        if (is != null) {
+            chain.add(is);
+        }
+        if (m.getDestination() instanceof InterceptorProvider) {
+            chain.add(((InterceptorProvider)m.getDestination()).getInInterceptors());
+        }
+    }
+
+    protected Binding getBinding() {
+        return endpoint.getBinding();
+    }
+
+    protected void setExchangeProperties(Exchange exchange, Message m) {
+        exchange.put(Endpoint.class, endpoint);
+        exchange.put(Binding.class, getBinding());
+        exchange.put(Bus.class, bus);
+        if (exchange.getDestination() == null) {
+            exchange.setDestination(m.getDestination());
+        }
+        if (endpoint != null && endpoint.getService() != null) {
+            exchange.put(Service.class, endpoint.getService());
+
+            EndpointInfo endpointInfo = endpoint.getEndpointInfo();
+
+            if (endpointInfo.getService() != null)  {
+                QName serviceQName = endpointInfo.getService().getName();
+                exchange.put(Message.WSDL_SERVICE, serviceQName);
+
+                QName interfaceQName = endpointInfo.getService().getInterface().getName();
+                exchange.put(Message.WSDL_INTERFACE, interfaceQName);
+
+
+                QName portQName = endpointInfo.getName();
+                exchange.put(Message.WSDL_PORT, portQName);
+                URI wsdlDescription = endpointInfo.getProperty("URI", URI.class);
+                if (wsdlDescription == null && !endpointInfo.hasProperty("URI")) {
+                    String address = endpointInfo.getAddress();
+                    try {
+                        wsdlDescription = new URI(address + "?wsdl");
+                    } catch (URISyntaxException e) {
+                        // do nothing
+                    }
+                    endpointInfo.setProperty("URI", wsdlDescription);
+                }
+                exchange.put(Message.WSDL_DESCRIPTION, wsdlDescription);
+            }
+        } else {
+            exchange.put(Service.class, null);
+        }
+    }
+
+    public Endpoint getEndpoint() {
+        return endpoint;
+    }
+
+}
diff --git a/transform/src/patch/java/org/apache/cxf/validation/AbstractBeanValidationInterceptor.java b/transform/src/patch/java/org/apache/cxf/validation/AbstractBeanValidationInterceptor.java
new file mode 100644
index 0000000..3fecf1a
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/validation/AbstractBeanValidationInterceptor.java
@@ -0,0 +1,65 @@
+/**
+ * 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.cxf.validation;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import javax.validation.ValidationException;
+
+import org.apache.cxf.message.Message;
+
+public abstract class AbstractBeanValidationInterceptor extends AbstractValidationInterceptor {
+    protected AbstractBeanValidationInterceptor(String phase) {
+        super(phase);
+    }
+
+    @Override
+    protected Object getServiceObject(Message message) {
+        return checkNotNull(super.getServiceObject(message), "SERVICE_OBJECT_NULL");
+    }
+
+    @Override
+    protected Method getServiceMethod(Message message) {
+        return (Method)checkNotNull(super.getServiceMethod(message), "SERVICE_METHOD_NULL");
+    }
+
+    private Object checkNotNull(Object object, String name) {
+        if (object == null) {
+            String message = new org.apache.cxf.common.i18n.Message(name, BUNDLE).toString();
+            LOG.severe(message);
+            throw new ValidationException(message);
+        }
+        return object;
+    }
+
+    @Override
+    protected void handleValidation(final Message message, final Object resourceInstance,
+                                    final Method method, final List<Object> arguments) {
+        if (!arguments.isEmpty()) {
+            BeanValidationProvider provider = getProvider(message);
+            provider.validateParameters(resourceInstance, method, unwrapArgs(arguments).toArray());
+            message.getExchange().put(BeanValidationProvider.class, provider);
+        }
+    }
+
+    protected List<Object> unwrapArgs(List<Object> arguments) {
+        return arguments;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/workqueue/AutomaticWorkQueueImpl.java b/transform/src/patch/java/org/apache/cxf/workqueue/AutomaticWorkQueueImpl.java
new file mode 100644
index 0000000..bff113e
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/workqueue/AutomaticWorkQueueImpl.java
@@ -0,0 +1,619 @@
+/**
+ * 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.cxf.workqueue;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.classloader.ClassLoaderUtils.ClassLoaderHolder;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ReflectionUtil;
+
+@NoJSR250Annotations
+public class AutomaticWorkQueueImpl implements AutomaticWorkQueue {
+    public static final String PROPERTY_NAME = "name";
+    static final int DEFAULT_MAX_QUEUE_SIZE = 256;
+    private static final Logger LOG =
+        LogUtils.getL7dLogger(AutomaticWorkQueueImpl.class);
+
+
+    String name = "default";
+    int maxQueueSize;
+    int initialThreads;
+    int lowWaterMark;
+    int highWaterMark;
+    long dequeueTimeout;
+    AtomicInteger approxThreadCount = new AtomicInteger();
+
+    ThreadPoolExecutor executor;
+    Method addWorkerMethod;
+    Object[] addWorkerArgs;
+
+    AWQThreadFactory threadFactory;
+    ReentrantLock mainLock;
+    final ReentrantLock addThreadLock = new ReentrantLock();
+
+    DelayQueue<DelayedTaskWrapper> delayQueue;
+    WatchDog watchDog;
+
+    boolean shared;
+    int sharedCount;
+
+    private List<PropertyChangeListener> changeListenerList;
+
+    public AutomaticWorkQueueImpl() {
+        this(DEFAULT_MAX_QUEUE_SIZE);
+    }
+    public AutomaticWorkQueueImpl(String name) {
+        this(DEFAULT_MAX_QUEUE_SIZE, name);
+    }
+    public AutomaticWorkQueueImpl(int max) {
+        this(max, "default");
+    }
+    public AutomaticWorkQueueImpl(int max, String name) {
+        this(max,
+             0,
+             25,
+             5,
+             2 * 60 * 1000L,
+             name);
+    }
+    public AutomaticWorkQueueImpl(int mqs,
+                                  int initialThreads,
+                                  int highWaterMark,
+                                  int lowWaterMark,
+                                  long dequeueTimeout) {
+        this(mqs, initialThreads, highWaterMark, lowWaterMark, dequeueTimeout, "default");
+    }
+    public AutomaticWorkQueueImpl(int mqs,
+                                  int initialThreads,
+                                  int highWaterMark,
+                                  int lowWaterMark,
+                                  long dequeueTimeout,
+                                  String name) {
+        this.maxQueueSize = mqs == -1 ? DEFAULT_MAX_QUEUE_SIZE : mqs;
+        this.initialThreads = initialThreads;
+        this.highWaterMark = -1 == highWaterMark ? Integer.MAX_VALUE : highWaterMark;
+        this.lowWaterMark = -1 == lowWaterMark ? Integer.MAX_VALUE : lowWaterMark;
+        this.dequeueTimeout = dequeueTimeout;
+        this.name = name;
+        this.changeListenerList = new ArrayList<>();
+    }
+
+    public void addChangeListener(PropertyChangeListener listener) {
+        this.changeListenerList.add(listener);
+    }
+
+    public void removeChangeListener(PropertyChangeListener listener) {
+        this.changeListenerList.remove(listener);
+    }
+
+    public void notifyChangeListeners(PropertyChangeEvent event) {
+        for (PropertyChangeListener listener : changeListenerList) {
+            listener.propertyChange(event);
+        }
+    }
+
+    public void setShared(boolean shared) {
+        this.shared = shared;
+    }
+    public boolean isShared() {
+        return shared;
+    }
+    public void addSharedUser() {
+        sharedCount++;
+    }
+    public void removeSharedUser() {
+        sharedCount--;
+    }
+    public int getShareCount() {
+        return sharedCount;
+    }
+
+    protected synchronized ThreadPoolExecutor getExecutor() {
+        if (executor == null) {
+            threadFactory = createThreadFactory(name);
+            executor = new ThreadPoolExecutor(lowWaterMark,
+                                              highWaterMark,
+                                              TimeUnit.MILLISECONDS.toMillis(dequeueTimeout),
+                                              TimeUnit.MILLISECONDS,
+                                              new LinkedBlockingQueue<Runnable>(maxQueueSize),
+                                              threadFactory) {
+                @Override
+                protected void terminated() {
+                    ThreadFactory f = executor.getThreadFactory();
+                    if (f instanceof AWQThreadFactory) {
+                        ((AWQThreadFactory)f).shutdown();
+                    }
+                    if (watchDog != null) {
+                        watchDog.shutdown();
+                    }
+                }
+            };
+
+
+            if (LOG.isLoggable(Level.FINE)) {
+                StringBuilder buf = new StringBuilder(128).append("Constructing automatic work queue with:\n")
+                        .append("max queue size: ").append(maxQueueSize).append('\n')
+                        .append("initialThreads: ").append(initialThreads).append('\n')
+                        .append("lowWaterMark: ").append(lowWaterMark).append('\n')
+                        .append("highWaterMark: ").append(highWaterMark).append('\n');
+                LOG.fine(buf.toString());
+            }
+
+            if (initialThreads > highWaterMark) {
+                initialThreads = highWaterMark;
+            }
+
+            // as we cannot prestart more core than corePoolSize initial threads, we temporarily
+            // change the corePoolSize to the number of initial threads
+            // this is important as otherwise these threads will be created only when
+            // the queue has filled up,
+            // potentially causing problems with starting up under heavy load
+            if (initialThreads < Integer.MAX_VALUE && initialThreads > 0) {
+                executor.setCorePoolSize(initialThreads);
+                int started = executor.prestartAllCoreThreads();
+                if (started < initialThreads) {
+                    LOG.log(Level.WARNING, "THREAD_START_FAILURE_MSG",
+                            new Object[] {started, initialThreads});
+                }
+                executor.setCorePoolSize(lowWaterMark);
+            }
+
+            ReentrantLock l;
+            try {
+                Field f = ThreadPoolExecutor.class.getDeclaredField("mainLock");
+                ReflectionUtil.setAccessible(f);
+                l = (ReentrantLock)f.get(executor);
+            } catch (Throwable t) {
+                l = new ReentrantLock();
+            }
+            mainLock = l;
+
+
+            try {
+                //java 7
+                addWorkerMethod = ThreadPoolExecutor.class.getDeclaredMethod("addWorker",
+                                                                             Runnable.class, Boolean.TYPE);
+                addWorkerArgs = new Object[] {null, Boolean.FALSE};
+            } catch (Throwable t2) {
+                //nothing we cando
+            }
+        }
+        return executor;
+    }
+    private AWQThreadFactory createThreadFactory(final String nm) {
+        ThreadGroup group;
+        try {
+            //Try and find the highest level ThreadGroup that we're allowed to use.
+            //That SHOULD allow the default classloader and thread locals and such
+            //to be the least likely to cause issues down the road.
+            group = AccessController.doPrivileged(
+                new PrivilegedAction<ThreadGroup>() {
+                    public ThreadGroup run() {
+                        ThreadGroup group = Thread.currentThread().getThreadGroup();
+                        ThreadGroup parent = group;
+                        try {
+                            while (parent != null) {
+                                group = parent;
+                                parent = parent.getParent();
+                            }
+                        } catch (SecurityException se) {
+                            //ignore - if we get here, the "group" is as high as
+                            //the security manager will allow us to go.   Use that one.
+                        }
+                        return new ThreadGroup(group, nm + "-workqueue");
+                    }
+                }
+            );
+        } catch (SecurityException e) {
+            group = new ThreadGroup(nm + "-workqueue");
+        }
+        return new AWQThreadFactory(group, nm);
+    }
+
+    static class DelayedTaskWrapper implements Delayed, Runnable {
+        long trigger;
+        Runnable work;
+
+        DelayedTaskWrapper(Runnable work, long delay) {
+            this.work = work;
+            trigger = System.currentTimeMillis() + delay;
+        }
+
+        public long getDelay(TimeUnit unit) {
+            long n = trigger - System.currentTimeMillis();
+            return unit.convert(n, TimeUnit.MILLISECONDS);
+        }
+
+        public int compareTo(Delayed delayed) {
+            long other = ((DelayedTaskWrapper)delayed).trigger;
+            int returnValue;
+            if (this.trigger < other) {
+                returnValue = -1;
+            } else if (this.trigger > other) {
+                returnValue = 1;
+            } else {
+                returnValue = 0;
+            }
+            return returnValue;
+        }
+
+        public void run() {
+            work.run();
+        }
+
+    }
+
+    class WatchDog extends Thread {
+        DelayQueue<DelayedTaskWrapper> delayQueue;
+        AtomicBoolean shutdown = new AtomicBoolean(false);
+
+        WatchDog(DelayQueue<DelayedTaskWrapper> queue) {
+            delayQueue = queue;
+        }
+
+        public void shutdown() {
+            shutdown.set(true);
+            // to exit the waiting thread
+            interrupt();
+        }
+
+        public void run() {
+            DelayedTaskWrapper task;
+            try {
+                while (!shutdown.get()) {
+                    task = delayQueue.take();
+                    if (task != null) {
+                        try {
+                            execute(task);
+                        } catch (Exception ex) {
+                            LOG.warning("Executing the task from DelayQueue with exception: " + ex);
+                        }
+                    }
+                }
+            } catch (InterruptedException e) {
+                if (LOG.isLoggable(Level.FINE)) {
+                    LOG.finer("The DelayQueue watchdog Task is stopping");
+                }
+            }
+
+        }
+
+    }
+    class AWQThreadFactory implements ThreadFactory {
+        final AtomicInteger threadNumber = new AtomicInteger(1);
+        ThreadGroup group;
+        String name;
+        ClassLoader loader;
+
+        AWQThreadFactory(ThreadGroup gp, String nm) {
+            group = gp;
+            name = nm;
+            //force the loader to be the loader of CXF, not the application loader
+            loader = AutomaticWorkQueueImpl.class.getClassLoader();
+        }
+
+        public Thread newThread(final Runnable r) {
+            if (group.isDestroyed()) {
+                group = new ThreadGroup(group.getParent(), name + "-workqueue");
+            }
+            Runnable wrapped = new Runnable() {
+                public void run() {
+                    approxThreadCount.incrementAndGet();
+                    try {
+                        r.run();
+                    } finally {
+                        approxThreadCount.decrementAndGet();
+                    }
+                }
+            };
+            final Thread t = new Thread(group,
+                                  wrapped,
+                                  name + "-workqueue-" + threadNumber.getAndIncrement(),
+                                  0);
+            AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+                public Boolean run() {
+                    t.setContextClassLoader(loader);
+                    return true;
+                }
+            });
+            t.setDaemon(true);
+            if (t.getPriority() != Thread.NORM_PRIORITY) {
+                t.setPriority(Thread.NORM_PRIORITY);
+            }
+            return t;
+        }
+        public void setName(String s) {
+            name = s;
+        }
+        public void shutdown() {
+            if (!group.isDestroyed()) {
+                try {
+                    group.destroy();
+                    group.setDaemon(true);
+                } catch (Throwable t) {
+                    //ignore
+                }
+            }
+        }
+    }
+
+    public void setName(String s) {
+        name = s;
+        if (threadFactory != null) {
+            threadFactory.setName(s);
+        }
+    }
+    public String getName() {
+        return name;
+    }
+
+    public String toString() {
+        return new StringBuilder(super.toString())
+                .append(" [queue size: ").append(getSize())
+                .append(", max size: ").append(maxQueueSize)
+                .append(", threads: ").append(getPoolSize())
+                .append(", active threads: ").append(getActiveCount())
+                .append(", low water mark: ").append(getLowWaterMark())
+                .append(", high water mark: ").append(getHighWaterMark())
+                .append(']').toString();
+    }
+
+    public void execute(final Runnable command) {
+        //Grab the context classloader of this thread.   We'll make sure we use that
+        //on the thread the runnable actually runs on.
+
+        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        Runnable r = new Runnable() {
+            public void run() {
+                ClassLoaderHolder orig = ClassLoaderUtils.setThreadContextClassloader(loader);
+                try {
+                    command.run();
+                } finally {
+                    if (orig != null) {
+                        orig.reset();
+                    }
+                }
+            }
+        };
+        //The ThreadPoolExecutor in the JDK doesn't expand the number
+        //of threads until the queue is full.   However, we would
+        //prefer the number of threads to expand immediately and
+        //only uses the queue if we've reached the maximum number
+        //of threads.
+        ThreadPoolExecutor ex = getExecutor();
+        ex.execute(r);
+        if (addWorkerMethod != null
+            && !ex.getQueue().isEmpty()
+            && this.approxThreadCount.get() < highWaterMark
+            && addThreadLock.tryLock()) {
+            try {
+                mainLock.lock();
+                try {
+                    int ps = this.getPoolSize();
+                    int sz = executor.getQueue().size();
+                    int sz2 = this.getActiveCount();
+
+                    if ((sz + sz2) > ps) {
+                        // Needs --add-opens java.base/java.util.concurrent=ALL-UNNAMED for JDK16+
+                        ReflectionUtil.setAccessible(addWorkerMethod).invoke(executor, addWorkerArgs);
+                    }
+                } catch (Exception exc) {
+                    //ignore
+                } finally {
+                    mainLock.unlock();
+                }
+            } finally {
+                addThreadLock.unlock();
+            }
+        }
+    }
+
+    // WorkQueue interface
+    public void execute(Runnable work, long timeout) {
+        try {
+            execute(work);
+        } catch (RejectedExecutionException ree) {
+            try {
+                if (!getExecutor().getQueue().offer(work, timeout, TimeUnit.MILLISECONDS)) {
+                    throw ree;
+                }
+            } catch (InterruptedException ie) {
+                throw ree;
+            }
+        }
+    }
+
+    public synchronized void schedule(final Runnable work, final long delay) {
+        if (delayQueue == null) {
+            delayQueue = new DelayQueue<>();
+            watchDog = new WatchDog(delayQueue);
+            watchDog.setDaemon(true);
+            watchDog.start();
+        }
+        delayQueue.put(new DelayedTaskWrapper(work, delay));
+    }
+
+    // AutomaticWorkQueue interface
+
+    public void shutdown(boolean processRemainingWorkItems) {
+        if (executor != null) {
+            if (!processRemainingWorkItems) {
+                executor.getQueue().clear();
+            }
+            executor.shutdown();
+        }
+    }
+
+
+    /**
+     * Gets the maximum size (capacity) of the backing queue.
+     * @return the maximum size (capacity) of the backing queue.
+     */
+    public long getMaxSize() {
+        return maxQueueSize;
+    }
+
+    /**
+     * Gets the current size of the backing queue.
+     * @return the current size of the backing queue.
+     */
+    public long getSize() {
+        return executor == null ? 0 : executor.getQueue().size();
+    }
+
+
+    public boolean isEmpty() {
+        return executor == null || executor.getQueue().isEmpty();
+    }
+
+    public boolean isFull() {
+        return executor != null && executor.getQueue().remainingCapacity() == 0;
+    }
+
+    public int getHighWaterMark() {
+        int hwm = executor == null ? highWaterMark : executor.getMaximumPoolSize();
+        return hwm == Integer.MAX_VALUE ? -1 : hwm;
+    }
+
+    public int getLowWaterMark() {
+        int lwm = executor == null ? lowWaterMark : executor.getCorePoolSize();
+        return lwm == Integer.MAX_VALUE ? -1 : lwm;
+    }
+
+    public int getInitialSize() {
+        return this.initialThreads;
+    }
+
+    public void setHighWaterMark(int hwm) {
+        highWaterMark = hwm < 0 ? Integer.MAX_VALUE : hwm;
+        if (executor != null) {
+            notifyChangeListeners(new PropertyChangeEvent(this, "highWaterMark",
+                                                          this.executor.getMaximumPoolSize(), hwm));
+            executor.setMaximumPoolSize(highWaterMark);
+        }
+    }
+
+    public void setLowWaterMark(int lwm) {
+        lowWaterMark = lwm < 0 ? 0 : lwm;
+        if (executor != null) {
+            notifyChangeListeners(new PropertyChangeEvent(this, "lowWaterMark",
+                                                          this.executor.getCorePoolSize(), lwm));
+            executor.setCorePoolSize(lowWaterMark);
+        }
+    }
+
+    public void setInitialSize(int initialSize) {
+        notifyChangeListeners(new PropertyChangeEvent(this, "initialSize", this.initialThreads, initialSize));
+        this.initialThreads = initialSize;
+    }
+
+    public void setQueueSize(int size) {
+        notifyChangeListeners(new PropertyChangeEvent(this, "queueSize", this.maxQueueSize, size));
+        this.maxQueueSize = size;
+    }
+
+    public void setDequeueTimeout(long l) {
+        notifyChangeListeners(new PropertyChangeEvent(this, "dequeueTimeout", this.dequeueTimeout, l));
+        this.dequeueTimeout = l;
+    }
+
+    public boolean isShutdown() {
+        if (executor == null) {
+            return false;
+        }
+        return executor.isShutdown();
+    }
+    public int getLargestPoolSize() {
+        if (executor == null) {
+            return 0;
+        }
+        return executor.getLargestPoolSize();
+    }
+    public int getPoolSize() {
+        if (executor == null) {
+            return 0;
+        }
+        return executor.getPoolSize();
+    }
+    public int getActiveCount() {
+        if (executor == null) {
+            return 0;
+        }
+        return executor.getActiveCount();
+    }
+    public void update(Dictionary<String, String> config) {
+        String s = config.get("highWaterMark");
+        if (s != null) {
+            this.highWaterMark = Integer.parseInt(s);
+        }
+        s = config.get("lowWaterMark");
+        if (s != null) {
+            this.lowWaterMark = Integer.parseInt(s);
+        }
+        s = config.get("initialSize");
+        if (s != null) {
+            this.initialThreads = Integer.parseInt(s);
+        }
+        s = config.get("dequeueTimeout");
+        if (s != null) {
+            this.dequeueTimeout = Long.parseLong(s);
+        }
+        s = config.get("queueSize");
+        if (s != null) {
+            this.maxQueueSize = Integer.parseInt(s);
+        }
+    }
+    public Dictionary<String, String> getProperties() {
+        Dictionary<String, String> properties = new Hashtable<>();
+        NumberFormat nf = NumberFormat.getIntegerInstance();
+        properties.put("name", nf.format(getName()));
+        properties.put("highWaterMark", nf.format(getHighWaterMark()));
+        properties.put("lowWaterMark", nf.format(getLowWaterMark()));
+        properties.put("initialSize", nf.format(getLowWaterMark()));
+        properties.put("dequeueTimeout", nf.format(getLowWaterMark()));
+        properties.put("queueSize", nf.format(getLowWaterMark()));
+        return properties;
+    }
+}
diff --git a/transform/src/patch/java/org/apache/cxf/ws/addressing/MAPAggregator.java b/transform/src/patch/java/org/apache/cxf/ws/addressing/MAPAggregator.java
new file mode 100644
index 0000000..206494d
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/ws/addressing/MAPAggregator.java
@@ -0,0 +1,224 @@
+/**
+ * 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.cxf.ws.addressing;
+
+import java.util.Collection;
+
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.phase.PhaseInterceptor;
+
+/**
+ * Logical Handler responsible for aggregating the Message Addressing
+ * Properties for outgoing messages.
+ */
+public class MAPAggregator extends AbstractPhaseInterceptor<Message> {
+    public static final String USING_ADDRESSING = MAPAggregator.class.getName() + ".usingAddressing";
+    public static final String ADDRESSING_DISABLED = MAPAggregator.class.getName() + ".addressingDisabled";
+    public static final String DECOUPLED_DESTINATION = MAPAggregator.class.getName()
+        + ".decoupledDestination";
+    public static final String ACTION_VERIFIED = MAPAggregator.class.getName() + ".actionVerified";
+    public static final String ADDRESSING_NAMESPACE = MAPAggregator.class.getName() + ".addressingNamespace";
+
+    public interface MAPAggregatorLoader {
+        MAPAggregator createImplementation(MAPAggregator mag);
+    }
+
+    protected MessageIdCache messageIdCache;
+    protected boolean usingAddressingAdvisory = true;
+    protected boolean addressingRequired;
+    protected boolean allowDuplicates = true;
+    protected WSAddressingFeature.AddressingResponses addressingResponses
+        = WSAddressingFeature.AddressingResponses.ALL;
+
+    /**
+     * The real implementation of the MAPAggregator interceptor
+     */
+    private MAPAggregator impl;
+
+    /**
+     * Constructor.
+     */
+    public MAPAggregator() {
+        super(MAPAggregator.class.getName(), Phase.PRE_LOGICAL);
+        addBefore("org.apache.cxf.interceptor.OneWayProcessorInterceptor");
+    }
+
+    /**
+     * Indicates if duplicate messageIDs are allowed.
+     * @return true if duplicate messageIDs are allowed
+     */
+    public boolean allowDuplicates() {
+        if (impl != null) {
+            return impl.allowDuplicates();
+        }
+        return allowDuplicates;
+    }
+
+    /**
+     * Allows/disallows duplicate messageIdDs.
+     * @param ad whether duplicate messageIDs are allowed
+     */
+    public void setAllowDuplicates(boolean ad) {
+        if (impl != null) {
+            impl.setAllowDuplicates(ad);
+        }
+        allowDuplicates = ad;
+    }
+
+    /**
+     * Whether the presence of the <wsaw:UsingAddressing> element
+     * in the WSDL is purely advisory, i.e. its absence doesn't prevent
+     * the encoding of WS-A headers.
+     *
+     * @return true if the presence of the <wsaw:UsingAddressing> element is
+     * advisory
+     */
+    public boolean isUsingAddressingAdvisory() {
+        if (impl != null) {
+            return impl.isUsingAddressingAdvisory();
+        }
+        return usingAddressingAdvisory;
+    }
+
+    /**
+     * Controls whether the presence of the <wsaw:UsingAddressing> element
+     * in the WSDL is purely advisory, i.e. its absence doesn't prevent
+     * the encoding of WS-A headers.
+     *
+     * @param advisory true if the presence of the <wsaw:UsingAddressing>
+     * element is to be advisory
+     */
+    public void setUsingAddressingAdvisory(boolean advisory) {
+        if (impl != null) {
+            impl.setUsingAddressingAdvisory(advisory);
+        }
+        usingAddressingAdvisory = advisory;
+    }
+
+    /**
+     * Whether the use of addressing is completely required for this endpoint
+     *
+     * @return true if addressing is required
+     */
+    public boolean isAddressingRequired() {
+        if (impl != null) {
+            return impl.addressingRequired;
+        }
+        return addressingRequired;
+    }
+    /**
+     * Sets whether the use of addressing is completely required for this endpoint
+     *
+     */
+    public void setAddressingRequired(boolean required) {
+        if (impl != null) {
+            impl.setAddressingRequired(required);
+        }
+        addressingRequired = required;
+    }
+
+    /**
+     * Sets Addresing Response
+     *
+     */
+    public void setAddressingResponses(WSAddressingFeature.AddressingResponses responses) {
+        if (impl != null) {
+            impl.setAddressingResponses(responses);
+        }
+        addressingResponses = responses;
+    }
+
+    /**
+     * Returns the cache used to enforce duplicate message IDs when
+     * {@link #allowDuplicates()} returns {@code false}.
+     *
+     * @return the cache used to enforce duplicate message IDs
+     */
+    public MessageIdCache getMessageIdCache() {
+        if (impl != null) {
+            return impl.getMessageIdCache();
+        }
+        return messageIdCache;
+    }
+
+    /**
+     * Sets the cache used to enforce duplicate message IDs when
+     * {@link #allowDuplicates()} returns {@code false}.
+     *
+     * @param messageIdCache the cache to use
+     *
+     * @throws NullPointerException if {@code messageIdCache} is {@code null}
+     */
+    public void setMessageIdCache(MessageIdCache messageIdCache) {
+        if (messageIdCache == null) {
+            throw new NullPointerException("messageIdCache cannot be null.");
+        }
+        if (impl != null) {
+            impl.setMessageIdCache(messageIdCache);
+        }
+        this.messageIdCache = messageIdCache;
+    }
+
+    /**
+     * Sets Addressing Response
+     *
+     */
+    public WSAddressingFeature.AddressingResponses getAddressingResponses() {
+        if (impl != null) {
+            return impl.getAddressingResponses();
+        }
+        return addressingResponses;
+    }
+
+    /**
+     * Invoked for normal processing of inbound and outbound messages.
+     *
+     * @param message the current message
+     */
+    public void handleMessage(Message message) {
+        if (impl == null) {
+            //load impl
+            MAPAggregatorLoader loader = message.getExchange().getBus()
+                .getExtension(MAPAggregatorLoader.class);
+            impl = loader.createImplementation(this);
+        }
+        impl.handleMessage(message);
+    }
+
+    @Override
+    public void handleFault(Message message) {
+        if (impl != null) {
+            impl.handleFault(message);
+        }
+    }
+
+
+    @Override
+    public Collection<PhaseInterceptor<? extends Message>> getAdditionalInterceptors() {
+        if (impl != null) {
+            return impl.getAdditionalInterceptors();
+        }
+        return super.getAdditionalInterceptors();
+    }
+
+
+}
