diff --git a/jakarta/pom.xml b/jakarta/pom.xml
deleted file mode 100644
index f386e35..0000000
--- a/jakarta/pom.xml
+++ /dev/null
@@ -1,337 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<!-- $Rev: 600338 $ $Date: 2007-12-02 09:08:04 -0800 (Sun, 02 Dec 2007) $ -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
-  <parent>
-    <artifactId>tomee-project</artifactId>
-    <groupId>org.apache.tomee</groupId>
-    <version>8.0.3-SNAPSHOT</version>
-  </parent>
-
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>org.apache.tomee.jakarta</groupId>
-  <artifactId>apache-tomee</artifactId>
-  <version>9.0.0-M1-SNAPSHOT</version>
-  <packaging>jar</packaging>
-  <name>TomEE :: TomEE :: Apache TomEE 9</name>
-
-  <properties>
-    <tomee.version>8.0.3</tomee.version>
-    <tomee.build.name>${project.groupId}.tomee.tomee</tomee.build.name>
-    <webprofile.work-dir>${project.build.directory}/webprofile-work-dir</webprofile.work-dir>
-    <plus.work-dir>${project.build.directory}/plus-work-dir</plus.work-dir>
-    <plume.work-dir>${project.build.directory}/plume-work-dir</plume.work-dir>
-    <microprofile.work-dir>${project.build.directory}/microprofile-work-dir</microprofile.work-dir>
-  </properties>
-
-  <dependencies>
-    <dependency> <!-- to be sure to have it -->
-      <groupId>org.apache.tomee</groupId>
-      <artifactId>apache-tomee</artifactId>
-      <version>${tomee.version}</version>
-      <classifier>webprofile</classifier>
-      <type>zip</type>
-      <scope>provided</scope>
-      <exclusions>
-        <exclusion>
-          <groupId>*</groupId>
-          <artifactId>*</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency> <!-- to be sure to have it -->
-      <groupId>org.apache.tomee</groupId>
-      <artifactId>apache-tomee</artifactId>
-      <version>${tomee.version}</version>
-      <classifier>microprofile</classifier>
-      <type>zip</type>
-      <scope>provided</scope>
-      <exclusions>
-        <exclusion>
-          <groupId>*</groupId>
-          <artifactId>*</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency> <!-- to be sure to have it -->
-      <groupId>org.apache.tomee</groupId>
-      <artifactId>apache-tomee</artifactId>
-      <version>${tomee.version}</version>
-      <classifier>plume</classifier>
-      <type>zip</type>
-      <scope>provided</scope>
-      <exclusions>
-        <exclusion>
-          <groupId>*</groupId>
-          <artifactId>*</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency> <!-- to be sure to have it -->
-      <groupId>org.apache.tomee</groupId>
-      <artifactId>apache-tomee</artifactId>
-      <version>${tomee.version}</version>
-      <classifier>plus</classifier>
-      <type>zip</type>
-      <scope>provided</scope>
-      <exclusions>
-        <exclusion>
-          <groupId>*</groupId>
-          <artifactId>*</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <resources>
-      <resource>
-        <directory>src/main/resources</directory>
-        <filtering>true</filtering>
-      </resource>
-      <resource>
-        <directory>src/main/resources</directory>
-        <filtering>false</filtering>
-      </resource>
-    </resources>
-
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>unpack-webprofile</id>
-            <phase>process-resources</phase>
-            <goals>
-              <goal>unpack</goal>
-            </goals>
-            <configuration>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>org.apache.tomee</groupId>
-                  <artifactId>apache-tomee</artifactId>
-                  <version>${tomee.version}</version>
-                  <classifier>webprofile</classifier>
-                  <type>zip</type>
-                  <outputDirectory>${webprofile.work-dir}</outputDirectory>
-                </artifactItem>
-              </artifactItems>
-            </configuration>
-          </execution>
-          <execution>
-            <id>unpack-microprofile</id>
-            <phase>process-resources</phase>
-            <goals>
-              <goal>unpack</goal>
-            </goals>
-            <configuration>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>org.apache.tomee</groupId>
-                  <artifactId>apache-tomee</artifactId>
-                  <version>${tomee.version}</version>
-                  <classifier>microprofile</classifier>
-                  <type>zip</type>
-                  <outputDirectory>${microprofile.work-dir}</outputDirectory>
-                </artifactItem>
-              </artifactItems>
-            </configuration>
-          </execution>
-          <execution>
-            <id>unpack-plume</id>
-            <phase>process-resources</phase>
-            <goals>
-              <goal>unpack</goal>
-            </goals>
-            <configuration>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>org.apache.tomee</groupId>
-                  <artifactId>apache-tomee</artifactId>
-                  <version>${tomee.version}</version>
-                  <classifier>plume</classifier>
-                  <type>zip</type>
-                  <outputDirectory>${plume.work-dir}</outputDirectory>
-                </artifactItem>
-              </artifactItems>
-            </configuration>
-          </execution>
-          <execution>
-            <id>unpack-plus</id>
-            <phase>process-resources</phase>
-            <goals>
-              <goal>unpack</goal>
-            </goals>
-            <configuration>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>org.apache.tomee</groupId>
-                  <artifactId>apache-tomee</artifactId>
-                  <version>${tomee.version}</version>
-                  <classifier>plus</classifier>
-                  <type>zip</type>
-                  <outputDirectory>${plus.work-dir}</outputDirectory>
-                </artifactItem>
-              </artifactItems>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>webprofile</id>
-            <phase>package</phase>
-            <configuration>
-              <descriptors>
-                <descriptor>src/main/assembly/tomee-webprofile.xml</descriptor>
-              </descriptors>
-              <attach>false</attach>
-              <appendAssemblyId>false</appendAssemblyId>
-              <finalName>apache-tomee-webprofile-${project.version}</finalName>
-            </configuration>
-            <goals>
-              <goal>single</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>plus</id>
-            <phase>package</phase>
-            <configuration>
-              <descriptors>
-                <descriptor>src/main/assembly/tomee-plus.xml</descriptor>
-              </descriptors>
-              <attach>false</attach>
-              <appendAssemblyId>false</appendAssemblyId>
-              <finalName>apache-tomee-plus-${project.version}</finalName>
-            </configuration>
-            <goals>
-              <goal>single</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>plume</id>
-            <phase>package</phase>
-            <configuration>
-              <descriptors>
-                <descriptor>src/main/assembly/tomee-plume.xml</descriptor>
-              </descriptors>
-              <attach>false</attach>
-              <appendAssemblyId>false</appendAssemblyId>
-              <finalName>apache-tomee-plume-${project.version}</finalName>
-            </configuration>
-            <goals>
-              <goal>single</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>microprofile</id>
-            <phase>package</phase>
-            <configuration>
-              <descriptors>
-                <descriptor>src/main/assembly/tomee-microprofile.xml</descriptor>
-              </descriptors>
-              <attach>false</attach>
-              <appendAssemblyId>false</appendAssemblyId>
-              <finalName>apache-tomee-microprofile-${project.version}</finalName>
-            </configuration>
-            <goals>
-              <goal>single</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>build-helper-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>attach-artifacts</id>
-            <phase>package</phase>
-            <goals>
-              <goal>attach-artifact</goal>
-            </goals>
-            <configuration>
-              <artifacts>
-                <artifact>
-                  <file>${project.build.directory}/apache-tomee-webprofile-${project.version}.zip</file>
-                  <type>zip</type>
-                  <classifier>webprofile</classifier>
-                </artifact>
-                <artifact>
-                  <file>${project.build.directory}/apache-tomee-plus-${project.version}.zip</file>
-                  <type>zip</type>
-                  <classifier>plus</classifier>
-                </artifact>
-                <artifact>
-                  <file>${project.build.directory}/apache-tomee-plume-${project.version}.zip</file>
-                  <type>zip</type>
-                  <classifier>plume</classifier>
-                </artifact>
-                <artifact>
-                  <file>${project.build.directory}/apache-tomee-microprofile-${project.version}.zip</file>
-                  <type>zip</type>
-                  <classifier>microprofile</classifier>
-                </artifact>
-              </artifacts>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.tomitribe.transformer</groupId>
-        <artifactId>org.eclipse.transformer.maven</artifactId>
-        <version>0.1.1a</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>run</goal>
-            </goals>
-            <phase>package</phase>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.tomee.patch</groupId>
-        <artifactId>tomee-patch-plugin</artifactId>
-        <version>0.1</version>
-        <configuration>
-          <select>apache-tomee.*\.zip</select>
-        </configuration>
-        <executions>
-          <execution>
-            <goals>
-              <goal>run</goal>
-            </goals>
-            <phase>package</phase>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-
-</project>
diff --git a/jakarta/src/main/assembly/tomee-microprofile.xml b/jakarta/src/main/assembly/tomee-microprofile.xml
deleted file mode 100644
index 6a1e49b..0000000
--- a/jakarta/src/main/assembly/tomee-microprofile.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<!-- $Rev: 576067 $ $Date: 2007-09-16 03:17:08 -0700 (Sun, 16 Sep 2007) $ -->
-
-<assembly>
-  <id>tomee-microprofile</id>
-  <formats>
-    <format>zip</format>
-  </formats>
-  <includeBaseDirectory>false</includeBaseDirectory>
-  <fileSets>
-    <fileSet>
-      <directory>${microprofile.work-dir}/apache-tomee-microprofile-${tomee.version}</directory>
-      <outputDirectory>/apache-tomee-microprofile-${project.version}</outputDirectory>
-      <includes>
-        <include>**/*</include>
-      </includes>
-    </fileSet>
-  </fileSets>
-</assembly>
-
diff --git a/jakarta/src/main/assembly/tomee-plume.xml b/jakarta/src/main/assembly/tomee-plume.xml
deleted file mode 100644
index bb71e05..0000000
--- a/jakarta/src/main/assembly/tomee-plume.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<!-- $Rev: 576067 $ $Date: 2007-09-16 03:17:08 -0700 (Sun, 16 Sep 2007) $ -->
-
-<assembly>
-  <id>tomee-plume</id>
-  <formats>
-    <format>zip</format>
-  </formats>
-  <includeBaseDirectory>false</includeBaseDirectory>
-  <fileSets>
-    <fileSet>
-      <directory>${plume.work-dir}/apache-tomee-plume-${tomee.version}</directory>
-      <outputDirectory>/apache-tomee-plume-${project.version}</outputDirectory>
-      <includes>
-        <include>**/*</include>
-      </includes>
-    </fileSet>
-  </fileSets>
-</assembly>
-
diff --git a/jakarta/src/main/assembly/tomee-plus.xml b/jakarta/src/main/assembly/tomee-plus.xml
deleted file mode 100644
index e0c5708..0000000
--- a/jakarta/src/main/assembly/tomee-plus.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<!-- $Rev: 576067 $ $Date: 2007-09-16 03:17:08 -0700 (Sun, 16 Sep 2007) $ -->
-
-<assembly>
-  <id>tomee-plus</id>
-  <formats>
-    <format>zip</format>
-  </formats>
-  <includeBaseDirectory>false</includeBaseDirectory>
-  <fileSets>
-    <fileSet>
-      <directory>${plus.work-dir}/apache-tomee-plus-${tomee.version}</directory>
-      <outputDirectory>/apache-tomee-plus-${project.version}</outputDirectory>
-      <includes>
-        <include>**/*</include>
-      </includes>
-    </fileSet>
-  </fileSets>
-</assembly>
-
diff --git a/jakarta/src/main/assembly/tomee-webprofile.xml b/jakarta/src/main/assembly/tomee-webprofile.xml
deleted file mode 100644
index 1777653..0000000
--- a/jakarta/src/main/assembly/tomee-webprofile.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<!-- $Rev: 576067 $ $Date: 2007-09-16 03:17:08 -0700 (Sun, 16 Sep 2007) $ -->
-
-<assembly>
-  <id>tomee-webprofile</id>
-  <formats>
-    <format>zip</format>
-  </formats>
-  <includeBaseDirectory>false</includeBaseDirectory>
-  <fileSets>
-    <fileSet>
-      <directory>${webprofile.work-dir}/apache-tomee-webprofile-${tomee.version}</directory>
-      <outputDirectory>/apache-tomee-webprofile-${project.version}</outputDirectory>
-      <includes>
-        <include>**/*</include>
-      </includes>
-    </fileSet>
-  </fileSets>
-</assembly>
-
diff --git a/jakarta/src/patch/java/org/apache/catalina/loader/WebappClassLoaderBase.java b/jakarta/src/patch/java/org/apache/catalina/loader/WebappClassLoaderBase.java
deleted file mode 100644
index 2e75d4c..0000000
--- a/jakarta/src/patch/java/org/apache/catalina/loader/WebappClassLoaderBase.java
+++ /dev/null
@@ -1,2725 +0,0 @@
-/*
- * 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.catalina.loader;
-
-import java.io.File;
-import java.io.FilePermission;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.IllegalClassFormatException;
-import java.lang.ref.Reference;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.security.AccessControlException;
-import java.security.AccessController;
-import java.security.CodeSource;
-import java.security.Permission;
-import java.security.PermissionCollection;
-import java.security.Policy;
-import java.security.PrivilegedAction;
-import java.security.ProtectionDomain;
-import java.security.cert.Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.ConcurrentModificationException;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NoSuchElementException;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.jar.Attributes;
-import java.util.jar.Attributes.Name;
-import java.util.jar.Manifest;
-
-import org.apache.catalina.Container;
-import org.apache.catalina.Globals;
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.LifecycleState;
-import org.apache.catalina.WebResource;
-import org.apache.catalina.WebResourceRoot;
-import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
-import org.apache.juli.WebappProperties;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
-import org.apache.tomcat.InstrumentableClassLoader;
-import org.apache.tomcat.util.ExceptionUtils;
-import org.apache.tomcat.util.IntrospectionUtils;
-import org.apache.tomcat.util.compat.JreCompat;
-import org.apache.tomcat.util.res.StringManager;
-import org.apache.tomcat.util.security.PermissionCheck;
-
-/**
- * Specialized web application class loader.
- * <p>
- * This class loader is a full reimplementation of the
- * <code>URLClassLoader</code> from the JDK. It is designed to be fully
- * compatible with a normal <code>URLClassLoader</code>, although its internal
- * behavior may be completely different.
- * <p>
- * <strong>IMPLEMENTATION NOTE</strong> - By default, this class loader follows
- * the delegation model required by the specification. The system class
- * loader will be queried first, then the local repositories, and only then
- * delegation to the parent class loader will occur. This allows the web
- * application to override any shared class except the classes from J2SE.
- * Special handling is provided from the JAXP XML parser interfaces, the JNDI
- * interfaces, and the classes from the servlet API, which are never loaded
- * from the webapp repositories. The <code>delegate</code> property
- * allows an application to modify this behavior to move the parent class loader
- * ahead of the local repositories.
- * <p>
- * <strong>IMPLEMENTATION NOTE</strong> - Due to limitations in Jasper
- * compilation technology, any repository which contains classes from
- * the servlet API will be ignored by the class loader.
- * <p>
- * <strong>IMPLEMENTATION NOTE</strong> - The class loader generates source
- * URLs which include the full JAR URL when a class is loaded from a JAR file,
- * which allows setting security permission at the class level, even when a
- * class is contained inside a JAR.
- * <p>
- * <strong>IMPLEMENTATION NOTE</strong> - Local repositories are searched in
- * the order they are added via the initial constructor.
- * <p>
- * <strong>IMPLEMENTATION NOTE</strong> - No check for sealing violations or
- * security is made unless a security manager is present.
- * <p>
- * <strong>IMPLEMENTATION NOTE</strong> - As of 8.0, this class
- * loader implements {@link InstrumentableClassLoader}, permitting web
- * application classes to instrument other classes in the same web
- * application. It does not permit instrumentation of system or container
- * classes or classes in other web apps.
- *
- * @author Remy Maucherat
- * @author Craig R. McClanahan
- */
-public abstract class WebappClassLoaderBase extends URLClassLoader
-        implements Lifecycle, InstrumentableClassLoader, WebappProperties, PermissionCheck {
-
-    private static final Log log = LogFactory.getLog(WebappClassLoaderBase.class);
-
-    /**
-     * List of ThreadGroup names to ignore when scanning for web application
-     * started threads that need to be shut down.
-     */
-    private static final List<String> JVM_THREAD_GROUP_NAMES = new ArrayList<>();
-
-    private static final String JVM_THREAD_GROUP_SYSTEM = "system";
-
-    private static final String CLASS_FILE_SUFFIX = ".class";
-
-    static {
-        if (!JreCompat.isGraalAvailable()) {
-            ClassLoader.registerAsParallelCapable();
-        }
-        JVM_THREAD_GROUP_NAMES.add(JVM_THREAD_GROUP_SYSTEM);
-        JVM_THREAD_GROUP_NAMES.add("RMI Runtime");
-    }
-
-    protected class PrivilegedFindClassByName implements PrivilegedAction<Class<?>> {
-
-        private final String name;
-
-        PrivilegedFindClassByName(String name) {
-            this.name = name;
-        }
-
-        @Override
-        public Class<?> run() {
-            return findClassInternal(name);
-        }
-    }
-
-
-    protected static final class PrivilegedGetClassLoader implements PrivilegedAction<ClassLoader> {
-
-        private final Class<?> clazz;
-
-        public PrivilegedGetClassLoader(Class<?> clazz){
-            this.clazz = clazz;
-        }
-
-        @Override
-        public ClassLoader run() {
-            return clazz.getClassLoader();
-        }
-    }
-
-
-    protected final class PrivilegedJavaseGetResource implements PrivilegedAction<URL> {
-
-        private final String name;
-
-        public PrivilegedJavaseGetResource(String name) {
-            this.name = name;
-        }
-
-        @Override
-        public URL run() {
-            return javaseClassLoader.getResource(name);
-        }
-    }
-
-
-    // ------------------------------------------------------- Static Variables
-
-    /**
-     * The string manager for this package.
-     */
-    protected static final StringManager sm =
-        StringManager.getManager(Constants.Package);
-
-
-    // ----------------------------------------------------------- Constructors
-
-    /**
-     * Construct a new ClassLoader with no defined repositories and no
-     * parent ClassLoader.
-     */
-    protected WebappClassLoaderBase() {
-
-        super(new URL[0]);
-
-        ClassLoader p = getParent();
-        if (p == null) {
-            p = getSystemClassLoader();
-        }
-        this.parent = p;
-
-        ClassLoader j = String.class.getClassLoader();
-        if (j == null) {
-            j = getSystemClassLoader();
-            while (j.getParent() != null) {
-                j = j.getParent();
-            }
-        }
-        this.javaseClassLoader = j;
-
-        securityManager = System.getSecurityManager();
-        if (securityManager != null) {
-            refreshPolicy();
-        }
-    }
-
-
-    /**
-     * Construct a new ClassLoader with no defined repositories and the given
-     * parent ClassLoader.
-     * <p>
-     * Method is used via reflection -
-     * see {@link WebappLoader#createClassLoader()}
-     *
-     * @param parent Our parent class loader
-     */
-    protected WebappClassLoaderBase(ClassLoader parent) {
-
-        super(new URL[0], parent);
-
-        ClassLoader p = getParent();
-        if (p == null) {
-            p = getSystemClassLoader();
-        }
-        this.parent = p;
-
-        ClassLoader j = String.class.getClassLoader();
-        if (j == null) {
-            j = getSystemClassLoader();
-            while (j.getParent() != null) {
-                j = j.getParent();
-            }
-        }
-        this.javaseClassLoader = j;
-
-        securityManager = System.getSecurityManager();
-        if (securityManager != null) {
-            refreshPolicy();
-        }
-    }
-
-
-    // ----------------------------------------------------- Instance Variables
-
-    /**
-     * Associated web resources for this webapp.
-     */
-    protected WebResourceRoot resources = null;
-
-
-    /**
-     * The cache of ResourceEntry for classes and resources we have loaded,
-     * keyed by resource path, not binary name. Path is used as the key since
-     * resources may be requested by binary name (classes) or path (other
-     * resources such as property files) and the mapping from binary name to
-     * path is unambiguous but the reverse mapping is ambiguous.
-     */
-    protected final Map<String, ResourceEntry> resourceEntries =
-            new ConcurrentHashMap<>();
-
-
-    /**
-     * Should this class loader delegate to the parent class loader
-     * <strong>before</strong> searching its own repositories (i.e. the
-     * usual Java2 delegation model)?  If set to <code>false</code>,
-     * this class loader will search its own repositories first, and
-     * delegate to the parent only if the class or resource is not
-     * found locally. Note that the default, <code>false</code>, is
-     * the behavior called for by the servlet specification.
-     */
-    protected boolean delegate = false;
-
-
-    private final Map<String,Long> jarModificationTimes = new HashMap<>();
-
-
-    /**
-     * A list of read File Permission's required if this loader is for a web
-     * application context.
-     */
-    protected final ArrayList<Permission> permissionList = new ArrayList<>();
-
-
-    /**
-     * The PermissionCollection for each CodeSource for a web
-     * application context.
-     */
-    protected final HashMap<String, PermissionCollection> loaderPC = new HashMap<>();
-
-
-    /**
-     * Instance of the SecurityManager installed.
-     */
-    protected final SecurityManager securityManager;
-
-
-    /**
-     * The parent class loader.
-     */
-    protected final ClassLoader parent;
-
-
-    /**
-     * The bootstrap class loader used to load the JavaSE classes. In some
-     * implementations this class loader is always <code>null</code> and in
-     * those cases {@link ClassLoader#getParent()} will be called recursively on
-     * the system class loader and the last non-null result used.
-     */
-    private ClassLoader javaseClassLoader;
-
-
-    /**
-     * Enables the RMI Target memory leak detection to be controlled. This is
-     * necessary since the detection can only work on Java 9 if some of the
-     * modularity checks are disabled.
-     */
-    private boolean clearReferencesRmiTargets = true;
-
-    /**
-     * Should Tomcat attempt to terminate threads that have been started by the
-     * web application? Stopping threads is performed via the deprecated (for
-     * good reason) <code>Thread.stop()</code> method and is likely to result in
-     * instability. As such, enabling this should be viewed as an option of last
-     * resort in a development environment and is not recommended in a
-     * production environment. If not specified, the default value of
-     * <code>false</code> will be used.
-     */
-    private boolean clearReferencesStopThreads = false;
-
-    /**
-     * Should Tomcat attempt to terminate any {@link java.util.TimerThread}s
-     * that have been started by the web application? If not specified, the
-     * default value of <code>false</code> will be used.
-     */
-    private boolean clearReferencesStopTimerThreads = false;
-
-    /**
-     * Should Tomcat call
-     * {@link org.apache.juli.logging.LogFactory#release(ClassLoader)}
-     * when the class loader is stopped? If not specified, the default value
-     * of <code>true</code> is used. Changing the default setting is likely to
-     * lead to memory leaks and other issues.
-     */
-    private boolean clearReferencesLogFactoryRelease = true;
-
-    /**
-     * If an HttpClient keep-alive timer thread has been started by this web
-     * application and is still running, should Tomcat change the context class
-     * loader from the current {@link ClassLoader} to
-     * {@link ClassLoader#getParent()} to prevent a memory leak? Note that the
-     * keep-alive timer thread will stop on its own once the keep-alives all
-     * expire however, on a busy system that might not happen for some time.
-     */
-    private boolean clearReferencesHttpClientKeepAliveThread = true;
-
-    /**
-     * Should Tomcat attempt to clear references to classes loaded by this class
-     * loader from the ObjectStreamClass caches?
-     */
-    private boolean clearReferencesObjectStreamClassCaches = true;
-
-    /**
-     * Should Tomcat attempt to clear references to classes loaded by this class
-     * loader from ThreadLocals?
-     */
-    private boolean clearReferencesThreadLocals = true;
-
-    /**
-     * Should Tomcat skip the memory leak checks when the web application is
-     * stopped as part of the process of shutting down the JVM?
-     */
-    private boolean skipMemoryLeakChecksOnJvmShutdown = false;
-
-    /**
-     * Holds the class file transformers decorating this class loader. The
-     * CopyOnWriteArrayList is thread safe. It is expensive on writes, but
-     * those should be rare. It is very fast on reads, since synchronization
-     * is not actually used. Importantly, the ClassLoader will never block
-     * iterating over the transformers while loading a class.
-     */
-    private final List<ClassFileTransformer> transformers = new CopyOnWriteArrayList<>();
-
-
-    /**
-     * Flag that indicates that {@link #addURL(URL)} has been called which
-     * creates a requirement to check the super class when searching for
-     * resources.
-     */
-    private boolean hasExternalRepositories = false;
-
-
-    /**
-     * Repositories managed by this class rather than the super class.
-     */
-    private List<URL> localRepositories = new ArrayList<>();
-
-
-    private volatile LifecycleState state = LifecycleState.NEW;
-
-
-    // ------------------------------------------------------------- Properties
-
-    /**
-     * @return associated resources.
-     */
-    public WebResourceRoot getResources() {
-        return this.resources;
-    }
-
-
-    /**
-     * Set associated resources.
-     * @param resources the resources from which the classloader will
-     *     load the classes
-     */
-    public void setResources(WebResourceRoot resources) {
-        this.resources = resources;
-    }
-
-
-    /**
-     * @return the context name for this class loader.
-     */
-    public String getContextName() {
-        if (resources == null) {
-            return "Unknown";
-        } else {
-            return resources.getContext().getBaseName();
-        }
-    }
-
-
-    /**
-     * Return the "delegate first" flag for this class loader.
-     * @return <code>true</code> if the class lookup will delegate to
-     *   the parent first. The default in Tomcat is <code>false</code>.
-     */
-    public boolean getDelegate() {
-        return this.delegate;
-    }
-
-
-    /**
-     * Set the "delegate first" flag for this class loader.
-     * If this flag is true, this class loader delegates
-     * to the parent class loader
-     * <strong>before</strong> searching its own repositories, as
-     * in an ordinary (non-servlet) chain of Java class loaders.
-     * If set to <code>false</code> (the default),
-     * this class loader will search its own repositories first, and
-     * delegate to the parent only if the class or resource is not
-     * found locally, as per the servlet specification.
-     *
-     * @param delegate The new "delegate first" flag
-     */
-    public void setDelegate(boolean delegate) {
-        this.delegate = delegate;
-    }
-
-
-    /**
-     * If there is a Java SecurityManager create a read permission for the
-     * target of the given URL as appropriate.
-     *
-     * @param url URL for a file or directory on local system
-     */
-    void addPermission(URL url) {
-        if (url == null) {
-            return;
-        }
-        if (securityManager != null) {
-            String protocol = url.getProtocol();
-            if ("file".equalsIgnoreCase(protocol)) {
-                URI uri;
-                File f;
-                String path;
-                try {
-                    uri = url.toURI();
-                    f = new File(uri);
-                    path = f.getCanonicalPath();
-                } catch (IOException | URISyntaxException e) {
-                    log.warn(sm.getString(
-                            "webappClassLoader.addPermisionNoCanonicalFile",
-                            url.toExternalForm()));
-                    return;
-                }
-                if (f.isFile()) {
-                    // Allow the file to be read
-                    addPermission(new FilePermission(path, "read"));
-                } else if (f.isDirectory()) {
-                    addPermission(new FilePermission(path, "read"));
-                    addPermission(new FilePermission(
-                            path + File.separator + "-", "read"));
-                } else {
-                    // File does not exist - ignore (shouldn't happen)
-                }
-            } else {
-                // Unsupported URL protocol
-                log.warn(sm.getString(
-                        "webappClassLoader.addPermisionNoProtocol",
-                        protocol, url.toExternalForm()));
-            }
-        }
-    }
-
-
-    /**
-     * If there is a Java SecurityManager create a Permission.
-     *
-     * @param permission The permission
-     */
-    void addPermission(Permission permission) {
-        if ((securityManager != null) && (permission != null)) {
-            permissionList.add(permission);
-        }
-    }
-
-
-    public boolean getClearReferencesRmiTargets() {
-        return this.clearReferencesRmiTargets;
-    }
-
-
-    public void setClearReferencesRmiTargets(boolean clearReferencesRmiTargets) {
-        this.clearReferencesRmiTargets = clearReferencesRmiTargets;
-    }
-
-
-    /**
-     * @return the clearReferencesStopThreads flag for this Context.
-     */
-    public boolean getClearReferencesStopThreads() {
-        return this.clearReferencesStopThreads;
-    }
-
-
-    /**
-     * Set the clearReferencesStopThreads feature for this Context.
-     *
-     * @param clearReferencesStopThreads The new flag value
-     */
-    public void setClearReferencesStopThreads(
-            boolean clearReferencesStopThreads) {
-        this.clearReferencesStopThreads = clearReferencesStopThreads;
-    }
-
-
-    /**
-     * @return the clearReferencesStopTimerThreads flag for this Context.
-     */
-    public boolean getClearReferencesStopTimerThreads() {
-        return this.clearReferencesStopTimerThreads;
-    }
-
-
-    /**
-     * Set the clearReferencesStopTimerThreads feature for this Context.
-     *
-     * @param clearReferencesStopTimerThreads The new flag value
-     */
-    public void setClearReferencesStopTimerThreads(
-            boolean clearReferencesStopTimerThreads) {
-        this.clearReferencesStopTimerThreads = clearReferencesStopTimerThreads;
-    }
-
-
-    /**
-     * @return the clearReferencesLogFactoryRelease flag for this Context.
-     */
-    public boolean getClearReferencesLogFactoryRelease() {
-        return this.clearReferencesLogFactoryRelease;
-    }
-
-
-    /**
-     * Set the clearReferencesLogFactoryRelease feature for this Context.
-     *
-     * @param clearReferencesLogFactoryRelease The new flag value
-     */
-    public void setClearReferencesLogFactoryRelease(
-            boolean clearReferencesLogFactoryRelease) {
-        this.clearReferencesLogFactoryRelease =
-            clearReferencesLogFactoryRelease;
-    }
-
-
-    /**
-     * @return the clearReferencesHttpClientKeepAliveThread flag for this
-     * Context.
-     */
-    public boolean getClearReferencesHttpClientKeepAliveThread() {
-        return this.clearReferencesHttpClientKeepAliveThread;
-    }
-
-
-    /**
-     * Set the clearReferencesHttpClientKeepAliveThread feature for this
-     * Context.
-     *
-     * @param clearReferencesHttpClientKeepAliveThread The new flag value
-     */
-    public void setClearReferencesHttpClientKeepAliveThread(
-            boolean clearReferencesHttpClientKeepAliveThread) {
-        this.clearReferencesHttpClientKeepAliveThread =
-            clearReferencesHttpClientKeepAliveThread;
-    }
-
-
-    public boolean getClearReferencesObjectStreamClassCaches() {
-        return clearReferencesObjectStreamClassCaches;
-    }
-
-
-    public void setClearReferencesObjectStreamClassCaches(
-            boolean clearReferencesObjectStreamClassCaches) {
-        this.clearReferencesObjectStreamClassCaches = clearReferencesObjectStreamClassCaches;
-    }
-
-
-    public boolean getClearReferencesThreadLocals() {
-        return clearReferencesThreadLocals;
-    }
-
-
-    public void setClearReferencesThreadLocals(boolean clearReferencesThreadLocals) {
-        this.clearReferencesThreadLocals = clearReferencesThreadLocals;
-    }
-
-
-    public boolean getSkipMemoryLeakChecksOnJvmShutdown() {
-        return skipMemoryLeakChecksOnJvmShutdown;
-    }
-
-
-    public void setSkipMemoryLeakChecksOnJvmShutdown(boolean skipMemoryLeakChecksOnJvmShutdown) {
-        this.skipMemoryLeakChecksOnJvmShutdown = skipMemoryLeakChecksOnJvmShutdown;
-    }
-
-
-    // ------------------------------------------------------- Reloader Methods
-
-    /**
-     * Adds the specified class file transformer to this class loader. The
-     * transformer will then be able to modify the bytecode of any classes
-     * loaded by this class loader after the invocation of this method.
-     *
-     * @param transformer The transformer to add to the class loader
-     */
-    @Override
-    public void addTransformer(ClassFileTransformer transformer) {
-
-        if (transformer == null) {
-            throw new IllegalArgumentException(sm.getString(
-                    "webappClassLoader.addTransformer.illegalArgument", getContextName()));
-        }
-
-        if (this.transformers.contains(transformer)) {
-            // if the same instance of this transformer was already added, bail out
-            log.warn(sm.getString("webappClassLoader.addTransformer.duplicate",
-                    transformer, getContextName()));
-            return;
-        }
-        this.transformers.add(transformer);
-
-        log.info(sm.getString("webappClassLoader.addTransformer", transformer, getContextName()));
-    }
-
-    /**
-     * Removes the specified class file transformer from this class loader.
-     * It will no longer be able to modify the byte code of any classes
-     * loaded by the class loader after the invocation of this method.
-     * However, any classes already modified by this transformer will
-     * remain transformed.
-     *
-     * @param transformer The transformer to remove
-     */
-    @Override
-    public void removeTransformer(ClassFileTransformer transformer) {
-
-        if (transformer == null) {
-            return;
-        }
-
-        if (this.transformers.remove(transformer)) {
-            log.info(sm.getString("webappClassLoader.removeTransformer",
-                    transformer, getContextName()));
-        }
-    }
-
-    protected void copyStateWithoutTransformers(WebappClassLoaderBase base) {
-        base.resources = this.resources;
-        base.delegate = this.delegate;
-        base.state = LifecycleState.NEW;
-        base.clearReferencesStopThreads = this.clearReferencesStopThreads;
-        base.clearReferencesStopTimerThreads = this.clearReferencesStopTimerThreads;
-        base.clearReferencesLogFactoryRelease = this.clearReferencesLogFactoryRelease;
-        base.clearReferencesHttpClientKeepAliveThread = this.clearReferencesHttpClientKeepAliveThread;
-        base.jarModificationTimes.putAll(this.jarModificationTimes);
-        base.permissionList.addAll(this.permissionList);
-        base.loaderPC.putAll(this.loaderPC);
-    }
-
-    /**
-     * Have one or more classes or resources been modified so that a reload
-     * is appropriate?
-     * @return <code>true</code> if there's been a modification
-     */
-    public boolean modified() {
-
-        if (log.isDebugEnabled())
-            log.debug("modified()");
-
-        for (Entry<String,ResourceEntry> entry : resourceEntries.entrySet()) {
-            long cachedLastModified = entry.getValue().lastModified;
-            long lastModified = resources.getClassLoaderResource(
-                    entry.getKey()).getLastModified();
-            if (lastModified != cachedLastModified) {
-                if( log.isDebugEnabled() )
-                    log.debug(sm.getString("webappClassLoader.resourceModified",
-                            entry.getKey(),
-                            new Date(cachedLastModified),
-                            new Date(lastModified)));
-                return true;
-            }
-        }
-
-        // Check if JARs have been added or removed
-        WebResource[] jars = resources.listResources("/WEB-INF/lib");
-        // Filter out non-JAR resources
-
-        int jarCount = 0;
-        for (WebResource jar : jars) {
-            if (jar.getName().endsWith(".jar") && jar.isFile() && jar.canRead()) {
-                jarCount++;
-                Long recordedLastModified = jarModificationTimes.get(jar.getName());
-                if (recordedLastModified == null) {
-                    // Jar has been added
-                    log.info(sm.getString("webappClassLoader.jarsAdded",
-                            resources.getContext().getName()));
-                    return true;
-                }
-                if (recordedLastModified.longValue() != jar.getLastModified()) {
-                    // Jar has been changed
-                    log.info(sm.getString("webappClassLoader.jarsModified",
-                            resources.getContext().getName()));
-                    return true;
-                }
-            }
-        }
-
-        if (jarCount < jarModificationTimes.size()){
-            log.info(sm.getString("webappClassLoader.jarsRemoved",
-                    resources.getContext().getName()));
-            return true;
-        }
-
-
-        // No classes have been modified
-        return false;
-    }
-
-
-    @Override
-    public String toString() {
-
-        StringBuilder sb = new StringBuilder(this.getClass().getSimpleName());
-        sb.append("\r\n  context: ");
-        sb.append(getContextName());
-        sb.append("\r\n  delegate: ");
-        sb.append(delegate);
-        sb.append("\r\n");
-        if (this.parent != null) {
-            sb.append("----------> Parent Classloader:\r\n");
-            sb.append(this.parent.toString());
-            sb.append("\r\n");
-        }
-        if (this.transformers.size() > 0) {
-            sb.append("----------> Class file transformers:\r\n");
-            for (ClassFileTransformer transformer : this.transformers) {
-                sb.append(transformer).append("\r\n");
-            }
-        }
-        return sb.toString();
-    }
-
-
-    // ---------------------------------------------------- ClassLoader Methods
-
-
-    // Note: exposed for use by tests
-    protected final Class<?> doDefineClass(String name, byte[] b, int off, int len,
-            ProtectionDomain protectionDomain) {
-        return super.defineClass(name, b, off, len, protectionDomain);
-    }
-
-    /**
-     * Find the specified class in our local repositories, if possible.  If
-     * not found, throw <code>ClassNotFoundException</code>.
-     *
-     * @param name The binary name of the class to be loaded
-     *
-     * @exception ClassNotFoundException if the class was not found
-     */
-    @Override
-    public Class<?> findClass(String name) throws ClassNotFoundException {
-
-        if (log.isDebugEnabled())
-            log.debug("    findClass(" + name + ")");
-
-        checkStateForClassLoading(name);
-
-        // (1) Permission to define this class when using a SecurityManager
-        if (securityManager != null) {
-            int i = name.lastIndexOf('.');
-            if (i >= 0) {
-                try {
-                    if (log.isTraceEnabled())
-                        log.trace("      securityManager.checkPackageDefinition");
-                    securityManager.checkPackageDefinition(name.substring(0,i));
-                } catch (Exception se) {
-                    if (log.isTraceEnabled())
-                        log.trace("      -->Exception-->ClassNotFoundException", se);
-                    throw new ClassNotFoundException(name, se);
-                }
-            }
-        }
-
-        // Ask our superclass to locate this class, if possible
-        // (throws ClassNotFoundException if it is not found)
-        Class<?> clazz = null;
-        try {
-            if (log.isTraceEnabled())
-                log.trace("      findClassInternal(" + name + ")");
-            try {
-                if (securityManager != null) {
-                    PrivilegedAction<Class<?>> dp =
-                        new PrivilegedFindClassByName(name);
-                    clazz = AccessController.doPrivileged(dp);
-                } else {
-                    clazz = findClassInternal(name);
-                }
-            } catch(AccessControlException ace) {
-                log.warn(sm.getString("webappClassLoader.securityException", name,
-                        ace.getMessage()), ace);
-                throw new ClassNotFoundException(name, ace);
-            } catch (RuntimeException e) {
-                if (log.isTraceEnabled())
-                    log.trace("      -->RuntimeException Rethrown", e);
-                throw e;
-            }
-            if ((clazz == null) && hasExternalRepositories) {
-                try {
-                    clazz = super.findClass(name);
-                } catch(AccessControlException ace) {
-                    log.warn(sm.getString("webappClassLoader.securityException", name,
-                            ace.getMessage()), ace);
-                    throw new ClassNotFoundException(name, ace);
-                } catch (RuntimeException e) {
-                    if (log.isTraceEnabled())
-                        log.trace("      -->RuntimeException Rethrown", e);
-                    throw e;
-                }
-            }
-            if (clazz == null) {
-                if (log.isDebugEnabled())
-                    log.debug("    --> Returning ClassNotFoundException");
-                throw new ClassNotFoundException(name);
-            }
-        } catch (ClassNotFoundException e) {
-            if (log.isTraceEnabled())
-                log.trace("    --> Passing on ClassNotFoundException");
-            throw e;
-        }
-
-        // Return the class we have located
-        if (log.isTraceEnabled())
-            log.debug("      Returning class " + clazz);
-
-        if (log.isTraceEnabled()) {
-            ClassLoader cl;
-            if (Globals.IS_SECURITY_ENABLED){
-                cl = AccessController.doPrivileged(
-                    new PrivilegedGetClassLoader(clazz));
-            } else {
-                cl = clazz.getClassLoader();
-            }
-            log.debug("      Loaded by " + cl.toString());
-        }
-        return clazz;
-
-    }
-
-
-    /**
-     * Find the specified resource in our local repository, and return a
-     * <code>URL</code> referring to it, or <code>null</code> if this resource
-     * cannot be found.
-     *
-     * @param name Name of the resource to be found
-     */
-    @Override
-    public URL findResource(final String name) {
-
-        if (log.isDebugEnabled())
-            log.debug("    findResource(" + name + ")");
-
-        checkStateForResourceLoading(name);
-
-        URL url = null;
-
-        String path = nameToPath(name);
-
-        WebResource resource = resources.getClassLoaderResource(path);
-        if (resource.exists()) {
-            url = resource.getURL();
-            trackLastModified(path, resource);
-        }
-
-        if ((url == null) && hasExternalRepositories) {
-            url = super.findResource(name);
-        }
-
-        if (log.isDebugEnabled()) {
-            if (url != null)
-                log.debug("    --> Returning '" + url.toString() + "'");
-            else
-                log.debug("    --> Resource not found, returning null");
-        }
-        return url;
-    }
-
-
-    private void trackLastModified(String path, WebResource resource) {
-        if (resourceEntries.containsKey(path)) {
-            return;
-        }
-        ResourceEntry entry = new ResourceEntry();
-        entry.lastModified = resource.getLastModified();
-        synchronized(resourceEntries) {
-            resourceEntries.putIfAbsent(path, entry);
-        }
-    }
-
-
-    /**
-     * Return an enumeration of <code>URLs</code> representing all of the
-     * resources with the given name.  If no resources with this name are
-     * found, return an empty enumeration.
-     *
-     * @param name Name of the resources to be found
-     *
-     * @exception IOException if an input/output error occurs
-     */
-    @Override
-    public Enumeration<URL> findResources(String name) throws IOException {
-
-        if (log.isDebugEnabled())
-            log.debug("    findResources(" + name + ")");
-
-        checkStateForResourceLoading(name);
-
-        LinkedHashSet<URL> result = new LinkedHashSet<>();
-
-        String path = nameToPath(name);
-
-        WebResource[] webResources = resources.getClassLoaderResources(path);
-        for (WebResource webResource : webResources) {
-            if (webResource.exists()) {
-                result.add(webResource.getURL());
-            }
-        }
-
-        // Adding the results of a call to the superclass
-        if (hasExternalRepositories) {
-            Enumeration<URL> otherResourcePaths = super.findResources(name);
-            while (otherResourcePaths.hasMoreElements()) {
-                result.add(otherResourcePaths.nextElement());
-            }
-        }
-
-        return Collections.enumeration(result);
-    }
-
-
-    /**
-     * Find the resource with the given name.  A resource is some data
-     * (images, audio, text, etc.) that can be accessed by class code in a
-     * way that is independent of the location of the code.  The name of a
-     * resource is a "/"-separated path name that identifies the resource.
-     * If the resource cannot be found, return <code>null</code>.
-     * <p>
-     * This method searches according to the following algorithm, returning
-     * as soon as it finds the appropriate URL.  If the resource cannot be
-     * found, returns <code>null</code>.
-     * <ul>
-     * <li>If the <code>delegate</code> property is set to <code>true</code>,
-     *     call the <code>getResource()</code> method of the parent class
-     *     loader, if any.</li>
-     * <li>Call <code>findResource()</code> to find this resource in our
-     *     locally defined repositories.</li>
-     * <li>Call the <code>getResource()</code> method of the parent class
-     *     loader, if any.</li>
-     * </ul>
-     *
-     * @param name Name of the resource to return a URL for
-     */
-    @Override
-    public URL getResource(String name) {
-
-        if (log.isDebugEnabled())
-            log.debug("getResource(" + name + ")");
-
-        checkStateForResourceLoading(name);
-
-        URL url = null;
-
-        boolean delegateFirst = delegate || filter(name, false);
-
-        // (1) Delegate to parent if requested
-        if (delegateFirst) {
-            if (log.isDebugEnabled())
-                log.debug("  Delegating to parent classloader " + parent);
-            url = parent.getResource(name);
-            if (url != null) {
-                if (log.isDebugEnabled())
-                    log.debug("  --> Returning '" + url.toString() + "'");
-                return url;
-            }
-        }
-
-        // (2) Search local repositories
-        url = findResource(name);
-        if (url != null) {
-            if (log.isDebugEnabled())
-                log.debug("  --> Returning '" + url.toString() + "'");
-            return url;
-        }
-
-        // (3) Delegate to parent unconditionally if not already attempted
-        if (!delegateFirst) {
-            url = parent.getResource(name);
-            if (url != null) {
-                if (log.isDebugEnabled())
-                    log.debug("  --> Returning '" + url.toString() + "'");
-                return url;
-            }
-        }
-
-        // (4) Resource was not found
-        if (log.isDebugEnabled())
-            log.debug("  --> Resource not found, returning null");
-        return null;
-
-    }
-
-
-    @Override
-    public Enumeration<URL> getResources(String name) throws IOException {
-
-        Enumeration<URL> parentResources = getParent().getResources(name);
-        Enumeration<URL> localResources = findResources(name);
-
-        // Need to combine these enumerations. The order in which the
-        // Enumerations are combined depends on how delegation is configured
-        boolean delegateFirst = delegate || filter(name, false);
-
-        if (delegateFirst) {
-            return new CombinedEnumeration(parentResources, localResources);
-        } else {
-            return new CombinedEnumeration(localResources, parentResources);
-        }
-    }
-
-
-    /**
-     * Find the resource with the given name, and return an input stream
-     * that can be used for reading it.  The search order is as described
-     * for <code>getResource()</code>, after checking to see if the resource
-     * data has been previously cached.  If the resource cannot be found,
-     * return <code>null</code>.
-     *
-     * @param name Name of the resource to return an input stream for
-     */
-    @Override
-    public InputStream getResourceAsStream(String name) {
-
-        if (log.isDebugEnabled())
-            log.debug("getResourceAsStream(" + name + ")");
-
-        checkStateForResourceLoading(name);
-
-        InputStream stream = null;
-
-        boolean delegateFirst = delegate || filter(name, false);
-
-        // (1) Delegate to parent if requested
-        if (delegateFirst) {
-            if (log.isDebugEnabled())
-                log.debug("  Delegating to parent classloader " + parent);
-            stream = parent.getResourceAsStream(name);
-            if (stream != null) {
-                if (log.isDebugEnabled())
-                    log.debug("  --> Returning stream from parent");
-                return stream;
-            }
-        }
-
-        // (2) Search local repositories
-        if (log.isDebugEnabled())
-            log.debug("  Searching local repositories");
-        String path = nameToPath(name);
-        WebResource resource = resources.getClassLoaderResource(path);
-        if (resource.exists()) {
-            stream = resource.getInputStream();
-            trackLastModified(path, resource);
-        }
-        try {
-            if (hasExternalRepositories && stream == null) {
-                URL url = super.findResource(name);
-                if (url != null) {
-                    stream = url.openStream();
-                }
-            }
-        } catch (IOException e) {
-            // Ignore
-        }
-        if (stream != null) {
-            if (log.isDebugEnabled())
-                log.debug("  --> Returning stream from local");
-            return stream;
-        }
-
-        // (3) Delegate to parent unconditionally
-        if (!delegateFirst) {
-            if (log.isDebugEnabled())
-                log.debug("  Delegating to parent classloader unconditionally " + parent);
-            stream = parent.getResourceAsStream(name);
-            if (stream != null) {
-                if (log.isDebugEnabled())
-                    log.debug("  --> Returning stream from parent");
-                return stream;
-            }
-        }
-
-        // (4) Resource was not found
-        if (log.isDebugEnabled())
-            log.debug("  --> Resource not found, returning null");
-        return null;
-    }
-
-
-    /**
-     * Load the class with the specified name.  This method searches for
-     * classes in the same manner as <code>loadClass(String, boolean)</code>
-     * with <code>false</code> as the second argument.
-     *
-     * @param name The binary name of the class to be loaded
-     *
-     * @exception ClassNotFoundException if the class was not found
-     */
-    @Override
-    public Class<?> loadClass(String name) throws ClassNotFoundException {
-        return loadClass(name, false);
-    }
-
-
-    /**
-     * Load the class with the specified name, searching using the following
-     * algorithm until it finds and returns the class.  If the class cannot
-     * be found, returns <code>ClassNotFoundException</code>.
-     * <ul>
-     * <li>Call <code>findLoadedClass(String)</code> to check if the
-     *     class has already been loaded.  If it has, the same
-     *     <code>Class</code> object is returned.</li>
-     * <li>If the <code>delegate</code> property is set to <code>true</code>,
-     *     call the <code>loadClass()</code> method of the parent class
-     *     loader, if any.</li>
-     * <li>Call <code>findClass()</code> to find this class in our locally
-     *     defined repositories.</li>
-     * <li>Call the <code>loadClass()</code> method of our parent
-     *     class loader, if any.</li>
-     * </ul>
-     * If the class was found using the above steps, and the
-     * <code>resolve</code> flag is <code>true</code>, this method will then
-     * call <code>resolveClass(Class)</code> on the resulting Class object.
-     *
-     * @param name The binary name of the class to be loaded
-     * @param resolve If <code>true</code> then resolve the class
-     *
-     * @exception ClassNotFoundException if the class was not found
-     */
-    @Override
-    public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-
-        synchronized (JreCompat.isGraalAvailable() ? this : getClassLoadingLock(name)) {
-            if (log.isDebugEnabled())
-                log.debug("loadClass(" + name + ", " + resolve + ")");
-            Class<?> clazz = null;
-
-            // Log access to stopped class loader
-            checkStateForClassLoading(name);
-
-            // (0) Check our previously loaded local class cache
-            clazz = findLoadedClass0(name);
-            if (clazz != null) {
-                if (log.isDebugEnabled())
-                    log.debug("  Returning class from cache");
-                if (resolve)
-                    resolveClass(clazz);
-                return clazz;
-            }
-
-            // (0.1) Check our previously loaded class cache
-            clazz = JreCompat.isGraalAvailable() ? null : findLoadedClass(name);
-            if (clazz != null) {
-                if (log.isDebugEnabled())
-                    log.debug("  Returning class from cache");
-                if (resolve)
-                    resolveClass(clazz);
-                return clazz;
-            }
-
-            // (0.2) Try loading the class with the system class loader, to prevent
-            //       the webapp from overriding Java SE classes. This implements
-            //       SRV.10.7.2
-            String resourceName = binaryNameToPath(name, false);
-
-            ClassLoader javaseLoader = getJavaseClassLoader();
-            boolean tryLoadingFromJavaseLoader;
-            try {
-                // Use getResource as it won't trigger an expensive
-                // ClassNotFoundException if the resource is not available from
-                // the Java SE class loader. However (see
-                // https://bz.apache.org/bugzilla/show_bug.cgi?id=58125 for
-                // details) when running under a security manager in rare cases
-                // this call may trigger a ClassCircularityError.
-                // See https://bz.apache.org/bugzilla/show_bug.cgi?id=61424 for
-                // details of how this may trigger a StackOverflowError
-                // Given these reported errors, catch Throwable to ensure any
-                // other edge cases are also caught
-                URL url;
-                if (securityManager != null) {
-                    PrivilegedAction<URL> dp = new PrivilegedJavaseGetResource(resourceName);
-                    url = AccessController.doPrivileged(dp);
-                } else {
-                    url = javaseLoader.getResource(resourceName);
-                }
-                tryLoadingFromJavaseLoader = (url != null);
-            } catch (Throwable t) {
-                // Swallow all exceptions apart from those that must be re-thrown
-                ExceptionUtils.handleThrowable(t);
-                // The getResource() trick won't work for this class. We have to
-                // try loading it directly and accept that we might get a
-                // ClassNotFoundException.
-                tryLoadingFromJavaseLoader = true;
-            }
-
-            if (tryLoadingFromJavaseLoader) {
-                try {
-                    clazz = javaseLoader.loadClass(name);
-                    if (clazz != null) {
-                        if (resolve)
-                            resolveClass(clazz);
-                        return clazz;
-                    }
-                } catch (ClassNotFoundException e) {
-                    // Ignore
-                }
-            }
-
-            // (0.5) Permission to access this class when using a SecurityManager
-            if (securityManager != null) {
-                int i = name.lastIndexOf('.');
-                if (i >= 0) {
-                    try {
-                        securityManager.checkPackageAccess(name.substring(0,i));
-                    } catch (SecurityException se) {
-                        String error = sm.getString("webappClassLoader.restrictedPackage", name);
-                        log.info(error, se);
-                        throw new ClassNotFoundException(error, se);
-                    }
-                }
-            }
-
-            boolean delegateLoad = delegate || filter(name, true);
-
-            // (1) Delegate to our parent if requested
-            if (delegateLoad) {
-                if (log.isDebugEnabled())
-                    log.debug("  Delegating to parent classloader1 " + parent);
-                try {
-                    clazz = Class.forName(name, false, parent);
-                    if (clazz != null) {
-                        if (log.isDebugEnabled())
-                            log.debug("  Loading class from parent");
-                        if (resolve)
-                            resolveClass(clazz);
-                        return clazz;
-                    }
-                } catch (ClassNotFoundException e) {
-                    // Ignore
-                }
-            }
-
-            // (2) Search local repositories
-            if (log.isDebugEnabled())
-                log.debug("  Searching local repositories");
-            try {
-                clazz = findClass(name);
-                if (clazz != null) {
-                    if (log.isDebugEnabled())
-                        log.debug("  Loading class from local repository");
-                    if (resolve)
-                        resolveClass(clazz);
-                    return clazz;
-                }
-            } catch (ClassNotFoundException e) {
-                // Ignore
-            }
-
-            // (3) Delegate to parent unconditionally
-            if (!delegateLoad) {
-                if (log.isDebugEnabled())
-                    log.debug("  Delegating to parent classloader at end: " + parent);
-                try {
-                    clazz = Class.forName(name, false, parent);
-                    if (clazz != null) {
-                        if (log.isDebugEnabled())
-                            log.debug("  Loading class from parent");
-                        if (resolve)
-                            resolveClass(clazz);
-                        return clazz;
-                    }
-                } catch (ClassNotFoundException e) {
-                    // Ignore
-                }
-            }
-        }
-
-        throw new ClassNotFoundException(name);
-    }
-
-
-    protected void checkStateForClassLoading(String className) throws ClassNotFoundException {
-        // It is not permitted to load new classes once the web application has
-        // been stopped.
-        try {
-            checkStateForResourceLoading(className);
-        } catch (IllegalStateException ise) {
-            throw new ClassNotFoundException(ise.getMessage(), ise);
-        }
-    }
-
-
-    protected void checkStateForResourceLoading(String resource) throws IllegalStateException {
-        // It is not permitted to load resources once the web application has
-        // been stopped.
-        if (!state.isAvailable()) {
-            String msg = sm.getString("webappClassLoader.stopped", resource);
-            IllegalStateException ise = new IllegalStateException(msg);
-            log.info(msg, ise);
-            throw ise;
-        }
-    }
-
-    /**
-     * Get the Permissions for a CodeSource.  If this instance
-     * of WebappClassLoaderBase is for a web application context,
-     * add read FilePermission for the appropriate resources.
-     *
-     * @param codeSource where the code was loaded from
-     * @return PermissionCollection for CodeSource
-     */
-    @Override
-    protected PermissionCollection getPermissions(CodeSource codeSource) {
-        String codeUrl = codeSource.getLocation().toString();
-        PermissionCollection pc;
-        if ((pc = loaderPC.get(codeUrl)) == null) {
-            pc = super.getPermissions(codeSource);
-            if (pc != null) {
-                for (Permission p : permissionList) {
-                    pc.add(p);
-                }
-                loaderPC.put(codeUrl,pc);
-            }
-        }
-        return pc;
-    }
-
-
-    @Override
-    public boolean check(Permission permission) {
-        if (!Globals.IS_SECURITY_ENABLED) {
-            return true;
-        }
-        Policy currentPolicy = Policy.getPolicy();
-        if (currentPolicy != null) {
-            URL contextRootUrl = resources.getResource("/").getCodeBase();
-            CodeSource cs = new CodeSource(contextRootUrl, (Certificate[]) null);
-            PermissionCollection pc = currentPolicy.getPermissions(cs);
-            if (pc.implies(permission)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     * <p>
-     * Note that list of URLs returned by this method may not be complete. The
-     * web application class loader accesses class loader resources via the
-     * {@link WebResourceRoot} which supports the arbitrary mapping of
-     * additional files, directories and contents of JAR files under
-     * WEB-INF/classes. Any such resources will not be included in the URLs
-     * returned here.
-     */
-    @Override
-    public URL[] getURLs() {
-        ArrayList<URL> result = new ArrayList<>();
-        result.addAll(localRepositories);
-        result.addAll(Arrays.asList(super.getURLs()));
-        return result.toArray(new URL[0]);
-    }
-
-
-    // ------------------------------------------------------ Lifecycle Methods
-
-
-    /**
-     * Add a lifecycle event listener to this component.
-     *
-     * @param listener The listener to add
-     */
-    @Override
-    public void addLifecycleListener(LifecycleListener listener) {
-        // NOOP
-    }
-
-
-    /**
-     * Get the lifecycle listeners associated with this lifecycle. If this
-     * Lifecycle has no listeners registered, a zero-length array is returned.
-     */
-    @Override
-    public LifecycleListener[] findLifecycleListeners() {
-        return new LifecycleListener[0];
-    }
-
-
-    /**
-     * Remove a lifecycle event listener from this component.
-     *
-     * @param listener The listener to remove
-     */
-    @Override
-    public void removeLifecycleListener(LifecycleListener listener) {
-        // NOOP
-    }
-
-
-    /**
-     * Obtain the current state of the source component.
-     *
-     * @return The current state of the source component.
-     */
-    @Override
-    public LifecycleState getState() {
-        return state;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getStateName() {
-        return getState().toString();
-    }
-
-
-    @Override
-    public void init() {
-        state = LifecycleState.INITIALIZED;
-    }
-
-
-    /**
-     * Start the class loader.
-     *
-     * @exception LifecycleException if a lifecycle error occurs
-     */
-    @Override
-    public void start() throws LifecycleException {
-
-        state = LifecycleState.STARTING_PREP;
-
-        WebResource[] classesResources = resources.getResources("/WEB-INF/classes");
-        for (WebResource classes : classesResources) {
-            if (classes.isDirectory() && classes.canRead()) {
-                localRepositories.add(classes.getURL());
-            }
-        }
-        WebResource[] jars = resources.listResources("/WEB-INF/lib");
-        for (WebResource jar : jars) {
-            if (jar.getName().endsWith(".jar") && jar.isFile() && jar.canRead()) {
-                localRepositories.add(jar.getURL());
-                jarModificationTimes.put(
-                        jar.getName(), Long.valueOf(jar.getLastModified()));
-            }
-        }
-
-        state = LifecycleState.STARTED;
-    }
-
-
-    /**
-     * Stop the class loader.
-     *
-     * @exception LifecycleException if a lifecycle error occurs
-     */
-    @Override
-    public void stop() throws LifecycleException {
-
-        state = LifecycleState.STOPPING_PREP;
-
-        // Clearing references should be done before setting started to
-        // false, due to possible side effects
-        clearReferences();
-
-        state = LifecycleState.STOPPING;
-
-        resourceEntries.clear();
-        jarModificationTimes.clear();
-        resources = null;
-
-        permissionList.clear();
-        loaderPC.clear();
-
-        state = LifecycleState.STOPPED;
-    }
-
-
-    @Override
-    public void destroy() {
-        state = LifecycleState.DESTROYING;
-
-        try {
-            super.close();
-        } catch (IOException ioe) {
-            log.warn(sm.getString("webappClassLoader.superCloseFail"), ioe);
-        }
-        state = LifecycleState.DESTROYED;
-    }
-
-
-    // ------------------------------------------------------ Protected Methods
-
-    protected ClassLoader getJavaseClassLoader() {
-        return javaseClassLoader;
-    }
-
-    protected void setJavaseClassLoader(ClassLoader classLoader) {
-        if (classLoader == null) {
-            throw new IllegalArgumentException(
-                    sm.getString("webappClassLoader.javaseClassLoaderNull"));
-        }
-        javaseClassLoader = classLoader;
-    }
-
-    /**
-     * Clear references.
-     */
-    protected void clearReferences() {
-
-        // If the JVM is shutting down, skip the memory leak checks
-        if (skipMemoryLeakChecksOnJvmShutdown
-            && !resources.getContext().getParent().getState().isAvailable()) {
-            // During reloading / redeployment the parent is expected to be
-            // available. Parent is not available so this might be a JVM
-            // shutdown.
-            try {
-                Thread dummyHook = new Thread();
-                Runtime.getRuntime().addShutdownHook(dummyHook);
-                Runtime.getRuntime().removeShutdownHook(dummyHook);
-            } catch (IllegalStateException ise) {
-                return;
-            }
-        }
-
-        if (!JreCompat.isGraalAvailable()) {
-            // De-register any remaining JDBC drivers
-            clearReferencesJdbc();
-        }
-
-        // Stop any threads the web application started
-        clearReferencesThreads();
-
-        // Clear any references retained in the serialization caches
-        if (clearReferencesObjectStreamClassCaches && !JreCompat.isGraalAvailable()) {
-            clearReferencesObjectStreamClassCaches();
-        }
-
-        // Check for leaks triggered by ThreadLocals loaded by this class loader
-        if (clearReferencesThreadLocals && !JreCompat.isGraalAvailable()) {
-            checkThreadLocalsForLeaks();
-        }
-
-        // Clear RMI Targets loaded by this class loader
-        if (clearReferencesRmiTargets) {
-            clearReferencesRmiTargets();
-        }
-
-         // Clear the IntrospectionUtils cache.
-        IntrospectionUtils.clear();
-
-        // Clear the classloader reference in common-logging
-        if (clearReferencesLogFactoryRelease) {
-            org.apache.juli.logging.LogFactory.release(this);
-        }
-
-        // Clear the classloader reference in the VM's bean introspector
-        java.beans.Introspector.flushCaches();
-
-        // Clear any custom URLStreamHandlers
-        TomcatURLStreamHandlerFactory.release(this);
-    }
-
-
-    /**
-     * Deregister any JDBC drivers registered by the webapp that the webapp
-     * forgot. This is made unnecessary complex because a) DriverManager
-     * checks the class loader of the calling class (it would be much easier
-     * if it checked the context class loader) b) using reflection would
-     * create a dependency on the DriverManager implementation which can,
-     * and has, changed.
-     *
-     * We can't just create an instance of JdbcLeakPrevention as it will be
-     * loaded by the common class loader (since it's .class file is in the
-     * $CATALINA_HOME/lib directory). This would fail DriverManager's check
-     * on the class loader of the calling class. So, we load the bytes via
-     * our parent class loader but define the class with this class loader
-     * so the JdbcLeakPrevention looks like a webapp class to the
-     * DriverManager.
-     *
-     * If only apps cleaned up after themselves...
-     */
-    private final void clearReferencesJdbc() {
-        // We know roughly how big the class will be (~ 1K) so allow 2k as a
-        // starting point
-        byte[] classBytes = new byte[2048];
-        int offset = 0;
-        try (InputStream is = getResourceAsStream(
-                "org/apache/catalina/loader/JdbcLeakPrevention.class")) {
-            int read = is.read(classBytes, offset, classBytes.length-offset);
-            while (read > -1) {
-                offset += read;
-                if (offset == classBytes.length) {
-                    // Buffer full - double size
-                    byte[] tmp = new byte[classBytes.length * 2];
-                    System.arraycopy(classBytes, 0, tmp, 0, classBytes.length);
-                    classBytes = tmp;
-                }
-                read = is.read(classBytes, offset, classBytes.length-offset);
-            }
-            Class<?> lpClass =
-                defineClass("org.apache.catalina.loader.JdbcLeakPrevention",
-                    classBytes, 0, offset, this.getClass().getProtectionDomain());
-            Object obj = lpClass.getConstructor().newInstance();
-            @SuppressWarnings("unchecked")
-            List<String> driverNames = (List<String>) obj.getClass().getMethod(
-                    "clearJdbcDriverRegistrations").invoke(obj);
-            for (String name : driverNames) {
-                log.warn(sm.getString("webappClassLoader.clearJdbc",
-                        getContextName(), name));
-            }
-        } catch (Exception e) {
-            // So many things to go wrong above...
-            Throwable t = ExceptionUtils.unwrapInvocationTargetException(e);
-            ExceptionUtils.handleThrowable(t);
-            log.warn(sm.getString(
-                    "webappClassLoader.jdbcRemoveFailed", getContextName()), t);
-        }
-    }
-
-
-    @SuppressWarnings("deprecation") // thread.stop()
-    private void clearReferencesThreads() {
-        Thread[] threads = getThreads();
-        List<Thread> threadsToStop = new ArrayList<>();
-
-        // Iterate over the set of threads
-        for (Thread thread : threads) {
-            if (thread != null) {
-                ClassLoader ccl = thread.getContextClassLoader();
-                if (ccl == this) {
-                    // Don't warn about this thread
-                    if (thread == Thread.currentThread()) {
-                        continue;
-                    }
-
-                    final String threadName = thread.getName();
-
-                    // JVM controlled threads
-                    ThreadGroup tg = thread.getThreadGroup();
-                    if (tg != null && JVM_THREAD_GROUP_NAMES.contains(tg.getName())) {
-                        // HttpClient keep-alive threads
-                        if (clearReferencesHttpClientKeepAliveThread &&
-                                threadName.equals("Keep-Alive-Timer")) {
-                            thread.setContextClassLoader(parent);
-                            log.debug(sm.getString("webappClassLoader.checkThreadsHttpClient"));
-                        }
-
-                        // Don't warn about remaining JVM controlled threads
-                        continue;
-                    }
-
-                    // Skip threads that have already died
-                    if (!thread.isAlive()) {
-                        continue;
-                    }
-
-                    // TimerThread can be stopped safely so treat separately
-                    // "java.util.TimerThread" in Sun/Oracle JDK
-                    // "java.util.Timer$TimerImpl" in Apache Harmony and in IBM JDK
-                    if (thread.getClass().getName().startsWith("java.util.Timer") &&
-                            clearReferencesStopTimerThreads) {
-                        clearReferencesStopTimerThread(thread);
-                        continue;
-                    }
-
-                    if (isRequestThread(thread)) {
-                        log.warn(sm.getString("webappClassLoader.stackTraceRequestThread",
-                                getContextName(), threadName, getStackTrace(thread)));
-                    } else {
-                        log.warn(sm.getString("webappClassLoader.stackTrace",
-                                getContextName(), threadName, getStackTrace(thread)));
-                    }
-
-                    // Don't try and stop the threads unless explicitly
-                    // configured to do so
-                    if (!clearReferencesStopThreads) {
-                        continue;
-                    }
-
-                    // If the thread has been started via an executor, try
-                    // shutting down the executor
-                    boolean usingExecutor = false;
-                    try {
-
-                        // Runnable wrapped by Thread
-                        // "target" in Sun/Oracle JDK
-                        // "runnable" in IBM JDK
-                        // "action" in Apache Harmony
-                        Object target = null;
-                        for (String fieldName : new String[] { "target", "runnable", "action" }) {
-                            try {
-                                Field targetField = thread.getClass().getDeclaredField(fieldName);
-                                targetField.setAccessible(true);
-                                target = targetField.get(thread);
-                                break;
-                            } catch (NoSuchFieldException nfe) {
-                                continue;
-                            }
-                        }
-
-                        // "java.util.concurrent" code is in public domain,
-                        // so all implementations are similar
-                        if (target != null && target.getClass().getCanonicalName() != null &&
-                                target.getClass().getCanonicalName().equals(
-                                        "java.util.concurrent.ThreadPoolExecutor.Worker")) {
-                            Field executorField = target.getClass().getDeclaredField("this$0");
-                            executorField.setAccessible(true);
-                            Object executor = executorField.get(target);
-                            if (executor instanceof ThreadPoolExecutor) {
-                                ((ThreadPoolExecutor) executor).shutdownNow();
-                                usingExecutor = true;
-                            }
-                        }
-                    } catch (SecurityException | NoSuchFieldException | IllegalArgumentException |
-                            IllegalAccessException e) {
-                        log.warn(sm.getString("webappClassLoader.stopThreadFail",
-                                thread.getName(), getContextName()), e);
-                    }
-
-                    // Stopping an executor automatically interrupts the
-                    // associated threads. For non-executor threads, interrupt
-                    // them here.
-                    if (!usingExecutor && !thread.isInterrupted()) {
-                        thread.interrupt();
-                    }
-
-                    // Threads are expected to take a short time to stop after
-                    // being interrupted. Make a note of all threads that are
-                    // expected to stop to enable them to be checked at the end
-                    // of this method.
-                    threadsToStop.add(thread);
-                }
-            }
-        }
-
-        // If thread stopping is enabled, threads should have been stopped above
-        // when the executor was shut down or the thread was interrupted but
-        // that depends on the thread correctly handling the interrupt. Check
-        // each thread and if any are still running give all threads up to a
-        // total of 2 seconds to shutdown.
-        int count = 0;
-        for (Thread t : threadsToStop) {
-            while (t.isAlive() && count < 100) {
-                try {
-                    Thread.sleep(20);
-                } catch (InterruptedException e) {
-                    // Quit the while loop
-                    break;
-                }
-                count++;
-            }
-            if (t.isAlive()) {
-                // This method is deprecated and for good reason. This is
-                // very risky code but is the only option at this point.
-                // A *very* good reason for apps to do this clean-up
-                // themselves.
-                t.stop();
-            }
-        }
-    }
-
-
-    /*
-     * Look at a threads stack trace to see if it is a request thread or not. It
-     * isn't perfect, but it should be good-enough for most cases.
-     */
-    private boolean isRequestThread(Thread thread) {
-
-        StackTraceElement[] elements = thread.getStackTrace();
-
-        if (elements == null || elements.length == 0) {
-            // Must have stopped already. Too late to ignore it. Assume not a
-            // request processing thread.
-            return false;
-        }
-
-        // Step through the methods in reverse order looking for calls to any
-        // CoyoteAdapter method. All request threads will have this unless
-        // Tomcat has been heavily modified - in which case there isn't much we
-        // can do.
-        for (int i = 0; i < elements.length; i++) {
-            StackTraceElement element = elements[elements.length - (i+1)];
-            if ("org.apache.catalina.connector.CoyoteAdapter".equals(
-                    element.getClassName())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    private void clearReferencesStopTimerThread(Thread thread) {
-
-        // Need to get references to:
-        // in Sun/Oracle JDK:
-        // - newTasksMayBeScheduled field (in java.util.TimerThread)
-        // - queue field
-        // - queue.clear()
-        // in IBM JDK, Apache Harmony:
-        // - cancel() method (in java.util.Timer$TimerImpl)
-
-        try {
-
-            try {
-                Field newTasksMayBeScheduledField =
-                    thread.getClass().getDeclaredField("newTasksMayBeScheduled");
-                newTasksMayBeScheduledField.setAccessible(true);
-                Field queueField = thread.getClass().getDeclaredField("queue");
-                queueField.setAccessible(true);
-
-                Object queue = queueField.get(thread);
-
-                Method clearMethod = queue.getClass().getDeclaredMethod("clear");
-                clearMethod.setAccessible(true);
-
-                synchronized(queue) {
-                    newTasksMayBeScheduledField.setBoolean(thread, false);
-                    clearMethod.invoke(queue);
-                    // In case queue was already empty. Should only be one
-                    // thread waiting but use notifyAll() to be safe.
-                    queue.notifyAll();
-                }
-
-            }catch (NoSuchFieldException nfe){
-                Method cancelMethod = thread.getClass().getDeclaredMethod("cancel");
-                synchronized(thread) {
-                    cancelMethod.setAccessible(true);
-                    cancelMethod.invoke(thread);
-                }
-            }
-
-            log.warn(sm.getString("webappClassLoader.warnTimerThread",
-                    getContextName(), thread.getName()));
-
-        } catch (Exception e) {
-            // So many things to go wrong above...
-            Throwable t = ExceptionUtils.unwrapInvocationTargetException(e);
-            ExceptionUtils.handleThrowable(t);
-            log.warn(sm.getString(
-                    "webappClassLoader.stopTimerThreadFail",
-                    thread.getName(), getContextName()), t);
-        }
-    }
-
-    private void checkThreadLocalsForLeaks() {
-        Thread[] threads = getThreads();
-
-        try {
-            // Make the fields in the Thread class that store ThreadLocals
-            // accessible
-            Field threadLocalsField =
-                Thread.class.getDeclaredField("threadLocals");
-            threadLocalsField.setAccessible(true);
-            Field inheritableThreadLocalsField =
-                Thread.class.getDeclaredField("inheritableThreadLocals");
-            inheritableThreadLocalsField.setAccessible(true);
-            // Make the underlying array of ThreadLoad.ThreadLocalMap.Entry objects
-            // accessible
-            Class<?> tlmClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
-            Field tableField = tlmClass.getDeclaredField("table");
-            tableField.setAccessible(true);
-            Method expungeStaleEntriesMethod = tlmClass.getDeclaredMethod("expungeStaleEntries");
-            expungeStaleEntriesMethod.setAccessible(true);
-
-            for (Thread thread : threads) {
-                Object threadLocalMap;
-                if (thread != null) {
-
-                    // Clear the first map
-                    threadLocalMap = threadLocalsField.get(thread);
-                    if (null != threadLocalMap) {
-                        expungeStaleEntriesMethod.invoke(threadLocalMap);
-                        checkThreadLocalMapForLeaks(threadLocalMap, tableField);
-                    }
-
-                    // Clear the second map
-                    threadLocalMap = inheritableThreadLocalsField.get(thread);
-                    if (null != threadLocalMap) {
-                        expungeStaleEntriesMethod.invoke(threadLocalMap);
-                        checkThreadLocalMapForLeaks(threadLocalMap, tableField);
-                    }
-                }
-            }
-        } catch (Throwable t) {
-            JreCompat jreCompat = JreCompat.getInstance();
-            if (jreCompat.isInstanceOfInaccessibleObjectException(t)) {
-                // Must be running on Java 9 without the necessary command line
-                // options.
-                log.warn(sm.getString("webappClassLoader.addExportsThreadLocal"));
-            } else {
-                ExceptionUtils.handleThrowable(t);
-                log.warn(sm.getString(
-                        "webappClassLoader.checkThreadLocalsForLeaksFail",
-                        getContextName()), t);
-            }
-        }
-    }
-
-
-    /**
-     * Analyzes the given thread local map object. Also pass in the field that
-     * points to the internal table to save re-calculating it on every
-     * call to this method.
-     */
-    private void checkThreadLocalMapForLeaks(Object map,
-            Field internalTableField) throws IllegalAccessException,
-            NoSuchFieldException {
-        if (map != null) {
-            Object[] table = (Object[]) internalTableField.get(map);
-            if (table != null) {
-                for (Object obj : table) {
-                    if (obj != null) {
-                        boolean keyLoadedByWebapp = false;
-                        boolean valueLoadedByWebapp = false;
-                        // Check the key
-                        Object key = ((Reference<?>) obj).get();
-                        if (this.equals(key) || loadedByThisOrChild(key)) {
-                            keyLoadedByWebapp = true;
-                        }
-                        // Check the value
-                        Field valueField =
-                                obj.getClass().getDeclaredField("value");
-                        valueField.setAccessible(true);
-                        Object value = valueField.get(obj);
-                        if (this.equals(value) || loadedByThisOrChild(value)) {
-                            valueLoadedByWebapp = true;
-                        }
-                        if (keyLoadedByWebapp || valueLoadedByWebapp) {
-                            Object[] args = new Object[5];
-                            args[0] = getContextName();
-                            if (key != null) {
-                                args[1] = getPrettyClassName(key.getClass());
-                                try {
-                                    args[2] = key.toString();
-                                } catch (Exception e) {
-                                    log.warn(sm.getString(
-                                            "webappClassLoader.checkThreadLocalsForLeaks.badKey",
-                                            args[1]), e);
-                                    args[2] = sm.getString(
-                                            "webappClassLoader.checkThreadLocalsForLeaks.unknown");
-                                }
-                            }
-                            if (value != null) {
-                                args[3] = getPrettyClassName(value.getClass());
-                                try {
-                                    args[4] = value.toString();
-                                } catch (Exception e) {
-                                    log.warn(sm.getString(
-                                            "webappClassLoader.checkThreadLocalsForLeaks.badValue",
-                                            args[3]), e);
-                                    args[4] = sm.getString(
-                                            "webappClassLoader.checkThreadLocalsForLeaks.unknown");
-                                }
-                            }
-                            if (valueLoadedByWebapp) {
-                                log.error(sm.getString(
-                                        "webappClassLoader.checkThreadLocalsForLeaks",
-                                        args));
-                            } else if (value == null) {
-                                if (log.isDebugEnabled()) {
-                                    log.debug(sm.getString(
-                                            "webappClassLoader.checkThreadLocalsForLeaksNull",
-                                            args));
-                                }
-                            } else {
-                                if (log.isDebugEnabled()) {
-                                    log.debug(sm.getString(
-                                            "webappClassLoader.checkThreadLocalsForLeaksNone",
-                                            args));
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private String getPrettyClassName(Class<?> clazz) {
-        String name = clazz.getCanonicalName();
-        if (name==null){
-            name = clazz.getName();
-        }
-        return name;
-    }
-
-    private String getStackTrace(Thread thread) {
-        StringBuilder builder = new StringBuilder();
-        for (StackTraceElement ste : thread.getStackTrace()) {
-            builder.append("\n ").append(ste);
-        }
-        return builder.toString();
-    }
-
-    /**
-     * @param o object to test, may be null
-     * @return <code>true</code> if o has been loaded by the current classloader
-     * or one of its descendants.
-     */
-    private boolean loadedByThisOrChild(Object o) {
-        if (o == null) {
-            return false;
-        }
-
-        Class<?> clazz;
-        if (o instanceof Class) {
-            clazz = (Class<?>) o;
-        } else {
-            clazz = o.getClass();
-        }
-
-        ClassLoader cl = clazz.getClassLoader();
-        while (cl != null) {
-            if (cl == this) {
-                return true;
-            }
-            cl = cl.getParent();
-        }
-
-        if (o instanceof Collection<?>) {
-            Iterator<?> iter = ((Collection<?>) o).iterator();
-            try {
-                while (iter.hasNext()) {
-                    Object entry = iter.next();
-                    if (loadedByThisOrChild(entry)) {
-                        return true;
-                    }
-                }
-            } catch (ConcurrentModificationException e) {
-                log.warn(sm.getString(
-                        "webappClassLoader.loadedByThisOrChildFail", clazz.getName(), getContextName()),
-                        e);
-            }
-        }
-        return false;
-    }
-
-    /*
-     * Get the set of current threads as an array.
-     */
-    private Thread[] getThreads() {
-        // Get the current thread group
-        ThreadGroup tg = Thread.currentThread().getThreadGroup();
-        // Find the root thread group
-        try {
-            while (tg.getParent() != null) {
-                tg = tg.getParent();
-            }
-        } catch (SecurityException se) {
-            String msg = sm.getString(
-                    "webappClassLoader.getThreadGroupError", tg.getName());
-            if (log.isDebugEnabled()) {
-                log.debug(msg, se);
-            } else {
-                log.warn(msg);
-            }
-        }
-
-        int threadCountGuess = tg.activeCount() + 50;
-        Thread[] threads = new Thread[threadCountGuess];
-        int threadCountActual = tg.enumerate(threads);
-        // Make sure we don't miss any threads
-        while (threadCountActual == threadCountGuess) {
-            threadCountGuess *=2;
-            threads = new Thread[threadCountGuess];
-            // Note tg.enumerate(Thread[]) silently ignores any threads that
-            // can't fit into the array
-            threadCountActual = tg.enumerate(threads);
-        }
-
-        return threads;
-    }
-
-
-    /**
-     * This depends on the internals of the Sun JVM so it does everything by
-     * reflection.
-     */
-    private void clearReferencesRmiTargets() {
-        try {
-            // Need access to the ccl field of sun.rmi.transport.Target to find
-            // the leaks
-            Class<?> objectTargetClass =
-                Class.forName("sun.rmi.transport.Target");
-            Field cclField = objectTargetClass.getDeclaredField("ccl");
-            cclField.setAccessible(true);
-            // Need access to the stub field to report the leaks
-            Field stubField = objectTargetClass.getDeclaredField("stub");
-            stubField.setAccessible(true);
-
-            // Clear the objTable map
-            Class<?> objectTableClass = Class.forName("sun.rmi.transport.ObjectTable");
-            Field objTableField = objectTableClass.getDeclaredField("objTable");
-            objTableField.setAccessible(true);
-            Object objTable = objTableField.get(null);
-            if (objTable == null) {
-                return;
-            }
-            Field tableLockField = objectTableClass.getDeclaredField("tableLock");
-            tableLockField.setAccessible(true);
-            Object tableLock = tableLockField.get(null);
-
-            synchronized (tableLock) {
-                // Iterate over the values in the table
-                if (objTable instanceof Map<?,?>) {
-                    Iterator<?> iter = ((Map<?,?>) objTable).values().iterator();
-                    while (iter.hasNext()) {
-                        Object obj = iter.next();
-                        Object cclObject = cclField.get(obj);
-                        if (this == cclObject) {
-                            iter.remove();
-                            Object stubObject = stubField.get(obj);
-                            log.error(sm.getString("webappClassLoader.clearRmi",
-                                    stubObject.getClass().getName(), stubObject));
-                        }
-                    }
-                }
-
-                // Clear the implTable map
-                Field implTableField = objectTableClass.getDeclaredField("implTable");
-                implTableField.setAccessible(true);
-                Object implTable = implTableField.get(null);
-                if (implTable == null) {
-                    return;
-                }
-
-                // Iterate over the values in the table
-                if (implTable instanceof Map<?,?>) {
-                    Iterator<?> iter = ((Map<?,?>) implTable).values().iterator();
-                    while (iter.hasNext()) {
-                        Object obj = iter.next();
-                        Object cclObject = cclField.get(obj);
-                        if (this == cclObject) {
-                            iter.remove();
-                        }
-                    }
-                }
-            }
-        } catch (ClassNotFoundException e) {
-            log.info(sm.getString("webappClassLoader.clearRmiInfo",
-                    getContextName()), e);
-        } catch (SecurityException | NoSuchFieldException | IllegalArgumentException |
-                IllegalAccessException e) {
-            log.warn(sm.getString("webappClassLoader.clearRmiFail",
-                    getContextName()), e);
-        } catch (Exception e) {
-            JreCompat jreCompat = JreCompat.getInstance();
-            if (jreCompat.isInstanceOfInaccessibleObjectException(e)) {
-                // Must be running on Java 9 without the necessary command line
-                // options.
-                log.warn(sm.getString("webappClassLoader.addExportsRmi"));
-            } else {
-                // Re-throw all other exceptions
-                throw e;
-            }
-        }
-    }
-
-
-    private void clearReferencesObjectStreamClassCaches() {
-        try {
-            Class<?> clazz = Class.forName("java.io.ObjectStreamClass$Caches");
-            clearCache(clazz, "localDescs");
-            clearCache(clazz, "reflectors");
-        } catch (ReflectiveOperationException | SecurityException | ClassCastException e) {
-            log.warn(sm.getString(
-                    "webappClassLoader.clearObjectStreamClassCachesFail", getContextName()), e);
-        }
-    }
-
-
-    private void clearCache(Class<?> target, String mapName)
-            throws ReflectiveOperationException, SecurityException, ClassCastException {
-        Field f = target.getDeclaredField(mapName);
-        f.setAccessible(true);
-        Map<?,?> map = (Map<?,?>) f.get(null);
-        Iterator<?> keys = map.keySet().iterator();
-        while (keys.hasNext()) {
-            Object key = keys.next();
-            if (key instanceof Reference) {
-                Object clazz = ((Reference<?>) key).get();
-                if (loadedByThisOrChild(clazz)) {
-                    keys.remove();
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Find specified class in local repositories.
-     *
-     * @param name The binary name of the class to be loaded
-     *
-     * @return the loaded class, or null if the class isn't found
-     */
-    protected Class<?> findClassInternal(String name) {
-
-        checkStateForResourceLoading(name);
-
-        if (name == null) {
-            return null;
-        }
-        String path = binaryNameToPath(name, true);
-
-        ResourceEntry entry = resourceEntries.get(path);
-        WebResource resource = null;
-
-        if (entry == null) {
-            resource = resources.getClassLoaderResource(path);
-
-            if (!resource.exists()) {
-                return null;
-            }
-
-            entry = new ResourceEntry();
-            entry.lastModified = resource.getLastModified();
-
-            // Add the entry in the local resource repository
-            synchronized (resourceEntries) {
-                // Ensures that all the threads which may be in a race to load
-                // a particular class all end up with the same ResourceEntry
-                // instance
-                ResourceEntry entry2 = resourceEntries.get(path);
-                if (entry2 == null) {
-                    resourceEntries.put(path, entry);
-                } else {
-                    entry = entry2;
-                }
-            }
-        }
-
-        Class<?> clazz = entry.loadedClass;
-        if (clazz != null)
-            return clazz;
-
-        synchronized (JreCompat.isGraalAvailable() ? this : getClassLoadingLock(name)) {
-            clazz = entry.loadedClass;
-            if (clazz != null)
-                return clazz;
-
-            if (resource == null) {
-                resource = resources.getClassLoaderResource(path);
-            }
-
-            if (!resource.exists()) {
-                return null;
-            }
-
-            byte[] binaryContent = resource.getContent();
-            if (binaryContent == null) {
-                // Something went wrong reading the class bytes (and will have
-                // been logged at debug level).
-                return null;
-            }
-            Manifest manifest = resource.getManifest();
-            URL codeBase = resource.getCodeBase();
-            Certificate[] certificates = resource.getCertificates();
-
-            if (transformers.size() > 0) {
-                // If the resource is a class just being loaded, decorate it
-                // with any attached transformers
-
-                // Ignore leading '/' and trailing CLASS_FILE_SUFFIX
-                // Should be cheaper than replacing '.' by '/' in class name.
-                String internalName = path.substring(1, path.length() - CLASS_FILE_SUFFIX.length());
-
-                for (ClassFileTransformer transformer : this.transformers) {
-                    try {
-                        byte[] transformed = transformer.transform(
-                                this, internalName, null, null, binaryContent);
-                        if (transformed != null) {
-                            binaryContent = transformed;
-                        }
-                    } catch (IllegalClassFormatException e) {
-                        log.error(sm.getString("webappClassLoader.transformError", name), e);
-                        return null;
-                    }
-                }
-            }
-
-            // Looking up the package
-            String packageName = null;
-            int pos = name.lastIndexOf('.');
-            if (pos != -1)
-                packageName = name.substring(0, pos);
-
-            Package pkg = null;
-
-            if (packageName != null) {
-                pkg = getPackage(packageName);
-                // Define the package (if null)
-                if (pkg == null) {
-                    try {
-                        if (manifest == null) {
-                            definePackage(packageName, null, null, null, null, null, null, null);
-                        } else {
-                            definePackage(packageName, manifest, codeBase);
-                        }
-                    } catch (IllegalArgumentException e) {
-                        // Ignore: normal error due to dual definition of package
-                    }
-                    pkg = getPackage(packageName);
-                }
-            }
-
-            if (securityManager != null) {
-
-                // Checking sealing
-                if (pkg != null) {
-                    boolean sealCheck = true;
-                    if (pkg.isSealed()) {
-                        sealCheck = pkg.isSealed(codeBase);
-                    } else {
-                        sealCheck = (manifest == null) || !isPackageSealed(packageName, manifest);
-                    }
-                    if (!sealCheck)
-                        throw new SecurityException
-                            ("Sealing violation loading " + name + " : Package "
-                             + packageName + " is sealed.");
-                }
-
-            }
-
-            try {
-                clazz = defineClass(name, binaryContent, 0,
-                        binaryContent.length, new CodeSource(codeBase, certificates));
-            } catch (UnsupportedClassVersionError ucve) {
-                throw new UnsupportedClassVersionError(
-                        ucve.getLocalizedMessage() + " " +
-                        sm.getString("webappClassLoader.wrongVersion",
-                                name));
-            }
-            entry.loadedClass = clazz;
-        }
-
-        return clazz;
-    }
-
-
-    private String binaryNameToPath(String binaryName, boolean withLeadingSlash) {
-        // 1 for leading '/', 6 for ".class"
-        StringBuilder path = new StringBuilder(7 + binaryName.length());
-        if (withLeadingSlash) {
-            path.append('/');
-        }
-        path.append(binaryName.replace('.', '/'));
-        path.append(CLASS_FILE_SUFFIX);
-        return path.toString();
-    }
-
-
-    private String nameToPath(String name) {
-        if (name.startsWith("/")) {
-            return name;
-        }
-        StringBuilder path = new StringBuilder(
-                1 + name.length());
-        path.append('/');
-        path.append(name);
-        return path.toString();
-    }
-
-
-    /**
-     * Returns true if the specified package name is sealed according to the
-     * given manifest.
-     *
-     * @param name Path name to check
-     * @param man Associated manifest
-     * @return <code>true</code> if the manifest associated says it is sealed
-     */
-    protected boolean isPackageSealed(String name, Manifest man) {
-
-        String path = name.replace('.', '/') + '/';
-        Attributes attr = man.getAttributes(path);
-        String sealed = null;
-        if (attr != null) {
-            sealed = attr.getValue(Name.SEALED);
-        }
-        if (sealed == null) {
-            if ((attr = man.getMainAttributes()) != null) {
-                sealed = attr.getValue(Name.SEALED);
-            }
-        }
-        return "true".equalsIgnoreCase(sealed);
-
-    }
-
-
-    /**
-     * Finds the class with the given name if it has previously been
-     * loaded and cached by this class loader, and return the Class object.
-     * If this class has not been cached, return <code>null</code>.
-     *
-     * @param name The binary name of the resource to return
-     * @return a loaded class
-     */
-    protected Class<?> findLoadedClass0(String name) {
-
-        String path = binaryNameToPath(name, true);
-
-        ResourceEntry entry = resourceEntries.get(path);
-        if (entry != null) {
-            return entry.loadedClass;
-        }
-        return null;
-    }
-
-
-    /**
-     * Refresh the system policy file, to pick up eventual changes.
-     */
-    protected void refreshPolicy() {
-
-        try {
-            // The policy file may have been modified to adjust
-            // permissions, so we're reloading it when loading or
-            // reloading a Context
-            Policy policy = Policy.getPolicy();
-            policy.refresh();
-        } catch (AccessControlException e) {
-            // Some policy files may restrict this, even for the core,
-            // so this exception is ignored
-        }
-
-    }
-
-
-    /**
-     * Filter classes.
-     *
-     * @param name class name
-     * @param isClassName <code>true</code> if name is a class name,
-     *                <code>false</code> if name is a resource name
-     * @return <code>true</code> if the class should be filtered
-     */
-    protected boolean filter(String name, boolean isClassName) {
-
-        if (name == null)
-            return false;
-
-        char ch;
-        if (name.startsWith("jakarta")) {
-            /* 7 == length("jakarta") */
-            if (name.length() == 7) {
-                return false;
-            }
-            ch = name.charAt(7);
-            if (isClassName && ch == '.') {
-                /* 8 == length("jakarta.") */
-                if (name.startsWith("servlet.jsp.jstl.", 8)) {
-                    return false;
-                }
-                if (name.startsWith("el.", 8) ||
-                    name.startsWith("servlet.", 8) ||
-                    name.startsWith("websocket.", 8) ||
-                    name.startsWith("security.auth.message.", 8)) {
-                    return true;
-                }
-            } else if (!isClassName && ch == '/') {
-                /* 8 == length("jakarta/") */
-                if (name.startsWith("servlet/jsp/jstl/", 8)) {
-                    return false;
-                }
-                if (name.startsWith("el/", 8) ||
-                    name.startsWith("servlet/", 8) ||
-                    name.startsWith("websocket/", 8) ||
-                    name.startsWith("security/auth/message/", 8)) {
-                    return true;
-                }
-            }
-        } else if (name.startsWith("javax")) {
-            /* 5 == length("javax") */
-            if (name.length() == 5) {
-                return false;
-            }
-            ch = name.charAt(5);
-            if (isClassName && ch == '.') {
-                /* 6 == length("javax.") */
-                if (name.startsWith("websocket.", 6)) {
-                    return true;
-                }
-            } else if (!isClassName && ch == '/') {
-                /* 6 == length("javax/") */
-                if (name.startsWith("websocket/", 6)) {
-                    return true;
-                }
-            }
-        } else if (name.startsWith("org")) {
-            /* 3 == length("org") */
-            if (name.length() == 3) {
-                return false;
-            }
-            ch = name.charAt(3);
-            if (isClassName && ch == '.') {
-                /* 4 == length("org.") */
-                if (name.startsWith("apache.", 4)) {
-                    /* 11 == length("org.apache.") */
-                    if (name.startsWith("tomcat.jdbc.", 11)) {
-                        return false;
-                    }
-                    if (name.startsWith("el.", 11) ||
-                        name.startsWith("catalina.", 11) ||
-                        name.startsWith("jasper.", 11) ||
-                        name.startsWith("juli.", 11) ||
-                        name.startsWith("tomcat.", 11) ||
-                        name.startsWith("naming.", 11) ||
-                        name.startsWith("coyote.", 11)) {
-                        return true;
-                    }
-                }
-            } else if (!isClassName && ch == '/') {
-                /* 4 == length("org/") */
-                if (name.startsWith("apache/", 4)) {
-                    /* 11 == length("org/apache/") */
-                    if (name.startsWith("tomcat/jdbc/", 11)) {
-                        return false;
-                    }
-                    if (name.startsWith("el/", 11) ||
-                        name.startsWith("catalina/", 11) ||
-                        name.startsWith("jasper/", 11) ||
-                        name.startsWith("juli/", 11) ||
-                        name.startsWith("tomcat/", 11) ||
-                        name.startsWith("naming/", 11) ||
-                        name.startsWith("coyote/", 11)) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-
-    @Override
-    protected void addURL(URL url) {
-        super.addURL(url);
-        hasExternalRepositories = true;
-    }
-
-
-    @Override
-    public String getWebappName() {
-        return getContextName();
-    }
-
-
-    @Override
-    public String getHostName() {
-        if (resources != null) {
-            Container host = resources.getContext().getParent();
-            if (host != null) {
-                return host.getName();
-            }
-        }
-        return null;
-    }
-
-
-    @Override
-    public String getServiceName() {
-        if (resources != null) {
-            Container host = resources.getContext().getParent();
-            if (host != null) {
-                Container engine = host.getParent();
-                if (engine != null) {
-                    return engine.getName();
-                }
-            }
-        }
-        return null;
-    }
-
-
-    @Override
-    public boolean hasLoggingConfig() {
-        if (Globals.IS_SECURITY_ENABLED) {
-            Boolean result = AccessController.doPrivileged(new PrivilegedHasLoggingConfig());
-            return result.booleanValue();
-        } else {
-            return findResource("logging.properties") != null;
-        }
-    }
-
-
-    private class PrivilegedHasLoggingConfig implements PrivilegedAction<Boolean> {
-
-        @Override
-        public Boolean run() {
-            return Boolean.valueOf(findResource("logging.properties") != null);
-        }
-    }
-
-
-    private static class CombinedEnumeration implements Enumeration<URL> {
-
-        private final Enumeration<URL>[] sources;
-        private int index = 0;
-
-        public CombinedEnumeration(Enumeration<URL> enum1, Enumeration<URL> enum2) {
-            @SuppressWarnings("unchecked")
-            Enumeration<URL>[] sources = new Enumeration[] { enum1, enum2 };
-            this.sources = sources;
-        }
-
-
-        @Override
-        public boolean hasMoreElements() {
-            return inc();
-        }
-
-
-        @Override
-        public URL nextElement() {
-            if (inc()) {
-                return sources[index].nextElement();
-            }
-            throw new NoSuchElementException();
-        }
-
-
-        private boolean inc() {
-            while (index < sources.length) {
-                if (sources[index].hasMoreElements()) {
-                    return true;
-                }
-                index++;
-            }
-            return false;
-        }
-    }
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/apache/cxf/jaxb/JAXBContextInitializer.java b/jakarta/src/patch/java/org/apache/cxf/jaxb/JAXBContextInitializer.java
deleted file mode 100644
index 37b2d07..0000000
--- a/jakarta/src/patch/java/org/apache/cxf/jaxb/JAXBContextInitializer.java
+++ /dev/null
@@ -1,611 +0,0 @@
-/**
- * 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.jaxb;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAttribute;
-import jakarta.xml.bind.annotation.XmlElement;
-import jakarta.xml.bind.annotation.XmlRootElement;
-import jakarta.xml.bind.annotation.XmlSeeAlso;
-import jakarta.xml.bind.annotation.XmlTransient;
-import jakarta.xml.bind.annotation.XmlType;
-import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
-import javax.xml.namespace.QName;
-
-import org.apache.cxf.common.classloader.ClassLoaderUtils;
-import org.apache.cxf.common.jaxb.JAXBUtils;
-import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.common.util.ASMHelper.ClassWriter;
-import org.apache.cxf.common.util.ASMHelper.MethodVisitor;
-import org.apache.cxf.common.util.ASMHelper.Opcodes;
-import org.apache.cxf.common.util.ReflectionUtil;
-import org.apache.cxf.common.util.StringUtils;
-import org.apache.cxf.service.ServiceModelVisitor;
-import org.apache.cxf.service.model.MessageInfo;
-import org.apache.cxf.service.model.MessagePartInfo;
-import org.apache.cxf.service.model.OperationInfo;
-import org.apache.cxf.service.model.ServiceInfo;
-import org.apache.cxf.service.model.UnwrappedOperationInfo;
-
-/**
- * Walks the service model and sets up the classes for the context.
- */
-class JAXBContextInitializer extends ServiceModelVisitor {
-    private static final Logger LOG = LogUtils.getL7dLogger(JAXBContextInitializer.class);
-    private Set<Class<?>> classes;
-    private Collection<Object> typeReferences;
-    private Set<Class<?>> globalAdapters = new HashSet<>();
-    private Map<String, Object> unmarshallerProperties;
-
-    JAXBContextInitializer(ServiceInfo serviceInfo,
-                                  Set<Class<?>> classes,
-                                  Collection<Object> typeReferences,
-                                  Map<String, Object> unmarshallerProperties) {
-        super(serviceInfo);
-        this.classes = classes;
-        this.typeReferences = typeReferences;
-        this.unmarshallerProperties = unmarshallerProperties;
-    }
-
-    @Override
-    public void begin(MessagePartInfo part) {
-        Class<?> clazz = part.getTypeClass();
-        if (clazz == null) {
-            return;
-        }
-
-        if (Exception.class.isAssignableFrom(clazz)) {
-            //exceptions are handled special, make sure we mark it
-            part.setProperty(JAXBDataBinding.class.getName() + ".CUSTOM_EXCEPTION",
-                             Boolean.TRUE);
-        }
-        boolean isFromWrapper = part.getMessageInfo().getOperation().isUnwrapped();
-        if (isFromWrapper
-            && !Boolean.TRUE.equals(part.getProperty("messagepart.isheader"))) {
-            UnwrappedOperationInfo uop = (UnwrappedOperationInfo)part.getMessageInfo().getOperation();
-            OperationInfo op = uop.getWrappedOperation();
-            MessageInfo inf = null;
-            if (uop.getInput() == part.getMessageInfo()) {
-                inf = op.getInput();
-            } else if (uop.getOutput() == part.getMessageInfo()) {
-                inf = op.getOutput();
-            }
-            if (inf != null
-                && inf.getFirstMessagePart().getTypeClass() != null) {
-                //if the wrapper has a type class, we don't need to do anything
-                //as everything would have been discovered when walking the
-                //wrapper type (unless it's a header which wouldn't be in the wrapper)
-                return;
-            }
-        }
-        if (isFromWrapper
-            && clazz.isArray()
-            && !Byte.TYPE.equals(clazz.getComponentType())) {
-            clazz = clazz.getComponentType();
-        }
-
-        Annotation[] a = (Annotation[])part.getProperty("parameter.annotations");
-        checkForAdapter(clazz, a);
-
-        Type genericType = (Type) part.getProperty("generic.type");
-        if (genericType != null) {
-            boolean isList = Collection.class.isAssignableFrom(clazz);
-            if (isFromWrapper) {
-                if (genericType instanceof Class
-                    && ((Class<?>)genericType).isArray()) {
-                    Class<?> cl2 = (Class<?>)genericType;
-                    if (cl2.isArray()
-                        && !Byte.TYPE.equals(cl2.getComponentType())) {
-                        genericType = cl2.getComponentType();
-                    }
-                    addType(genericType);
-                } else if (!isList) {
-                    addType(genericType);
-                }
-            } else {
-                addType(genericType, true);
-            }
-
-            if (isList
-                && genericType instanceof ParameterizedType) {
-                ParameterizedType pt = (ParameterizedType) genericType;
-                if (pt.getActualTypeArguments().length > 0
-                    && pt.getActualTypeArguments()[0] instanceof Class) {
-
-                    Class<? extends Object> arrayCls =
-                        Array.newInstance((Class<?>) pt.getActualTypeArguments()[0], 0).getClass();
-                    clazz = arrayCls;
-                    part.setTypeClass(clazz);
-                    if (isFromWrapper) {
-                        addType(clazz.getComponentType(), true);
-                    }
-                } else if (pt.getActualTypeArguments().length > 0
-                    && pt.getActualTypeArguments()[0] instanceof GenericArrayType) {
-                    GenericArrayType gat = (GenericArrayType)pt.getActualTypeArguments()[0];
-                    gat.getGenericComponentType();
-                    Class<? extends Object> arrayCls =
-                        Array.newInstance((Class<?>) gat.getGenericComponentType(), 0).getClass();
-                    clazz = Array.newInstance(arrayCls, 0).getClass();
-                    part.setTypeClass(clazz);
-                    if (isFromWrapper) {
-                        addType(clazz.getComponentType(), true);
-                    }
-                }
-            }
-            if (isFromWrapper && isList) {
-                clazz = null;
-            }
-        }
-        if (clazz != null) {
-            if (!isFromWrapper
-                && clazz.getAnnotation(XmlRootElement.class) == null
-                && clazz.getAnnotation(XmlType.class) != null
-                && StringUtils.isEmpty(clazz.getAnnotation(XmlType.class).name())) {
-                Object ref = createTypeReference(part.getName(), clazz);
-                if (ref != null) {
-                    typeReferences.add(ref);
-                }
-            }
-
-            addClass(clazz);
-        }
-    }
-
-    private void checkForAdapter(Class<?> clazz, Annotation[] anns) {
-        if (anns != null) {
-            for (Annotation a : anns) {
-                if (XmlJavaTypeAdapter.class.isAssignableFrom(a.annotationType())) {
-                    Type t = Utils.getTypeFromXmlAdapter((XmlJavaTypeAdapter)a);
-                    if (t != null) {
-                        addType(t);
-                    }
-                }
-            }
-        }
-        XmlJavaTypeAdapter xjta = clazz.getAnnotation(XmlJavaTypeAdapter.class);
-        if (xjta != null) {
-            Type t = Utils.getTypeFromXmlAdapter(xjta);
-            if (t != null) {
-                addType(t);
-            }
-        }
-        if (clazz.getPackage() != null) {
-            XmlJavaTypeAdapters adapt = clazz.getPackage().getAnnotation(XmlJavaTypeAdapters.class);
-            if (adapt != null) {
-                for (XmlJavaTypeAdapter a : adapt.value()) {
-                    globalAdapters.add(a.type());
-                }
-                for (XmlJavaTypeAdapter a : adapt.value()) {
-                    Type t = Utils.getTypeFromXmlAdapter(a);
-                    if (t != null) {
-                        addType(t);
-                    }
-                }
-            }
-        }
-    }
-
-    private void addType(Type cls) {
-        addType(cls, false);
-    }
-    private void addType(Type cls, boolean allowArray) {
-        if (cls instanceof Class) {
-            if (globalAdapters.contains(cls)) {
-                return;
-            }
-            if (((Class<?>)cls).isArray() && !allowArray) {
-                addClass(((Class<?>)cls).getComponentType());
-            } else {
-                addClass((Class<?>)cls);
-            }
-        } else if (cls instanceof ParameterizedType) {
-            final ParameterizedType parameterizedType = (ParameterizedType)cls;
-            addType(parameterizedType.getRawType());
-            if (!parameterizedType.getRawType().equals(Enum.class)) {
-                for (Type t2 : parameterizedType.getActualTypeArguments()) {
-                    if (shouldTypeBeAdded(t2, parameterizedType)) {
-                        addType(t2);
-                    }
-                }
-            }
-        } else if (cls instanceof GenericArrayType) {
-            Class<?> ct;
-            GenericArrayType gt = (GenericArrayType)cls;
-            Type componentType = gt.getGenericComponentType();
-            if (componentType instanceof Class) {
-                ct = (Class<?>)componentType;
-            } else if (componentType instanceof ParameterizedType) {
-                final ParameterizedType parameterizedType = (ParameterizedType)componentType;
-                final Type rawType = parameterizedType.getRawType();
-                if (rawType instanceof Class) {
-                    ct = (Class<?>)rawType;
-                } else {
-                    throw new IllegalArgumentException("Unable to determine type for " + rawType);
-                }
-                if (!parameterizedType.getRawType().equals(Enum.class)) {
-                    for (Type t2 : parameterizedType.getActualTypeArguments()) {
-                        if (shouldTypeBeAdded(t2, parameterizedType)) {
-                            addType(t2);
-                        }
-                    }
-                }
-            } else {
-                TypeVariable<?> tv = (TypeVariable<?>)componentType;
-                Type[] bounds = tv.getBounds();
-                if (bounds != null && bounds.length == 1) {
-                    if (bounds[0] instanceof Class) {
-                        ct = (Class<?>)bounds[0];
-                    } else {
-                        throw new IllegalArgumentException("Unable to determine type for: " + tv);
-                    }
-                } else {
-                    throw new IllegalArgumentException("Unable to determine type for: " + tv);
-                }
-            }
-            ct = Array.newInstance(ct, 0).getClass();
-
-            addClass(ct);
-        } else if (cls instanceof WildcardType) {
-            for (Type t : ((WildcardType)cls).getUpperBounds()) {
-                addType(t);
-            }
-            for (Type t : ((WildcardType)cls).getLowerBounds()) {
-                addType(t);
-            }
-        } else if (cls instanceof TypeVariable) {
-            for (Type t : ((TypeVariable<?>)cls).getBounds()) {
-                addType(t);
-            }
-        }
-    }
-
-    private boolean shouldTypeBeAdded(final Type t2, final ParameterizedType parameterizedType) {
-        if (!(t2 instanceof TypeVariable)) {
-            return true;
-        }
-        TypeVariable<?> typeVariable = (TypeVariable<?>) t2;
-        final Type[] bounds = typeVariable.getBounds();
-        for (Type bound : bounds) {
-            if (bound instanceof ParameterizedType && bound.equals(parameterizedType)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    void addClass(Class<?> claz) {
-        if (Throwable.class.isAssignableFrom(claz)) {
-            if (!Throwable.class.equals(claz)
-                && !Exception.class.equals(claz)) {
-                walkReferences(claz);
-            }
-            addClass(String.class);
-        } else if (claz.getName().startsWith("java.")
-            || claz.getName().startsWith("javax.")
-            || claz.getName().startsWith("jakarta.")) {
-            return;
-        } else {
-            Class<?> cls = JAXBUtils.getValidClass(claz);
-            if (cls == null
-                && ReflectionUtil.getDeclaredConstructors(claz).length > 0
-                && !Modifier.isAbstract(claz.getModifiers())) {
-                if (LOG.isLoggable(Level.INFO)) {
-                    LOG.info("Class " + claz.getName() + " does not have a default constructor which JAXB requires.");
-                }
-                //there is no init(), but other constructors
-                Object factory = createFactory(claz, ReflectionUtil.getDeclaredConstructors(claz)[0]);
-                unmarshallerProperties.put("com.sun.xml.bind.ObjectFactory", factory);
-                cls = claz;
-            }
-            if (null != cls) {
-                if (classes.contains(cls)) {
-                    return;
-                }
-
-                if (!cls.isInterface()) {
-                    classes.add(cls);
-                }
-
-                XmlSeeAlso xsa = cls.getAnnotation(XmlSeeAlso.class);
-                if (xsa != null) {
-                    for (Class<?> c : xsa.value()) {
-                        addClass(c);
-                    }
-                }
-                XmlJavaTypeAdapter xjta = cls.getAnnotation(XmlJavaTypeAdapter.class);
-                if (xjta != null) {
-                    //has an adapter.   We need to inspect the adapter and then
-                    //return as the adapter will handle the superclass
-                    //and interfaces and such
-                    Type t = Utils.getTypeFromXmlAdapter(xjta);
-                    if (t != null) {
-                        addType(t);
-                    }
-                    return;
-                }
-
-                if (cls.getSuperclass() != null) {
-                    //JAXB should do this, but it doesn't always.
-                    //in particular, older versions of jaxb don't
-                    addClass(cls.getSuperclass());
-                }
-
-                if (!cls.isInterface()) {
-                    walkReferences(cls);
-                }
-            }
-        }
-    }
-
-    private void walkReferences(Class<?> cls) {
-        if (cls == null) {
-            return;
-        }
-        if (cls.getName().startsWith("java.")
-            || cls.getName().startsWith("javax.")
-            || cls.getName().startsWith("jakarta.")) {
-            return;
-        }
-        //walk the public fields/methods to try and find all the classes. JAXB will only load the
-        //EXACT classes in the fields/methods if they are in a different package. Thus,
-        //subclasses won't be found and the xsi:type stuff won't work at all.
-        //We'll grab the public field/method types and then add the ObjectFactory stuff
-        //as well as look for jaxb.index files in those packages.
-
-        XmlAccessType accessType = Utils.getXmlAccessType(cls);
-
-        if (accessType != XmlAccessType.PROPERTY) {   // only look for fields if we are instructed to
-            //fields are accessible even if not public, must look at the declared fields
-            //then walk to parents declared fields, etc...
-            Field[] fields = ReflectionUtil.getDeclaredFields(cls);
-            for (Field f : fields) {
-                if (isFieldAccepted(f, accessType)) {
-                    XmlJavaTypeAdapter xjta = Utils.getFieldXJTA(f);
-                    if (xjta != null) {
-                        Type t = Utils.getTypeFromXmlAdapter(xjta);
-                        if (t != null) {
-                            addType(t);
-                            continue;
-                        }
-                    }
-                    addType(f.getGenericType());
-                }
-            }
-            walkReferences(cls.getSuperclass());
-        }
-
-        if (accessType != XmlAccessType.FIELD) {   // only look for methods if we are instructed to
-            Method[] methods = ReflectionUtil.getDeclaredMethods(cls);
-            for (Method m : methods) {
-                if (isMethodAccepted(m, accessType)) {
-                    XmlJavaTypeAdapter xjta = Utils.getMethodXJTA(m);
-                    if (xjta != null) {
-                        Type t = Utils.getTypeFromXmlAdapter(xjta);
-                        if (t != null) {
-                            addType(t);
-                            continue;
-                        }
-                    }
-                    addType(m.getGenericReturnType());
-                    for (Type t : m.getGenericParameterTypes()) {
-                        addType(t);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Checks if the field is accepted as a JAXB property.
-     */
-    static boolean isFieldAccepted(Field field, XmlAccessType accessType) {
-        // We only accept non static fields which are not marked @XmlTransient or has transient modifier
-        if (field.isAnnotationPresent(XmlTransient.class)
-            || Modifier.isTransient(field.getModifiers())) {
-            return false;
-        }
-        if (Modifier.isStatic(field.getModifiers())) {
-            return field.isAnnotationPresent(XmlAttribute.class);
-        }
-        if (accessType == XmlAccessType.PUBLIC_MEMBER
-            && !Modifier.isPublic(field.getModifiers())) {
-            return false;
-        }
-        if (accessType == XmlAccessType.NONE
-            || accessType == XmlAccessType.PROPERTY) {
-            return checkJaxbAnnotation(field.getAnnotations());
-        }
-        return true;
-    }
-
-    /**
-     * Checks if the method is accepted as a JAXB property getter.
-     */
-    static boolean isMethodAccepted(Method method, XmlAccessType accessType) {
-        // We only accept non static property getters which are not marked @XmlTransient
-        if (Modifier.isStatic(method.getModifiers())
-                || method.isAnnotationPresent(XmlTransient.class)
-                || !Modifier.isPublic(method.getModifiers())
-                || "getClass".equals(method.getName())) {
-            return false;
-        }
-
-        // must not have parameters and return type must not be void
-        if (method.getReturnType() == Void.class || method.getReturnType() == Void.TYPE
-            || method.getParameterTypes().length != 0
-            || (method.getDeclaringClass().equals(Throwable.class)
-            && !("getMessage".equals(method.getName())))
-            || !(method.getName().startsWith("get")
-                    || method.getName().startsWith("is"))) {
-            return false;
-        }
-        int beginIndex = 3;
-        if (method.getName().startsWith("is")) {
-            beginIndex = 2;
-        }
-
-        Method setter = null;
-        try {
-            setter = method.getDeclaringClass()
-                .getMethod("set" + method.getName().substring(beginIndex),
-                           new Class[] {method.getReturnType()});
-        } catch (Exception e) {
-            //getter, but no setter
-        }
-        if (setter != null) {
-            if (setter.isAnnotationPresent(XmlTransient.class)
-                || !Modifier.isPublic(setter.getModifiers())) {
-                return false;
-            }
-        } else if (!Collection.class.isAssignableFrom(method.getReturnType())
-            && !Throwable.class.isAssignableFrom(method.getDeclaringClass())) {
-            //no setter, it's not a collection (thus getter().add(...)), and
-            //not an Exception,
-            return false;
-        }
-
-        if (accessType == XmlAccessType.NONE
-            || accessType == XmlAccessType.FIELD) {
-            return checkJaxbAnnotation(method.getAnnotations());
-        }
-        return true;
-    }
-
-    /**
-     * Checks if there are JAXB annotations among the annotations of the class member.
-     * @param annotations the array of annotations from the class member
-     * @return true if JAXB annotations are present, false otherwise
-     */
-    static boolean checkJaxbAnnotation(Annotation[] annotations) {
-        // must check if there are any jaxb annotations
-        Package jaxbAnnotationsPackage = XmlElement.class.getPackage();
-        for (Annotation annotation : annotations) {
-            if (annotation.annotationType().getPackage() == jaxbAnnotationsPackage) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * The TypeReference class is a sun specific class that is found in two different
-     * locations depending on environment. In IBM JDK the class is not available at all.
-     * So we have to load it at runtime.
-     *
-     * @param n
-     * @param cls
-     * @return initiated TypeReference
-     */
-    private static Object createTypeReference(QName n, Class<?> cls) {
-        Class<?> refClass = null;
-        try {
-            refClass = ClassLoaderUtils.loadClass("com.sun.xml.bind.api.TypeReference",
-                                                  JAXBContextInitializer.class);
-        } catch (Throwable ex) {
-            try {
-                refClass = ClassLoaderUtils.loadClass("com.sun.xml.internal.bind.api.TypeReference",
-                                                      JAXBContextInitializer.class);
-            } catch (Throwable ex2) {
-                //ignore
-            }
-        }
-        if (refClass != null) {
-            try {
-                return refClass.getConstructor(QName.class, Type.class, new Annotation[0].getClass()) //NOPMD
-                    .newInstance(n, cls, new Annotation[0]);
-            } catch (Throwable e) {
-                //ignore
-            }
-        }
-        return null;
-    }
-
-    @SuppressWarnings("unused")
-    private Object createFactory(Class<?> cls, Constructor<?> contructor) {
-        String newClassName = cls.getName() + "Factory";
-        ASMHelper helper = new ASMHelper();
-        ClassWriter cw = helper.createClassWriter();
-        MethodVisitor mv;
-
-        cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
-                 ASMHelper.periodToSlashes(newClassName), null, "java/lang/Object", null);
-
-        cw.visitSource(cls.getSimpleName() + "Factory" + ".java", null);
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
-        mv.visitCode();
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
-        mv.visitInsn(Opcodes.RETURN);
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "create" + cls.getSimpleName(),
-                            "()L" + ASMHelper.periodToSlashes(cls.getName()) + ";", null, null);
-        mv.visitCode();
-        String name = cls.getName().replace(".", "/");
-        mv.visitTypeInsn(Opcodes.NEW, name);
-        mv.visitInsn(Opcodes.DUP);
-        StringBuilder paraString = new StringBuilder(32).append("(");
-
-        for (Class<?> paraClass : contructor.getParameterTypes()) {
-            mv.visitInsn(Opcodes.ACONST_NULL);
-            paraString.append("Ljava/lang/Object;");
-        }
-        paraString.append(")V");
-
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, name, "<init>", paraString.toString(), false);
-
-        mv.visitInsn(Opcodes.ARETURN);
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
-
-        cw.visitEnd();
-        Class<?> factoryClass = helper.loadClass(newClassName, cls, cw.toByteArray());
-        try {
-            return factoryClass.newInstance();
-        } catch (Exception e) {
-           //ignore
-        }
-        return null;
-    }
-
-
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/apache/openjpa/enhance/PCClassFileTransformer.java b/jakarta/src/patch/java/org/apache/openjpa/enhance/PCClassFileTransformer.java
deleted file mode 100644
index ee2cdac..0000000
--- a/jakarta/src/patch/java/org/apache/openjpa/enhance/PCClassFileTransformer.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * 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.openjpa.enhance;
-
-import java.io.ByteArrayInputStream;
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.IllegalClassFormatException;
-import java.security.AccessController;
-import java.security.ProtectionDomain;
-import java.util.Set;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.Options;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.util.GeneralException;
-
-import serp.bytecode.BCClass;
-import serp.bytecode.Project;
-import serp.bytecode.lowlevel.ConstantPoolTable;
-
-
-/**
- * Transformer that makes persistent classes implement the
- * {@link PersistenceCapable} interface at runtime.
- *
- * @author Abe White
- */
-public class PCClassFileTransformer
-    implements ClassFileTransformer {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (PCClassFileTransformer.class);
-
-    private final MetaDataRepository _repos;
-    private final PCEnhancer.Flags _flags;
-    private final ClassLoader _tmpLoader;
-    private final Log _log;
-    private final Set _names;
-    private boolean _transforming = false;
-
-    /**
-     * Constructor.
-     *
-     * @param repos metadata repository to use internally
-     * @param opts enhancer configuration options
-     * @param loader temporary class loader for loading intermediate classes
-     */
-    public PCClassFileTransformer(MetaDataRepository repos, Options opts,
-        ClassLoader loader) {
-        this(repos, toFlags(opts), loader, opts.removeBooleanProperty
-            ("scanDevPath", "ScanDevPath", false));
-    }
-
-    /**
-     * Create enhancer flags from the given options.
-     */
-    private static PCEnhancer.Flags toFlags(Options opts) {
-        PCEnhancer.Flags flags = new PCEnhancer.Flags();
-        flags.addDefaultConstructor = opts.removeBooleanProperty
-            ("addDefaultConstructor", "AddDefaultConstructor",
-                flags.addDefaultConstructor);
-        flags.enforcePropertyRestrictions = opts.removeBooleanProperty
-            ("enforcePropertyRestrictions", "EnforcePropertyRestrictions",
-                flags.enforcePropertyRestrictions);
-        return flags;
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param repos metadata repository to use internally
-     * @param flags enhancer configuration
-     * @param tmpLoader temporary class loader for loading intermediate classes
-     * @param devscan whether to scan the dev classpath for persistent types
-     * if none are configured
-     */
-    public PCClassFileTransformer(MetaDataRepository repos,
-        PCEnhancer.Flags flags, ClassLoader tmpLoader, boolean devscan) {
-        _repos = repos;
-        _tmpLoader = tmpLoader;
-
-        _log = repos.getConfiguration().
-            getLog(OpenJPAConfiguration.LOG_ENHANCE);
-        _flags = flags;
-
-        _names = repos.getPersistentTypeNames(devscan, tmpLoader);
-        if (_names == null && _log.isInfoEnabled())
-            _log.info(_loc.get("runtime-enhance-pcclasses"));
-    }
-
-    @Override
-    public byte[] transform(ClassLoader loader, String className,
-        Class redef, ProtectionDomain domain, byte[] bytes)
-        throws IllegalClassFormatException {
-        if (loader == _tmpLoader)
-            return null;
-
-        // JDK bug -- OPENJPA-1676
-        if (className == null) {
-            return null;
-        }
-        // prevent re-entrant calls, which can occur if the enhancing
-        // loader is used to also load OpenJPA libraries; this is to prevent
-        // recursive enhancement attempts for internal openjpa libraries
-        if (_transforming)
-            return null;
-
-        _transforming = true;
-
-        return transform0(className, redef, bytes);
-    }
-
-    /**
-     * We have to split the transform method into two methods to avoid
-     * ClassCircularityError when executing method using pure-JIT JVMs
-     * such as JRockit.
-     */
-    private byte[] transform0(String className, Class redef, byte[] bytes)
-        throws IllegalClassFormatException {
-
-        byte[] returnBytes = null;
-        try {
-            Boolean enhance = needsEnhance(className, redef, bytes);
-            if (enhance != null && _log.isTraceEnabled())
-                _log.trace(_loc.get("needs-runtime-enhance", className,
-                    enhance));
-            if (enhance != Boolean.TRUE)
-                return null;
-
-            ClassLoader oldLoader = AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction());
-            AccessController.doPrivileged(J2DoPrivHelper.setContextClassLoaderAction(_tmpLoader));
-            try {
-                PCEnhancer enhancer = new PCEnhancer(_repos.getConfiguration(),
-                        new Project().loadClass(new ByteArrayInputStream(bytes),
-                                _tmpLoader), _repos);
-                enhancer.setAddDefaultConstructor(_flags.addDefaultConstructor);
-                enhancer.setEnforcePropertyRestrictions
-                        (_flags.enforcePropertyRestrictions);
-
-                if (enhancer.run() == PCEnhancer.ENHANCE_NONE)
-                    return null;
-                BCClass pcb = enhancer.getPCBytecode();
-                returnBytes = AsmAdaptor.toByteArray(pcb, pcb.toByteArray());
-                return returnBytes;
-            } finally {
-                AccessController.doPrivileged(J2DoPrivHelper.setContextClassLoaderAction(oldLoader));
-            }
-        } catch (Throwable t) {
-            _log.warn(_loc.get("cft-exception-thrown", className), t);
-            if (t instanceof RuntimeException)
-                throw (RuntimeException) t;
-            if (t instanceof IllegalClassFormatException)
-                throw (IllegalClassFormatException) t;
-            throw new GeneralException(t);
-        } finally {
-            _transforming = false;
-            if (returnBytes != null && _log.isTraceEnabled())
-                _log.trace(_loc.get("runtime-enhance-complete", className,
-                    bytes.length, returnBytes.length));
-        }
-    }
-
-    /**
-     * Return whether the given class needs enhancement.
-     */
-    private Boolean needsEnhance(String clsName, Class redef, byte[] bytes) {
-        if (redef != null) {
-            Class[] intfs = redef.getInterfaces();
-            for (int i = 0; i < intfs.length; i++)
-                if (PersistenceCapable.class.getName().
-                    equals(intfs[i].getName()))
-                    return Boolean.valueOf(!isEnhanced(bytes));
-            return null;
-        }
-
-        if (_names != null) {
-            if (_names.contains(clsName.replace('/', '.')))
-                return Boolean.valueOf(!isEnhanced(bytes));
-            return null;
-        }
-
-        if (clsName.startsWith("java/") || clsName.startsWith("javax/") || clsName.startsWith("jakarta/"))
-            return null;
-        if (isEnhanced(bytes))
-            return Boolean.FALSE;
-
-        try {
-            Class c = Class.forName(clsName.replace('/', '.'), false,
-                _tmpLoader);
-            if (_repos.getMetaData(c, null, false) != null)
-                return Boolean.TRUE;
-            return null;
-        } catch (ClassNotFoundException cnfe) {
-            // cannot load the class: this might mean that it is a proxy
-            // or otherwise inaccessible class which can't be an entity
-            return Boolean.FALSE;
-        } catch (LinkageError cce) {
-            // this can happen if we are loading classes that this
-            // class depends on; these will never be enhanced anyway
-            return Boolean.FALSE;
-        } catch (RuntimeException re) {
-            throw re;
-        } catch (Throwable t) {
-            throw new GeneralException(t);
-        }
-    }
-
-    /**
-     * Analyze the bytecode to see if the given class definition implements
-     * {@link PersistenceCapable}.
-     */
-    private static boolean isEnhanced(byte[] b) {
-        if (AsmAdaptor.use())
-        {
-            return AsmAdaptor.isEnhanced(b);
-        }
-
-        ConstantPoolTable table = new ConstantPoolTable(b);
-        int idx = table.getEndIndex();
-
-        idx += 6; // skip access, cls, super
-        int ifaces = table.readUnsignedShort(idx);
-        int clsEntry, utfEntry;
-        String name;
-        for (int i = 0; i < ifaces; i++) {
-            idx += 2;
-            clsEntry = table.readUnsignedShort(idx);
-            utfEntry = table.readUnsignedShort(table.get(clsEntry));
-            name = table.readString(table.get(utfEntry));
-            if ("org/apache/openjpa/enhance/PersistenceCapable".equals(name))
-                return true;
-        }
-        return false;
-    }
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/apache/openjpa/lib/meta/ClassMetaDataIterator.java b/jakarta/src/patch/java/org/apache/openjpa/lib/meta/ClassMetaDataIterator.java
deleted file mode 100644
index b972512..0000000
--- a/jakarta/src/patch/java/org/apache/openjpa/lib/meta/ClassMetaDataIterator.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.openjpa.lib.meta;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-import org.apache.openjpa.lib.util.ClassUtil;
-import org.apache.openjpa.lib.util.J2DoPrivHelper;
-import org.apache.openjpa.lib.util.MultiClassLoader;
-
-/**
- * Iterator over all metadata resources that might contain the
- * metadata for a given class, starting with the most general. Assumes that
- * package-level resources are named "package.&lt;suffix&gt;".
- *
- * @author Abe White
- */
-public class ClassMetaDataIterator implements MetaDataIterator {
-
-    private final ClassLoader _loader;
-    private final List<String> _locs;
-    private int _loc = -1;
-    private final List<URL> _urls = new ArrayList<>(3);
-    private int _url = -1;
-
-    /**
-     * Constructor; supply the class whose metadata to find, the suffix
-     * of metadata files, and whether to parse top-down or bottom-up.
-     */
-    public ClassMetaDataIterator(Class<?> cls, String suffix, boolean topDown) {
-        this(cls, suffix, null, topDown);
-    }
-
-    /**
-     * Constructor; supply the class whose metadata to find, the suffix
-     * of metadata files, and whether to parse top-down or bottom-up.
-     */
-    public ClassMetaDataIterator(Class<?> cls, String suffix,
-            ClassLoader loader, boolean topDown) {
-        // skip classes that can't have metadata
-        if (cls != null && (cls.isPrimitive()
-            || cls.getName().startsWith("java.")
-            || cls.getName().startsWith("javax.")
-            || cls.getName().startsWith("jakarta."))) {
-            _loader = null;
-            _locs = Collections.emptyList();
-            return;
-        }
-
-        if (loader == null) {
-            MultiClassLoader multi = AccessController
-                .doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction());
-            multi.addClassLoader(MultiClassLoader.SYSTEM_LOADER);
-            multi.addClassLoader(MultiClassLoader.THREAD_LOADER);
-            multi.addClassLoader(getClass().getClassLoader());
-            if (cls != null)
-            {
-                ClassLoader clsLoader = (ClassLoader)
-                    AccessController.doPrivileged(
-                        J2DoPrivHelper.getClassLoaderAction(cls));
-                if (clsLoader != null)
-                    multi.addClassLoader(clsLoader);
-            }
-            loader = multi;
-        }
-        _loader = loader;
-
-        // collect the set of all possible metadata locations; start with
-        // system locations
-        _locs = new ArrayList<>();
-        _locs.add("META-INF/package" + suffix);
-        _locs.add("WEB-INF/package" + suffix);
-        _locs.add("package" + suffix);
-
-        // put this legacy location at the end regardless of whether we're
-        // going top down or bottom up so we don't have to parse it as often
-        // during testing
-        if (!topDown)
-            _locs.add("system" + suffix);
-
-        if (cls != null) {
-            // also check:
-            // 1. for each package from the top down to cls' package:
-            // <path>/package<suffix>
-            // <path>/<package-name><suffix> (legacy support)
-            // <path>/../<package-name><suffix> (legacy support)
-            // 2. <path>/<class-name><suffix>
-            String pkg = ClassUtil.getPackageName(cls).replace('.', '/');
-            if (pkg.length() > 0) {
-                int idx, start = 0;
-                String pkgName, path, upPath = "";
-                do {
-                    idx = pkg.indexOf('/', start);
-                    if (idx == -1) {
-                        pkgName = (start == 0) ? pkg : pkg.substring(start);
-                        path = pkg + "/";
-                    } else {
-                        pkgName = pkg.substring(start, idx);
-                        path = pkg.substring(0, idx + 1);
-                    }
-
-                    _locs.add(path + "package" + suffix);
-                    _locs.add(path + pkgName + suffix); // legacy
-                    _locs.add(upPath + pkgName + suffix); // legacy
-                    if (idx == -1)
-                        _locs.add(path + ClassUtil.getClassName(cls) + suffix);
-
-                    start = idx + 1;
-                    upPath = path;
-                }
-                while (idx != -1);
-            } else {
-                // <class-name><suffix> for top-level classes
-                _locs.add(cls.getName() + suffix);
-            }
-        }
-        if (topDown)
-            _locs.add("system" + suffix); // legacy
-        else
-            Collections.reverse(_locs);
-    }
-
-    @Override
-    public boolean hasNext() throws IOException {
-        Enumeration<URL> e;
-        while (_url + 1 >= _urls.size()) {
-            if (++_loc >= _locs.size())
-                return false;
-
-            _url = -1;
-            _urls.clear();
-            try {
-                e = AccessController.doPrivileged(
-                    J2DoPrivHelper.getResourcesAction(
-                        _loader, _locs.get(_loc)));
-            } catch (PrivilegedActionException pae) {
-                throw (IOException) pae.getException();
-            }
-            while (e.hasMoreElements())
-                _urls.add(e.nextElement());
-        }
-        return true;
-    }
-
-    @Override
-    public URL next() throws IOException {
-        if (!hasNext())
-            throw new NoSuchElementException();
-        return _urls.get(++_url);
-    }
-
-    @Override
-    public InputStream getInputStream() throws IOException {
-        if (_url == -1 || _url >= _urls.size())
-            throw new IllegalStateException();
-        try {
-            return AccessController.doPrivileged(
-                J2DoPrivHelper.openStreamAction(_urls.get(_url)));
-        } catch (PrivilegedActionException pae) {
-            throw (IOException) pae.getException();
-        }
-    }
-
-    @Override
-    public File getFile() throws IOException {
-        if (_url == -1 || _url >= _urls.size())
-            throw new IllegalStateException();
-        File file = new File(URLDecoder.decode((_urls.get(_url)).getFile()));
-        return ((AccessController.doPrivileged(
-            J2DoPrivHelper.existsAction(file))).booleanValue()) ? file:null;
-    }
-
-    @Override
-    public void close() {
-    }
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/apache/openjpa/lib/util/TemporaryClassLoader.java b/jakarta/src/patch/java/org/apache/openjpa/lib/util/TemporaryClassLoader.java
deleted file mode 100644
index dc5a93c..0000000
--- a/jakarta/src/patch/java/org/apache/openjpa/lib/util/TemporaryClassLoader.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.openjpa.lib.util;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import serp.bytecode.lowlevel.ConstantPoolTable;
-
-/**
- * ClassLoader implementation that allows classes to be temporarily
- * loaded and then thrown away. Useful for the enhancer to be able
- * to run against a class without first loading(and thus polluting)
- * the parent ClassLoader.
- *
- * @author Marc Prud'hommeaux
- */
-public class TemporaryClassLoader extends ClassLoader {
-
-    public TemporaryClassLoader(ClassLoader parent) {
-        super(parent);
-    }
-
-    @Override
-    public Class loadClass(String name) throws ClassNotFoundException {
-        return loadClass(name, false);
-    }
-
-    @Override
-    protected Class loadClass(String name, boolean resolve)
-        throws ClassNotFoundException {
-        // see if we've already loaded it
-        Class c = findLoadedClass(name);
-        if (c != null)
-            return c;
-
-        // bug #283. defer to system if the name is a protected name.
-        // "sun." is required for JDK 1.4, which has an access check for
-        // sun.reflect.GeneratedSerializationConstructorAccessor1
-        if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("jakarta.")
-            || name.startsWith("sun.") || name.startsWith("jdk.")) {
-            return Class.forName(name, resolve, getClass().getClassLoader());
-        }
-
-        String resourceName = name.replace('.', '/') + ".class";
-        InputStream resource = getResourceAsStream(resourceName);
-        if (resource == null) {
-            throw new ClassNotFoundException(name);
-        }
-
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        byte[] b = new byte[1024];
-        try {
-            for (int n = 0; (n = resource.read(b, 0, b.length)) != -1;
-                bout.write(b, 0, n))
-                ;
-            byte[] classBytes = bout.toByteArray();
-            // To avoid classloader issues with the JVM (Sun and IBM), we
-            // will not load Enums via the TemporaryClassLoader either.
-            // Reference JIRA Issue OPENJPA-646 for more information.
-            if (isAnnotation(classBytes) || isEnum(classBytes)) {
-                try {
-                    Class<?> frameworkClass = Class.forName(name, resolve,
-                            getClass().getClassLoader());
-                    return frameworkClass;
-                } catch (ClassNotFoundException e) {
-                    // OPENJPA-1121 continue, as it must be a user-defined class
-                }
-            }
-
-            try {
-                return defineClass(name, classBytes, 0, classBytes.length);
-            } catch (SecurityException e) {
-                // possible prohibited package: defer to the parent
-                return super.loadClass(name, resolve);
-            }
-        } catch (IOException ioe) {
-            // defer to the parent
-            return super.loadClass(name, resolve);
-        }
-    }
-
-    /**
-     * Fast-parse the given class bytecode to determine if it is an
-     * annotation class.
-     */
-    private static boolean isAnnotation(byte[] b) {
-        if (JavaVersions.VERSION < 5)
-            return false;
-        int idx = ConstantPoolTable.getEndIndex(b);
-        int access = ConstantPoolTable.readUnsignedShort(b, idx);
-        return (access & 0x2000) != 0; // access constant for annotation type
-    }
-
-    /**
-     * Fast-parse the given class bytecode to determine if it is an
-     * enum class.
-     */
-    private static boolean isEnum(byte[] b) {
-        if (JavaVersions.VERSION < 5)
-            return false;
-        int idx = ConstantPoolTable.getEndIndex(b);
-        int access = ConstantPoolTable.readUnsignedShort(b, idx);
-        return (access & 0x4000) != 0; // access constant for enum type
-    }
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java b/jakarta/src/patch/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java
deleted file mode 100644
index 03cd4fc..0000000
--- a/jakarta/src/patch/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * 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.openjpa.meta;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.security.PrivilegedActionException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.openjpa.enhance.PCRegistry;
-import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.util.OpenJPAException;
-import org.apache.openjpa.util.UserException;
-
-/**
- * Abstract implementation provides a set of generic utilities for detecting
- * persistence meta-data of Field/Member. Also provides bean-style properties
- * such as access style or identity type to be used by default when such
- * information is not derivable from available meta-data.
- *
- * @author Abe White
- * @author Pinaki Poddar
- */
-public abstract class AbstractMetaDataDefaults
-    implements MetaDataDefaults {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (AbstractMetaDataDefaults.class);
-
-    private int _access = AccessCode.FIELD;
-    private int _identity = ClassMetaData.ID_UNKNOWN;
-    private boolean _ignore = true;
-    private boolean _interface = true;
-    private boolean _pcRegistry = true;
-    private int _callback = CALLBACK_RETHROW;
-    private boolean _unwrapped = false;
-
-    /**
-     * Whether to attempt to use the information from registered classes
-     * to populate metadata defaults. Defaults to true.
-     */
-    public boolean getUsePCRegistry() {
-        return _pcRegistry;
-    }
-
-    /**
-     * Whether to attempt to use the information from registered classes
-     * to populate metadata defaults. Defaults to true.
-     */
-    public void setUsePCRegistry(boolean pcRegistry) {
-        _pcRegistry = pcRegistry;
-    }
-
-    /**
-     * The default access type for base classes with ACCESS_UNKNOWN.
-     * ACCESS_FIELD by default.
-     */
-    @Override
-    public int getDefaultAccessType() {
-        return _access;
-    }
-
-    /**
-     * The default access type for base classes with ACCESS_UNKNOWN.
-     * ACCESS_FIELD by default.
-     */
-    public void setDefaultAccessType(int access) {
-        _access = access;
-    }
-
-    /**
-     * The default identity type for unmapped classes without primary
-     * key fields. ID_UNKNOWN by default.
-     */
-    @Override
-    public int getDefaultIdentityType() {
-        return _identity;
-    }
-
-    /**
-     * The default identity type for unmapped classes without primary
-     * key fields. ID_UNKNOWN by default.
-     */
-    public void setDefaultIdentityType(int identity) {
-        _identity = identity;
-    }
-
-    @Override
-    public int getCallbackMode() {
-        return _callback;
-    }
-
-    public void setCallbackMode(int mode) {
-        _callback = mode;
-    }
-
-    public void setCallbackMode(int mode, boolean on) {
-        if (on)
-            _callback |= mode;
-        else
-            _callback &= ~mode;
-    }
-
-    @Override
-    public boolean getCallbacksBeforeListeners(int type) {
-        return false;
-    }
-
-    @Override
-    public boolean isDeclaredInterfacePersistent() {
-        return _interface;
-    }
-
-    public void setDeclaredInterfacePersistent(boolean pers) {
-        _interface = pers;
-    }
-
-    @Override
-    public boolean isDataStoreObjectIdFieldUnwrapped() {
-        return _unwrapped;
-    }
-
-    public void setDataStoreObjectIdFieldUnwrapped(boolean unwrapped) {
-        _unwrapped = unwrapped;
-    }
-
-    public boolean getIgnoreNonPersistent() {
-        return _ignore;
-    }
-
-    @Override
-    public void setIgnoreNonPersistent(boolean ignore) {
-        _ignore = ignore;
-    }
-
-    @Override
-    public void populate(ClassMetaData meta, int access) {
-        populate(meta, access, false);
-    }
-
-    @Override
-    public void populate(ClassMetaData meta, int access, boolean ignoreTransient) {
-        if (meta.getDescribedType() == Object.class)
-            return;
-        meta.setAccessType(access);
-
-        Log log = meta.getRepository().getLog();
-        if (log.isTraceEnabled())
-            log.trace(_loc.get("gen-meta", meta));
-        if (!_pcRegistry || !populateFromPCRegistry(meta)) {
-            if (log.isTraceEnabled())
-                log.trace(_loc.get("meta-reflect"));
-            populateFromReflection(meta, ignoreTransient);
-        }
-    }
-
-    /**
-     * Populate the given metadata using the {@link PCRegistry}.
-     */
-    private boolean populateFromPCRegistry(ClassMetaData meta) {
-        Class<?> cls = meta.getDescribedType();
-        if (!PCRegistry.isRegistered(cls))
-            return false;
-        try {
-            String[] fieldNames = PCRegistry.getFieldNames(cls);
-            Class<?>[] fieldTypes = PCRegistry.getFieldTypes(cls);
-            Member member;
-            FieldMetaData fmd;
-            for (int i = 0; i < fieldNames.length; i ++) {
-            	String property = fieldNames[i];
-                member = getMemberByProperty(meta, property,
-                	AccessCode.UNKNOWN, true);
-                if (member == null) // transient or indeterminable access
-                	continue;
-                fmd = meta.addDeclaredField(property, fieldTypes[i]);
-                fmd.backingMember(member);
-                populate(fmd);
-            }
-            return true;
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (Exception e) {
-            if (e instanceof PrivilegedActionException)
-                e = ((PrivilegedActionException) e).getException();
-            throw new UserException(e);
-        }
-    }
-
-    protected abstract List<Member> getPersistentMembers(ClassMetaData meta, boolean ignoreTransient);
-    /**
-     * Generate the given meta-data using reflection.
-     * Adds FieldMetaData for each persistent state.
-     * Delegate to concrete implementation to determine the persistent
-     * members.
-     */
-    private void populateFromReflection(ClassMetaData meta, boolean ignoreTransient) {
-        List<Member> members = getPersistentMembers(meta, ignoreTransient);
-        boolean iface = meta.getDescribedType().isInterface();
-        // If access is mixed or if the default is currently unknown,
-        // process all fields, otherwise only process members of the class
-        // level default access type.
-
-        String name;
-        boolean def;
-        FieldMetaData fmd;
-        for (int i = 0; i < members.size(); i++) {
-            Member member = members.get(i);
-            name = getFieldName(member);
-            if (name == null || isReservedFieldName(name))
-                continue;
-
-            def = isDefaultPersistent(meta, member, name, ignoreTransient);
-            if (!def && _ignore)
-                continue;
-
-            // passed the tests; persistent type -- we construct with
-            // Object.class because setting backing member will set proper
-            // type anyway
-            fmd = meta.addDeclaredField(name, Object.class);
-            fmd.backingMember(member);
-            if (!def) {
-                fmd.setExplicit(true);
-                fmd.setManagement(FieldMetaData.MANAGE_NONE);
-            }
-            populate(fmd);
-        }
-    }
-
-    protected void populate(FieldMetaData fmd) {
-
-    }
-
-    /**
-     * Return the list of fields in <code>meta</code> that use field access,
-     * or <code>null</code> if a list of fields is unobtainable. An empty list
-     * should be returned if the list of fields is obtainable, but there
-     * happens to be no field access in <code>meta</code>.
-     *
-     * This is used for error reporting purposes only, so need not be efficient.
-     *
-     * This implementation returns <code>null</code>.
-     */
-    protected List<String> getFieldAccessNames(ClassMetaData meta) {
-        return null;
-    }
-
-    /**
-     * Return the list of methods in <code>meta</code> that use property access,
-     * or <code>null</code> if a list of methods is unobtainable. An empty list
-     * should be returned if the list of methods is obtainable, but there
-     * happens to be no property access in <code>meta</code>.
-     *
-     * This is used for error reporting purposes only, so need not be efficient.
-     *
-     * This implementation returns <code>null</code>.
-     */
-    protected List<String> getPropertyAccessNames(ClassMetaData meta) {
-        return null;
-    }
-
-    /**
-     * Return the field name for the given member. This will only be invoked
-     * on members of the right type (field vs. method). Return null if the
-     * member cannot be managed. Default behavior: For fields, returns the
-     * field name. For getter methods, returns the minus "get" or "is" with
-     * the next letter lower-cased. For other methods, returns null.
-     */
-    public static String getFieldName(Member member) {
-        if (member instanceof Field)
-            return member.getName();
-        if (member instanceof Method == false)
-        	return null;
-        Method method = (Method) member;
-        String name = method.getName();
-        if (isNormalGetter(method))
-        	name = name.substring("get".length());
-        else if (isBooleanGetter(method))
-        	name = name.substring("is".length());
-        else
-            return null;
-
-        if (name.length() == 1)
-            return name.toLowerCase();
-        return Character.toLowerCase(name.charAt(0)) + name.substring(1);
-    }
-
-    /**
-     * Returns true if the given field name is reserved for unmanaged fields.
-     */
-    protected boolean isReservedFieldName(String name) {
-        // names used by enhancers
-        return name.startsWith("openjpa") || name.startsWith("jdo");
-    }
-
-    /**
-     * Return true if the given member is persistent by default. This will
-     * only be invoked on members of the right type (field vs. method).
-     * Returns false if member is static or final by default.
-     *
-     * @param name the field name from {@link #getFieldName}
-     */
-    protected abstract boolean isDefaultPersistent(ClassMetaData meta,
-        Member member, String name, boolean ignoreTransient);
-
-    /**
-     * Gets the backing member of the given field. If the field has not been
-     * assigned a backing member then get either the instance field or the
-     * getter method depending upon the access style of the defining class.
-     * <br>
-     * Defining class is used instead of declaring class because this method
-     * may be invoked during parsing phase when declaring metadata may not be
-     * available.
-     */
-    @Override
-    public Member getBackingMember(FieldMetaData fmd) {
-        if (fmd == null)
-            return null;
-        if (fmd.getBackingMember() != null)
-        	return fmd.getBackingMember();
-        return getMemberByProperty(fmd.getDeclaringMetaData(), fmd.getName(),
-            fmd.getAccessType(), true);
-    }
-
-    @Override
-    public Class<?> getUnimplementedExceptionType() {
-        return UnsupportedOperationException.class;
-    }
-
-    /**
-     * Helper method; returns true if the given class appears to be
-     * user-defined.
-     */
-    protected static boolean isUserDefined(Class<?> cls) {
-        return cls != null && !cls.getName().startsWith("java.")
-            && !cls.getName().startsWith ("javax.")
-            && !cls.getName().startsWith ("jakarta.");
-	}
-
-    /**
-     * Affirms if the given method matches the following signature
-     * <code> public T getXXX() </code>
-     * where T is any non-void type.
-     */
-    public static boolean isNormalGetter(Method method) {
-    	String methodName = method.getName();
-    	return startsWith(methodName, "get")
-    	    && method.getParameterTypes().length == 0
-    	    && method.getReturnType() != void.class;
-    }
-
-    /**
-     * Affirms if the given method matches the following signature
-     * <code> public boolean isXXX() </code>
-     * <code> public Boolean isXXX() </code>
-     */
-    public static boolean isBooleanGetter(Method method) {
-    	String methodName = method.getName();
-    	return startsWith(methodName, "is")
-    	    && method.getParameterTypes().length == 0
-    	    && isBoolean(method.getReturnType());
-    }
-
-    /**
-     * Affirms if the given method signature matches bean-style getter method
-     * signature.<br>
-     * <code> public T getXXX()</code> where T is any non-void type.<br>
-     * or<br>
-     * <code> public T isXXX()</code> where T is boolean or Boolean.<br>
-     */
-    public static boolean isGetter(Method method, boolean includePrivate) {
-    	if (method == null)
-    		return false;
-    	int mods = method.getModifiers();
-    	if (!(Modifier.isPublic(mods)
-    	      || Modifier.isProtected(mods)
-    	      || (Modifier.isPrivate(mods) && includePrivate))
-    	 || Modifier.isNative(mods)
-    	 || Modifier.isStatic(mods))
-    		return false;
-    	return isNormalGetter(method) || isBooleanGetter(method);
-    }
-
-    /**
-     * Affirms if the given full string starts with the given head.
-     */
-    public static boolean startsWith(String full, String head) {
-        return full != null && head != null && full.startsWith(head)
-            && full.length() > head.length();
-    }
-
-    public static boolean isBoolean(Class<?> cls) {
-    	return cls == boolean.class || cls == Boolean.class;
-    }
-
-    public static List<String> toNames(List<? extends Member> members) {
-    	List<String> result = new ArrayList<>();
-    	for (Member m : members)
-    		result.add(m.getName());
-    	return result;
-    }
-
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsIntrospectionSource.java b/jakarta/src/patch/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsIntrospectionSource.java
deleted file mode 100644
index 0c59207..0000000
--- a/jakarta/src/patch/java/org/apache/tomcat/util/modeler/modules/MbeansDescriptorsIntrospectionSource.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * 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.tomcat.util.modeler.modules;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map.Entry;
-
-import javax.management.ObjectName;
-
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
-import org.apache.tomcat.util.modeler.AttributeInfo;
-import org.apache.tomcat.util.modeler.ManagedBean;
-import org.apache.tomcat.util.modeler.OperationInfo;
-import org.apache.tomcat.util.modeler.ParameterInfo;
-import org.apache.tomcat.util.modeler.Registry;
-
-public class MbeansDescriptorsIntrospectionSource extends ModelerSource
-{
-    private static final Log log = LogFactory.getLog(MbeansDescriptorsIntrospectionSource.class);
-
-    private Registry registry;
-    private String type;
-    private final List<ObjectName> mbeans = new ArrayList<>();
-
-    public void setRegistry(Registry reg) {
-        this.registry=reg;
-    }
-
-    /**
-     * Used if a single component is loaded
-     *
-     * @param type The type
-     */
-    public void setType( String type ) {
-       this.type=type;
-    }
-
-    public void setSource( Object source ) {
-        this.source=source;
-    }
-
-    @Override
-    public List<ObjectName> loadDescriptors(Registry registry, String type,
-            Object source) throws Exception {
-        setRegistry(registry);
-        setType(type);
-        setSource(source);
-        execute();
-        return mbeans;
-    }
-
-    public void execute() throws Exception {
-        if( registry==null ) registry=Registry.getRegistry(null, null);
-        try {
-            ManagedBean managed = createManagedBean(registry, null,
-                    (Class<?>)source, type);
-            if( managed==null ) return;
-            managed.setName( type );
-
-            registry.addManagedBean(managed);
-
-        } catch( Exception ex ) {
-            log.error(sm.getString("modules.readDescriptorsError"), ex);
-        }
-    }
-
-
-
-    // ------------ Implementation for non-declared introspection classes
-
-    private static final Hashtable<String,String> specialMethods = new Hashtable<>();
-    static {
-        specialMethods.put( "preDeregister", "");
-        specialMethods.put( "postDeregister", "");
-    }
-
-    private static final Class<?>[] supportedTypes  = new Class[] {
-        Boolean.class,
-        Boolean.TYPE,
-        Byte.class,
-        Byte.TYPE,
-        Character.class,
-        Character.TYPE,
-        Short.class,
-        Short.TYPE,
-        Integer.class,
-        Integer.TYPE,
-        Long.class,
-        Long.TYPE,
-        Float.class,
-        Float.TYPE,
-        Double.class,
-        Double.TYPE,
-        String.class,
-        String[].class,
-        BigDecimal.class,
-        BigInteger.class,
-        ObjectName.class,
-        Object[].class,
-        java.io.File.class,
-    };
-
-    /**
-     * Check if this class is one of the supported types.
-     * If the class is supported, returns true.  Otherwise,
-     * returns false.
-     * @param ret The class to check
-     * @return boolean True if class is supported
-     */
-    private boolean supportedType(Class<?> ret) {
-        for (Class<?> supportedType : supportedTypes) {
-            if (ret == supportedType) {
-                return true;
-            }
-        }
-        if (isBeanCompatible(ret)) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Check if this class conforms to JavaBeans specifications.
-     * If the class is conformant, returns true.
-     *
-     * @param javaType The class to check
-     * @return boolean True if the class is compatible.
-     */
-    private boolean isBeanCompatible(Class<?> javaType) {
-        // Must be a non-primitive and non array
-        if (javaType.isArray() || javaType.isPrimitive()) {
-            return false;
-        }
-
-        // Anything in the java or javax package that
-        // does not have a defined mapping is excluded.
-        if (javaType.getName().startsWith("java.") ||
-            javaType.getName().startsWith("javax.") ||
-            javaType.getName().startsWith("jakarta.")) {
-            return false;
-        }
-
-        try {
-            javaType.getConstructor(new Class[]{});
-        } catch (java.lang.NoSuchMethodException e) {
-            return false;
-        }
-
-        // Make sure superclass is compatible
-        Class<?> superClass = javaType.getSuperclass();
-        if (superClass != null &&
-            superClass != java.lang.Object.class &&
-            superClass != java.lang.Exception.class &&
-            superClass != java.lang.Throwable.class) {
-            if (!isBeanCompatible(superClass)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Process the methods and extract 'attributes', methods, etc.
-     *
-     * @param realClass The class to process
-     * @param methods The methods to process
-     * @param attMap The attribute map (complete)
-     * @param getAttMap The readable attributes map
-     * @param setAttMap The settable attributes map
-     * @param invokeAttMap The invokable attributes map
-     */
-    private void initMethods(Class<?> realClass, Method methods[], Hashtable<String,Method> attMap,
-            Hashtable<String,Method> getAttMap, Hashtable<String,Method> setAttMap,
-            Hashtable<String,Method> invokeAttMap) {
-
-        for (Method method : methods) {
-            String name = method.getName();
-
-            if (Modifier.isStatic(method.getModifiers())) {
-                continue;
-            }
-            if (!Modifier.isPublic(method.getModifiers())) {
-                if (log.isDebugEnabled()) {
-                    log.debug("Not public " + method);
-                }
-                continue;
-            }
-            if (method.getDeclaringClass() == Object.class) {
-                continue;
-            }
-            Class<?> params[] = method.getParameterTypes();
-
-            if (name.startsWith("get") && params.length == 0) {
-                Class<?> ret = method.getReturnType();
-                if (!supportedType(ret)) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("Unsupported type " + method);
-                    }
-                    continue;
-                }
-                name = unCapitalize(name.substring(3));
-
-                getAttMap.put(name, method);
-                // just a marker, we don't use the value
-                attMap.put(name, method);
-            } else if (name.startsWith("is") && params.length == 0) {
-                Class<?> ret = method.getReturnType();
-                if (Boolean.TYPE != ret) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("Unsupported type " + method + " " + ret);
-                    }
-                    continue;
-                }
-                name = unCapitalize(name.substring(2));
-
-                getAttMap.put(name, method);
-                // just a marker, we don't use the value
-                attMap.put(name, method);
-
-            } else if (name.startsWith("set") && params.length == 1) {
-                if (!supportedType(params[0])) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("Unsupported type " + method + " " + params[0]);
-                    }
-                    continue;
-                }
-                name = unCapitalize(name.substring(3));
-                setAttMap.put(name, method);
-                attMap.put(name, method);
-            } else {
-                if (params.length == 0) {
-                    if (specialMethods.get(method.getName()) != null) {
-                        continue;
-                    }
-                    invokeAttMap.put(name, method);
-                } else {
-                    boolean supported = true;
-                    for (Class<?> param : params) {
-                        if (!supportedType(param)) {
-                            supported = false;
-                            break;
-                        }
-                    }
-                    if (supported) {
-                        invokeAttMap.put(name, method);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * XXX Find if the 'className' is the name of the MBean or
-     *       the real class ( I suppose first )
-     * XXX Read (optional) descriptions from a .properties, generated
-     *       from source
-     * XXX Deal with constructors
-     *
-     * @param registry The Bean registry (not used)
-     * @param domain The bean domain (not used)
-     * @param realClass The class to analyze
-     * @param type The bean type
-     * @return ManagedBean The create MBean
-     */
-    public ManagedBean createManagedBean(Registry registry, String domain,
-                                         Class<?> realClass, String type)
-    {
-        ManagedBean mbean= new ManagedBean();
-
-        Method methods[]=null;
-
-        Hashtable<String,Method> attMap = new Hashtable<>();
-        // key: attribute val: getter method
-        Hashtable<String,Method> getAttMap = new Hashtable<>();
-        // key: attribute val: setter method
-        Hashtable<String,Method> setAttMap = new Hashtable<>();
-        // key: operation val: invoke method
-        Hashtable<String,Method> invokeAttMap = new Hashtable<>();
-
-        methods = realClass.getMethods();
-
-        initMethods(realClass, methods, attMap, getAttMap, setAttMap, invokeAttMap );
-
-        try {
-
-            Enumeration<String> en = attMap.keys();
-            while( en.hasMoreElements() ) {
-                String name = en.nextElement();
-                AttributeInfo ai=new AttributeInfo();
-                ai.setName( name );
-                Method gm = getAttMap.get(name);
-                if( gm!=null ) {
-                    //ai.setGetMethodObj( gm );
-                    ai.setGetMethod( gm.getName());
-                    Class<?> t=gm.getReturnType();
-                    if( t!=null )
-                        ai.setType( t.getName() );
-                }
-                Method sm = setAttMap.get(name);
-                if( sm!=null ) {
-                    //ai.setSetMethodObj(sm);
-                    Class<?> t = sm.getParameterTypes()[0];
-                    if( t!=null )
-                        ai.setType( t.getName());
-                    ai.setSetMethod( sm.getName());
-                }
-                ai.setDescription("Introspected attribute " + name);
-                if( log.isDebugEnabled()) log.debug("Introspected attribute " +
-                        name + " " + gm + " " + sm);
-                if( gm==null )
-                    ai.setReadable(false);
-                if( sm==null )
-                    ai.setWriteable(false);
-                if( sm!=null || gm!=null )
-                    mbean.addAttribute(ai);
-            }
-
-            // This map is populated by iterating the methods (which end up as
-            // values in the Map) and obtaining the key from the value. It is
-            // impossible for a key to be associated with a null value.
-            for (Entry<String,Method> entry : invokeAttMap.entrySet()) {
-                String name = entry.getKey();
-                Method m = entry.getValue();
-
-                OperationInfo op=new OperationInfo();
-                op.setName(name);
-                op.setReturnType(m.getReturnType().getName());
-                op.setDescription("Introspected operation " + name);
-                Class<?> parms[] = m.getParameterTypes();
-                for(int i=0; i<parms.length; i++ ) {
-                    ParameterInfo pi=new ParameterInfo();
-                    pi.setType(parms[i].getName());
-                    pi.setName(("param" + i).intern());
-                    pi.setDescription(("Introspected parameter param" + i).intern());
-                    op.addParameter(pi);
-                }
-                mbean.addOperation(op);
-            }
-
-            if( log.isDebugEnabled())
-                log.debug("Setting name: " + type );
-            mbean.setName( type );
-
-            return mbean;
-        } catch( Exception ex ) {
-            ex.printStackTrace();
-            return null;
-        }
-    }
-
-
-    // -------------------- Utils --------------------
-    /**
-     * Converts the first character of the given
-     * String into lower-case.
-     *
-     * @param name The string to convert
-     * @return String
-     */
-    private static String unCapitalize(String name) {
-        if (name == null || name.length() == 0) {
-            return name;
-        }
-        char chars[] = name.toCharArray();
-        chars[0] = Character.toLowerCase(chars[0]);
-        return new String(chars);
-    }
-
-}
diff --git a/jakarta/src/patch/java/org/apache/webbeans/proxy/AbstractProxyFactory.java b/jakarta/src/patch/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
deleted file mode 100644
index eec5ba5..0000000
--- a/jakarta/src/patch/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
+++ /dev/null
@@ -1,737 +0,0 @@
-/*
- * 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.webbeans.proxy;
-
-import static org.apache.xbean.asm7.ClassReader.SKIP_CODE;
-import static org.apache.xbean.asm7.ClassReader.SKIP_DEBUG;
-import static org.apache.xbean.asm7.ClassReader.SKIP_FRAMES;
-
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import org.apache.webbeans.config.WebBeansContext;
-import org.apache.webbeans.exception.ProxyGenerationException;
-import org.apache.webbeans.exception.WebBeansException;
-import org.apache.webbeans.spi.DefiningClassService;
-import org.apache.xbean.asm7.ClassReader;
-import org.apache.xbean.asm7.ClassWriter;
-import org.apache.xbean.asm7.MethodVisitor;
-import org.apache.xbean.asm7.Opcodes;
-import org.apache.xbean.asm7.Type;
-import org.apache.xbean.asm7.shade.commons.EmptyVisitor;
-
-/**
- * Base class for all OWB Proxy factories
- */
-public abstract class AbstractProxyFactory
-{
-    public static final int MAX_CLASSLOAD_TRIES = 10000;
-
-    /**
-     * This is needed as the Modifier#VARARGS is not (yet) public.
-     * Note that the bitcode is the same as Modifier#TRANSIENT.
-     * But 'varargs' is only for methods, whereas 'transient' is only for fields.
-     */
-    public static final int MODIFIER_VARARGS = 0x00000080;
-
-    protected final Unsafe unsafe;
-
-    private final DefiningClassService definingService;
-
-    protected WebBeansContext webBeansContext;
-
-    private final int javaVersion;
-
-
-    /**
-     * The name of the field which stores the passivationID of the Bean this proxy serves.
-     * This is needed in case the proxy gets de-serialized back into a JVM
-     * which didn't have this bean loaded yet.
-     */
-    public static final String FIELD_BEAN_PASSIVATION_ID = "owbBeanPassivationId";
-
-
-    protected AbstractProxyFactory(WebBeansContext webBeansContext)
-    {
-        this.webBeansContext = webBeansContext;
-        javaVersion = determineDefaultJavaVersion();
-        unsafe = new Unsafe();
-        definingService = webBeansContext.getService(DefiningClassService.class);
-    }
-
-    private int determineDefaultJavaVersion()
-    {
-        String javaVersionProp = webBeansContext.getOpenWebBeansConfiguration().getGeneratorJavaVersion();
-        if (javaVersionProp == null)  // try to align on the runtime
-        {
-            javaVersionProp = System.getProperty("java.version");
-        }
-        if (javaVersionProp != null)
-        {
-            if (javaVersionProp.startsWith("1.8"))
-            {
-                return Opcodes.V1_8;
-            }
-            else if (javaVersionProp.startsWith("9") || javaVersionProp.startsWith("1.9"))
-            {
-                return Opcodes.V9;
-            }
-            else if (javaVersionProp.startsWith("10"))
-            {
-                return Opcodes.V10;
-            }
-            else if (javaVersionProp.startsWith("11"))
-            {
-                return Opcodes.V11;
-            }
-            else if (javaVersionProp.startsWith("12"))
-            {
-                return Opcodes.V12;
-            }
-            else if (javaVersionProp.startsWith("13"))
-            {
-                return Opcodes.V13;
-            }
-            else
-            {
-                try
-                {
-                    final int i = Integer.parseInt(javaVersionProp);
-                    if (i > 13)
-                    {
-                        return Opcodes.V13 + (i - 13);
-                    }
-                }
-                catch (final NumberFormatException nfe)
-                {
-                    // let's default
-                }
-            }
-        }
-
-        // the fallback is the lowest one to ensure it supports all possible classes of current environments
-        return Opcodes.V1_8;
-    }
-
-
-    protected ClassLoader getProxyClassLoader(Class<?> beanClass)
-    {
-        if (definingService != null)
-        {
-            return definingService.getProxyClassLoader(beanClass);
-        }
-        return webBeansContext.getApplicationBoundaryService().getBoundaryClassLoader(beanClass);
-    }
-
-    /**
-     * @return the marker interface which should be used for this proxy.
-     */
-    protected abstract Class getMarkerInterface();
-
-    /**
-     * generate the bytecode for creating the instance variables of the class
-     */
-    protected abstract void createInstanceVariables(ClassWriter cw, Class<?> classToProxy, String classFileName);
-
-    /**
-     * generate the bytecode for serialization.
-     */
-    protected abstract void createSerialisation(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, String classFileName);
-
-    /**
-     * Each of our interceptor/decorator proxies has exactly 1 constructor
-     * which invokes the super ct + sets the delegation field.
-     *
-     * @param cw
-     * @param classToProxy
-     * @param classFileName
-     * @throws org.apache.webbeans.exception.ProxyGenerationException
-     */
-    protected abstract void createConstructor(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, String classFileName, Constructor<?> injectConstructor)
-            throws ProxyGenerationException;
-
-    /**
-     * generate the bytecode for invoking all intercepted methods
-     */
-    protected abstract void delegateInterceptedMethods(ClassLoader classLoader, ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, Method[] interceptedMethods)
-            throws ProxyGenerationException;
-
-    /**
-     * generate the bytecode for invoking all non-intercepted methods
-     */
-    protected abstract void delegateNonInterceptedMethods(ClassLoader classLoader, ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, Method[] noninterceptedMethods)
-            throws ProxyGenerationException;
-
-    /**
-     * Detect a free classname based on the given one
-     * @param proxyClassName
-     * @return
-     */
-    protected String getUnusedProxyClassName(ClassLoader classLoader, String proxyClassName)
-    {
-        proxyClassName = fixPreservedPackages(proxyClassName);
-
-        String finalName = proxyClassName;
-
-        for (int i = 0; i < MAX_CLASSLOAD_TRIES; i++)
-        {
-            try
-            {
-                finalName = proxyClassName + i;
-                Class.forName(finalName, true, classLoader);
-            }
-            catch (ClassNotFoundException cnfe)
-            {
-                // this is exactly what we need!
-                return finalName;
-            }
-            // otherwise we continue ;)
-        }
-
-        throw new WebBeansException("Unable to detect a free proxy class name based on: " + proxyClassName);
-    }
-
-    protected  <T> String getSignedClassProxyName(final Class<T> classToProxy)
-    {
-        // avoid java.lang.SecurityException: class's signer information
-        // does not match signer information of other classes in the same package
-        return "org.apache.webbeans.custom.signed." + classToProxy.getName();
-    }
-
-    protected String fixPreservedPackages(String proxyClassName)
-    {
-        proxyClassName = fixPreservedPackage(proxyClassName, "java.");
-        proxyClassName = fixPreservedPackage(proxyClassName, "javax.");
-        proxyClassName = fixPreservedPackage(proxyClassName, "jakarta.");
-        proxyClassName = fixPreservedPackage(proxyClassName, "sun.misc.");
-
-        return proxyClassName;
-    }
-    /**
-     * Detect if the provided className is in the forbidden package.
-     * If so, move it to org.apache.webbeans.custom.
-     * @param forbiddenPackagePrefix including the '.', e.g. 'javax.'
-     */
-    private String fixPreservedPackage(String className, String forbiddenPackagePrefix)
-    {
-        String fixedClassName = className;
-
-        if (className.startsWith(forbiddenPackagePrefix))
-        {
-            fixedClassName = "org.apache.webbeans.custom." + className.substring(forbiddenPackagePrefix.length());
-        }
-
-        return fixedClassName;
-    }
-
-    protected <T> Class<T> createProxyClass(ClassLoader classLoader, String proxyClassName, Class<T> classToProxy,
-                                            Method[] interceptedMethods, Method[] nonInterceptedMethods)
-            throws ProxyGenerationException
-    {
-        return createProxyClass(classLoader, proxyClassName, classToProxy, interceptedMethods, nonInterceptedMethods, null);
-    }
-
-    /**
-     * @param classLoader to use for creating the class in
-     * @param classToProxy the class for which a subclass will get generated
-     * @param interceptedMethods the list of intercepted or decorated business methods.
-     * @param nonInterceptedMethods all methods which are <b>not</b> intercepted nor decorated and shall get delegated directly
-     * @param <T>
-     * @return the proxy class
-     */
-    protected <T> Class<T> createProxyClass(ClassLoader classLoader, String proxyClassName, Class<T> classToProxy,
-                                                      Method[] interceptedMethods, Method[] nonInterceptedMethods,
-                                                      Constructor<T> constructor)
-            throws ProxyGenerationException
-    {
-        String proxyClassFileName = proxyClassName.replace('.', '/');
-
-        byte[] proxyBytes = generateProxy(classLoader,
-                classToProxy,
-                proxyClassName,
-                proxyClassFileName,
-                sortOutDuplicateMethods(interceptedMethods),
-                sortOutDuplicateMethods(nonInterceptedMethods),
-                constructor);
-
-        if (definingService != null)
-        {
-            return definingService.defineAndLoad(proxyClassName, proxyBytes, classToProxy);
-        }
-        return unsafe.defineAndLoadClass(classLoader, proxyClassName, proxyBytes);
-    }
-
-    private Method[] sortOutDuplicateMethods(Method[] methods)
-    {
-        if (methods == null || methods.length == 0)
-        {
-            return null;
-        }
-
-        ArrayList<Method> duplicates = new ArrayList<>();
-
-        for (Method outer : methods)
-        {
-            for (Method inner : methods)
-            {
-                if (inner != outer
-                        && hasSameSignature(outer, inner)
-                        && !(duplicates.contains(outer) || duplicates.contains(inner)))
-                {
-                    duplicates.add(inner);
-                }
-            }
-        }
-
-        ArrayList<Method> outsorted = new ArrayList<>(Arrays.asList(methods));
-        outsorted.removeAll(duplicates);
-        return outsorted.toArray(new Method[outsorted.size()]);
-    }
-
-    private boolean hasSameSignature(Method a, Method b)
-    {
-        return a.getName().equals(b.getName())
-                && a.getReturnType().equals(b.getReturnType())
-                && Arrays.equals(a.getParameterTypes(), b.getParameterTypes());
-    }
-
-    private byte[] generateProxy(ClassLoader classLoader, Class<?> classToProxy, String proxyClassName, String proxyClassFileName,
-                                 Method[] interceptedMethods, Method[] nonInterceptedMethods, Constructor<?> constructor)
-            throws ProxyGenerationException
-    {
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
-        String classFileName = classToProxy.getName().replace('.', '/');
-
-        String[] interfaceNames = {Type.getInternalName(getMarkerInterface())};
-        String superClassName = classFileName;
-
-        if (classToProxy.isInterface())
-        {
-            interfaceNames = new String[]{Type.getInternalName(classToProxy), interfaceNames[0]};
-            superClassName = Type.getInternalName(Object.class);
-        }
-
-        cw.visit(findJavaVersion(classToProxy), Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER + Opcodes.ACC_SYNTHETIC, proxyClassFileName, null, superClassName, interfaceNames);
-        cw.visitSource(classFileName + ".java", null);
-
-        createInstanceVariables(cw, classToProxy, classFileName);
-        createSerialisation(cw, proxyClassFileName, classToProxy, classFileName);
-
-
-
-        // create a static String Field which contains the passivationId of the Bean or null if not PassivationCapable
-        cw.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC,
-                FIELD_BEAN_PASSIVATION_ID, Type.getDescriptor(String.class), null, null).visitEnd();
-
-        createConstructor(cw, proxyClassFileName, classToProxy, classFileName, constructor);
-
-
-        if (nonInterceptedMethods != null)
-        {
-            delegateNonInterceptedMethods(classLoader, cw, proxyClassFileName, classToProxy, nonInterceptedMethods);
-        }
-
-        if (interceptedMethods != null)
-        {
-            delegateInterceptedMethods(classLoader, cw, proxyClassFileName, classToProxy, interceptedMethods);
-        }
-
-        return cw.toByteArray();
-    }
-
-    private int findJavaVersion(final Class<?> from)
-    {
-        final String resource = from.getName().replace('.', '/') + ".class";
-        try (final InputStream stream = from.getClassLoader().getResourceAsStream(resource))
-        {
-            if (stream == null)
-            {
-                return javaVersion;
-            }
-            final ClassReader reader = new ClassReader(stream);
-            final VersionVisitor visitor = new VersionVisitor();
-            reader.accept(visitor, SKIP_DEBUG + SKIP_CODE + SKIP_FRAMES);
-            if (visitor.version != 0)
-            {
-                return visitor.version;
-            }
-        }
-        catch (final Exception e)
-        {
-            // no-op
-        }
-        // mainly for JVM classes - outside the classloader, find to fallback on the JVM version
-        return javaVersion;
-    }
-
-
-
-    protected boolean unproxyableMethod(Method delegatedMethod)
-    {
-        int modifiers = delegatedMethod.getModifiers();
-
-        return (modifiers & (Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL | Modifier.NATIVE)) > 0 ||
-               "finalize".equals(delegatedMethod.getName()) || delegatedMethod.isBridge();
-    }
-
-    /**
-     * @return the wrapper type for a primitive, e.g. java.lang.Integer for int
-     */
-    protected String getWrapperType(Class<?> type)
-    {
-        if (Integer.TYPE.equals(type))
-        {
-            return Integer.class.getCanonicalName().replace('.', '/');
-        }
-        else if (Boolean.TYPE.equals(type))
-        {
-            return Boolean.class.getCanonicalName().replace('.', '/');
-        }
-        else if (Character.TYPE.equals(type))
-        {
-            return Character.class.getCanonicalName().replace('.', '/');
-        }
-        else if (Byte.TYPE.equals(type))
-        {
-            return Byte.class.getCanonicalName().replace('.', '/');
-        }
-        else if (Short.TYPE.equals(type))
-        {
-            return Short.class.getCanonicalName().replace('.', '/');
-        }
-        else if (Float.TYPE.equals(type))
-        {
-            return Float.class.getCanonicalName().replace('.', '/');
-        }
-        else if (Long.TYPE.equals(type))
-        {
-            return Long.class.getCanonicalName().replace('.', '/');
-        }
-        else if (Double.TYPE.equals(type))
-        {
-            return Double.class.getCanonicalName().replace('.', '/');
-        }
-        else if (Void.TYPE.equals(type))
-        {
-            return Void.class.getCanonicalName().replace('.', '/');
-        }
-
-        throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type");
-    }
-
-    /**
-     * Returns the appropriate bytecode instruction to load a value from a variable to the stack
-     *
-     * @param type Type to load
-     * @return Bytecode instruction to use
-     */
-    protected int getVarInsn(Class<?> type)
-    {
-        if (type.isPrimitive())
-        {
-            if (Integer.TYPE.equals(type))
-            {
-                return Opcodes.ILOAD;
-            }
-            else if (Boolean.TYPE.equals(type))
-            {
-                return Opcodes.ILOAD;
-            }
-            else if (Character.TYPE.equals(type))
-            {
-                return Opcodes.ILOAD;
-            }
-            else if (Byte.TYPE.equals(type))
-            {
-                return Opcodes.ILOAD;
-            }
-            else if (Short.TYPE.equals(type))
-            {
-                return Opcodes.ILOAD;
-            }
-            else if (Float.TYPE.equals(type))
-            {
-                return Opcodes.FLOAD;
-            }
-            else if (Long.TYPE.equals(type))
-            {
-                return Opcodes.LLOAD;
-            }
-            else if (Double.TYPE.equals(type))
-            {
-                return Opcodes.DLOAD;
-            }
-        }
-
-        throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type");
-    }
-
-    /**
-     * Invokes the most appropriate bytecode instruction to put a number on the stack
-     *
-     * @param mv
-     * @param i
-     */
-    protected void pushIntOntoStack(MethodVisitor mv, int i)
-    {
-        if (i == 0)
-        {
-            mv.visitInsn(Opcodes.ICONST_0);
-        }
-        else if (i == 1)
-        {
-            mv.visitInsn(Opcodes.ICONST_1);
-        }
-        else if (i == 2)
-        {
-            mv.visitInsn(Opcodes.ICONST_2);
-        }
-        else if (i == 3)
-        {
-            mv.visitInsn(Opcodes.ICONST_3);
-        }
-        else if (i == 4)
-        {
-            mv.visitInsn(Opcodes.ICONST_4);
-        }
-        else if (i == 5)
-        {
-            mv.visitInsn(Opcodes.ICONST_5);
-        }
-        else if (i > 5 && i <= 255)
-        {
-            mv.visitIntInsn(Opcodes.BIPUSH, i);
-        }
-        else
-        {
-            mv.visitIntInsn(Opcodes.SIPUSH, i);
-        }
-    }
-
-    /**
-     * Gets the appropriate bytecode instruction for RETURN, according to what type we need to return
-     *
-     * @param type Type the needs to be returned
-     * @return The matching bytecode instruction
-     */
-    protected int getReturnInsn(Class<?> type)
-    {
-        if (type.isPrimitive())
-        {
-            if (Void.TYPE.equals(type))
-            {
-                return Opcodes.RETURN;
-            }
-            if (Integer.TYPE.equals(type))
-            {
-                return Opcodes.IRETURN;
-            }
-            else if (Boolean.TYPE.equals(type))
-            {
-                return Opcodes.IRETURN;
-            }
-            else if (Character.TYPE.equals(type))
-            {
-                return Opcodes.IRETURN;
-            }
-            else if (Byte.TYPE.equals(type))
-            {
-                return Opcodes.IRETURN;
-            }
-            else if (Short.TYPE.equals(type))
-            {
-                return Opcodes.IRETURN;
-            }
-            else if (Float.TYPE.equals(type))
-            {
-                return Opcodes.FRETURN;
-            }
-            else if (Long.TYPE.equals(type))
-            {
-                return Opcodes.LRETURN;
-            }
-            else if (Double.TYPE.equals(type))
-            {
-                return Opcodes.DRETURN;
-            }
-        }
-
-        return Opcodes.ARETURN;
-    }
-
-    /**
-     * Gets the string to use for CHECKCAST instruction, returning the correct value for any type, including primitives and arrays
-     *
-     * @param returnType The type to cast to with CHECKCAST
-     * @return CHECKCAST parameter
-     */
-    protected String getCastType(Class<?> returnType)
-    {
-        if (returnType.isPrimitive())
-        {
-            return getWrapperType(returnType);
-        }
-        else
-        {
-            return Type.getInternalName(returnType);
-        }
-    }
-
-    /**
-     * Returns the name of the Java method to call to get the primitive value from an Object - e.g. intValue for java.lang.Integer
-     *
-     * @param type Type whose primitive method we want to lookup
-     * @return The name of the method to use
-     */
-    protected String getPrimitiveMethod(Class<?> type)
-    {
-        if (Integer.TYPE.equals(type))
-        {
-            return "intValue";
-        }
-        else if (Boolean.TYPE.equals(type))
-        {
-            return "booleanValue";
-        }
-        else if (Character.TYPE.equals(type))
-        {
-            return "charValue";
-        }
-        else if (Byte.TYPE.equals(type))
-        {
-            return "byteValue";
-        }
-        else if (Short.TYPE.equals(type))
-        {
-            return "shortValue";
-        }
-        else if (Float.TYPE.equals(type))
-        {
-            return "floatValue";
-        }
-        else if (Long.TYPE.equals(type))
-        {
-            return "longValue";
-        }
-        else if (Double.TYPE.equals(type))
-        {
-            return "doubleValue";
-        }
-
-        throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type");
-    }
-
-    protected void generateReturn(MethodVisitor mv, Method delegatedMethod)
-    {
-        Class<?> returnType = delegatedMethod.getReturnType();
-        mv.visitInsn(getReturnInsn(returnType));
-    }
-
-    /**
-     * Create an Object[] parameter which contains all the parameters of the currently invoked method
-     * and store this array for use in the call stack.
-     * @param mv
-     * @param parameterTypes
-     */
-    protected void pushMethodParameterArray(MethodVisitor mv, Class<?>[] parameterTypes)
-    {
-        // need to construct the array of objects passed in
-        // create the Object[]
-        createArrayDefinition(mv, parameterTypes.length, Object.class);
-
-        int index = 1;
-        // push parameters into array
-        for (int i = 0; i < parameterTypes.length; i++)
-        {
-            // keep copy of array on stack
-            mv.visitInsn(Opcodes.DUP);
-
-            Class<?> parameterType = parameterTypes[i];
-
-            // push number onto stack
-            pushIntOntoStack(mv, i);
-
-            if (parameterType.isPrimitive())
-            {
-                String wrapperType = getWrapperType(parameterType);
-                mv.visitVarInsn(getVarInsn(parameterType), index);
-
-                mv.visitMethodInsn(Opcodes.INVOKESTATIC, wrapperType, "valueOf",
-                        "(" + Type.getDescriptor(parameterType) + ")L" + wrapperType + ";", false);
-                mv.visitInsn(Opcodes.AASTORE);
-
-                if (Long.TYPE.equals(parameterType) || Double.TYPE.equals(parameterType))
-                {
-                    index += 2;
-                }
-                else
-                {
-                    index++;
-                }
-            }
-            else
-            {
-                mv.visitVarInsn(Opcodes.ALOAD, index);
-                mv.visitInsn(Opcodes.AASTORE);
-                index++;
-            }
-        }
-    }
-
-    /**
-     * pushes an array of the specified size to the method visitor. The generated bytecode will leave
-     * the new array at the top of the stack.
-     *
-     * @param mv   MethodVisitor to use
-     * @param size Size of the array to create
-     * @param type Type of array to create
-     * @throws ProxyGenerationException
-     */
-    protected void createArrayDefinition(MethodVisitor mv, int size, Class<?> type)
-            throws ProxyGenerationException
-    {
-        // create a new array of java.lang.class (2)
-
-        if (size < 0)
-        {
-            throw new ProxyGenerationException("Array size cannot be less than zero");
-        }
-
-        pushIntOntoStack(mv, size);
-
-        mv.visitTypeInsn(Opcodes.ANEWARRAY, type.getCanonicalName().replace('.', '/'));
-    }
-
-
-    private static class VersionVisitor extends EmptyVisitor
-    {
-        private int version;
-
-        @Override
-        public void visit(final int version, final int access, final String name,
-                          final String signature, final String superName, final String[] interfaces)
-        {
-            this.version = version;
-        }
-    }
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/eclipse/persistence/internal/jpa/deployment/JavaSECMPInitializer.java b/jakarta/src/patch/java/org/eclipse/persistence/internal/jpa/deployment/JavaSECMPInitializer.java
deleted file mode 100644
index 3b773b3..0000000
--- a/jakarta/src/patch/java/org/eclipse/persistence/internal/jpa/deployment/JavaSECMPInitializer.java
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 1998, 2018 IBM Corporation. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- */
-
-// Contributors:
-//     Oracle - initial API and implementation from Oracle TopLink
-//     tware - 1.0RC1 - refactor for OSGi
-//     zhao jianyong - Bug 324627 - JarList stream is not explicitly closed after use in JavaSECMPInitializer
-package org.eclipse.persistence.internal.jpa.deployment;
-
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.IllegalClassFormatException;
-import java.lang.instrument.Instrumentation;
-import java.lang.reflect.Constructor;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.ProtectionDomain;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-
-import jakarta.persistence.PersistenceException;
-import jakarta.persistence.spi.ClassTransformer;
-import jakarta.persistence.spi.PersistenceUnitInfo;
-
-import org.eclipse.persistence.config.PersistenceUnitProperties;
-import org.eclipse.persistence.exceptions.EntityManagerSetupException;
-import org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider;
-import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
-import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
-import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
-import org.eclipse.persistence.logging.AbstractSessionLog;
-import org.eclipse.persistence.logging.SessionLog;
-
-/**
- * INTERNAL:
- *
- * JavaSECMPInitializer is used to bootstrap the deployment of EntityBeans in EJB 3.0
- * when deployed in a non-managed setting
- *
- * It is called internally by our Provider
- *
- * @see org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider
- */
-public class JavaSECMPInitializer extends JPAInitializer {
-
-    // Used when byte code enhancing
-    public static Instrumentation globalInstrumentation;
-    // Adding this flag because globalInstrumentation could be set to null after weaving is done.
-    protected static boolean usesAgent;
-    // Adding this flag to know that within a JEE container so weaving should be enabled without an agent for non managed persistence units.
-    protected static boolean isInContainer;
-    // Indicates whether has been initialized - that could be done only once.
-    protected static boolean isInitialized;
-    // Singleton corresponding to the main class loader. Created only if agent is used.
-    protected static JavaSECMPInitializer initializer;
-    // Used as a lock in getJavaSECMPInitializer.
-    private static final Object initializationLock = new Object();
-
-    public static boolean isInContainer() {
-        return isInContainer;
-    }
-    public static void setIsInContainer(boolean isInContainer) {
-        JavaSECMPInitializer.isInContainer = isInContainer;
-    }
-
-    /**
-     * Get the singleton entityContainer.
-     */
-    public static JavaSECMPInitializer getJavaSECMPInitializer() {
-        return getJavaSECMPInitializer(Thread.currentThread().getContextClassLoader(), null, false);
-    }
-    public static JavaSECMPInitializer getJavaSECMPInitializer(ClassLoader classLoader) {
-        return getJavaSECMPInitializer(classLoader, null, false);
-    }
-    public static JavaSECMPInitializer getJavaSECMPInitializerFromAgent() {
-        return getJavaSECMPInitializer(Thread.currentThread().getContextClassLoader(), null, true);
-    }
-    public static JavaSECMPInitializer getJavaSECMPInitializerFromMain(Map m) {
-        return getJavaSECMPInitializer(Thread.currentThread().getContextClassLoader(), m, false);
-    }
-    public static JavaSECMPInitializer getJavaSECMPInitializer(ClassLoader classLoader, Map m, boolean fromAgent) {
-        if(!isInitialized) {
-            if(globalInstrumentation != null) {
-                synchronized(initializationLock) {
-                    if(!isInitialized) {
-                        initializeTopLinkLoggingFile();
-                        if(fromAgent) {
-                            AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.WEAVER, "cmp_init_initialize_from_agent", (Object[])null);
-                        }
-                        usesAgent = true;
-                        initializer = new JavaSECMPInitializer(classLoader);
-                        initializer.initialize(m != null ? m : new HashMap(0));
-                        // all the transformers have been added to instrumentation, don't need it any more.
-                        globalInstrumentation = null;
-                    }
-                }
-            }
-            isInitialized = true;
-        }
-        if(initializer != null && initializer.getInitializationClassLoader() == classLoader) {
-            return initializer;
-        } else {
-            // when agent is not used initializer does not need to be initialized.
-            return new JavaSECMPInitializer(classLoader);
-        }
-    }
-
-    /**
-     * User should not instantiate JavaSECMPInitializer.
-     */
-    protected JavaSECMPInitializer() {
-        super();
-    }
-
-    protected JavaSECMPInitializer(ClassLoader loader) {
-        super();
-        this.initializationClassloader = loader;
-    }
-
-    /**
-     * Check whether weaving is possible and update the properties and variable as appropriate
-     * @param properties The list of properties to check for weaving and update if weaving is not needed
-     */
-    @Override
-    public void checkWeaving(Map properties){
-        String weaving = EntityManagerFactoryProvider.getConfigPropertyAsString(PersistenceUnitProperties.WEAVING, properties, null);
-        // Check usesAgent instead of globalInstrumentation!=null because globalInstrumentation is set to null after initialization,
-        // but we still have to keep weaving so that the resulting projects correspond to the woven (during initialization) classes.
-        if (!usesAgent && !isInContainer) {
-            if (weaving == null) {
-               properties.put(PersistenceUnitProperties.WEAVING, "false");
-               weaving = "false";
-            } else if (weaving.equalsIgnoreCase("true")) {
-                throw new PersistenceException(EntityManagerSetupException.wrongWeavingPropertyValue());
-            }
-        }
-        if ((weaving != null) && ((weaving.equalsIgnoreCase("false")) || (weaving.equalsIgnoreCase("static")))){
-            shouldCreateInternalLoader = false;
-        }
-    }
-
-    /**
-     * Create a temporary class loader that can be used to inspect classes and then
-     * thrown away.  This allows classes to be introspected prior to loading them
-     * with application's main class loader enabling weaving.
-     */
-    @Override
-    protected ClassLoader createTempLoader(Collection col) {
-        return createTempLoader(col, true);
-    }
-
-    @Override
-    protected ClassLoader createTempLoader(Collection col, boolean shouldOverrideLoadClassForCollectionMembers) {
-        if (!shouldCreateInternalLoader) {
-            return Thread.currentThread().getContextClassLoader();
-        }
-
-        ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
-        if (!(currentLoader instanceof URLClassLoader)) {
-            //we can't create a TempEntityLoader so just use the current one
-            //shouldn't be a problem (and should only occur) in JavaSE
-            return currentLoader;
-        }
-        URL[] urlPath = ((URLClassLoader)currentLoader).getURLs();
-
-        ClassLoader tempLoader = null;
-        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
-            try {
-                Class[] argsClasses = new Class[] { URL[].class, ClassLoader.class, Collection.class, boolean.class };
-                Object[] args = new Object[] { urlPath, currentLoader, col, shouldOverrideLoadClassForCollectionMembers };
-                Constructor classLoaderConstructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor(TempEntityLoader.class, argsClasses, true));
-                tempLoader = (ClassLoader) AccessController.doPrivileged(new PrivilegedInvokeConstructor(classLoaderConstructor, args));
-            } catch (PrivilegedActionException privilegedException) {
-                throw new PersistenceException(EntityManagerSetupException.failedToInstantiateTemporaryClassLoader(privilegedException));
-            }
-        } else {
-            tempLoader = new TempEntityLoader(urlPath, currentLoader, col, shouldOverrideLoadClassForCollectionMembers);
-        }
-
-        AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.WEAVER, "cmp_init_tempLoader_created", tempLoader);
-        AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.WEAVER, "cmp_init_shouldOverrideLoadClassForCollectionMembers", Boolean.valueOf(shouldOverrideLoadClassForCollectionMembers));
-
-        return tempLoader;
-    }
-
-    /**
-     * INTERNAL:
-     * Should be called only by the agent. (when weaving classes)
-     * If succeeded return true, false otherwise.
-     */
-    protected static void initializeFromAgent(Instrumentation instrumentation) throws Exception {
-        // Squirrel away the instrumentation for later
-        globalInstrumentation = instrumentation;
-        getJavaSECMPInitializerFromAgent();
-    }
-
-    /**
-     * Usually JavaSECMPInitializer is initialized from agent during premain
-     * to ensure that the classes to be weaved haven't been loaded before initialization.
-     * However, in this case initialization can't be debugged.
-     * In order to be able to debug initialization specify
-     * in java options -javaagent with parameter "main":  (note: a separate eclipselink-agent.jar is no longer required)
-     *   -javaagent:c:\trunk\eclipselink.jar=main
-     * that causes instrumentation to be cached during premain and postpones initialization until main.
-     * With initialization done in main (during the first createEntityManagerFactory call)
-     * there's a danger of the classes to be weaved being already loaded.
-     * In that situation initializeFromMain should be called before any classes are loaded.
-     * The sure-to-work method would be to create a new runnable class with a main method
-     * consisting of just two lines: calling initializeFromMain
-     * followed by reflective call to the main method of the original runnable class.
-     * The same could be achieved by calling PersistenceProvider.createEntityManagerFactory method instead
-     * of JavaSECMPInitializer.initializeFromMain method,
-     * however initializeFromMain might be more convenient because it
-     * doesn't require a persistence unit name.
-     * The method doesn't do anything if JavaSECMPInitializer has been already initialized.
-     * @param m - a map containing the set of properties to instantiate with.
-     */
-    public static void initializeFromMain(Map m) {
-        getJavaSECMPInitializerFromMain(m);
-    }
-
-    /**
-     * The version of initializeFromMain that passes an empty map.
-     */
-    public static void initializeFromMain() {
-        initializeFromMain(new HashMap());
-    }
-
-    /**
-     * Register a transformer.  In this case, we use the instrumentation to add a transformer for the
-     * JavaSE environment
-     * @param transformer
-     * @param persistenceUnitInfo
-     */
-    @Override
-    public void registerTransformer(final ClassTransformer transformer, PersistenceUnitInfo persistenceUnitInfo, Map properties){
-        if ((transformer != null) && (globalInstrumentation != null)) {
-            AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.WEAVER, "cmp_init_register_transformer", persistenceUnitInfo.getPersistenceUnitName());
-            globalInstrumentation.addTransformer(new ClassFileTransformer() {
-                // adapt ClassTransformer to ClassFileTransformer interface
-                @Override
-                public byte[] transform(
-                        ClassLoader loader, String className,
-                        Class<?> classBeingRedefined,
-                        ProtectionDomain protectionDomain,
-                        byte[] classfileBuffer) throws IllegalClassFormatException {
-                    return transformer.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
-                }
-            });
-        } else if (transformer == null) {
-            AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.WEAVER, "cmp_init_transformer_is_null", null, true);
-        } else if (globalInstrumentation == null) {
-            AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.WEAVER, "cmp_init_globalInstrumentation_is_null", null, true);
-        }
-    }
-
-    /**
-     * Indicates whether puName uniquely defines the persistence unit.
-     * usesAgent means that it is a stand alone SE case.
-     * Otherwise it could be an application server case where different persistence units
-     * may have the same name: that could happen if they are loaded by different classloaders;
-     * the common case is the same persistence unit jar deployed in several applications.
-     */
-    @Override
-    public boolean isPersistenceUnitUniquelyDefinedByName() {
-        return usesAgent;
-    }
-
-    /**
-     * Indicates whether initialization has already occurred.
-     */
-    public static boolean isInitialized() {
-        return isInitialized;
-    }
-
-    /**
-     * Indicates whether Java agent and globalInstrumentation was used.
-     */
-    public static boolean usesAgent() {
-        return usesAgent;
-    }
-
-    /**
-     * Indicates whether initialPuInfos and initialEmSetupImpls are used.
-     */
-    @Override
-    protected boolean keepAllPredeployedPersistenceUnits() {
-        return usesAgent;
-    }
-
-    /*********************************/
-    /***** Temporary Classloader *****/
-    /*********************************/
-    /**
-     * This class loader is provided at initialization time to allow us to temporarily load
-     * domain classes so we can examine them for annotations.  After they are loaded we will throw this
-     * class loader away.  Transformers can then be registered on the real class loader to allow
-     * weaving to occur.
-     *
-     * It selectively loads classes based on the list of classnames it is instantiated with.  Classes
-     * not on that list are allowed to be loaded by the parent.
-     */
-    public static class TempEntityLoader extends URLClassLoader {
-        Collection classNames;
-        boolean shouldOverrideLoadClassForCollectionMembers;
-
-        //added to resolved gf #589 - without this, the orm.xml url would be returned twice
-        @Override
-        public Enumeration<URL> getResources(String name) throws java.io.IOException {
-            return this.getParent().getResources(name);
-        }
-
-        public TempEntityLoader(URL[] urls, ClassLoader parent, Collection classNames, boolean shouldOverrideLoadClassForCollectionMembers) {
-            super(urls, parent);
-            this.classNames = classNames;
-            this.shouldOverrideLoadClassForCollectionMembers = shouldOverrideLoadClassForCollectionMembers;
-        }
-
-        public TempEntityLoader(URL[] urls, ClassLoader parent, Collection classNames) {
-            this(urls, parent, classNames, true);
-        }
-
-        // Indicates if the classLoad should be overridden for the passed className.
-        // Returns true in case the class should NOT be loaded by parent classLoader.
-        protected boolean shouldOverrideLoadClass(String name) {
-            if (shouldOverrideLoadClassForCollectionMembers) {
-                // Override classLoad if the name is in collection
-                return (classNames != null) && classNames.contains(name);
-            } else {
-                // Directly opposite: Override classLoad if the name is NOT in collection.
-                // Forced to check for java. and javax. packages here, because even if the class
-                // has been loaded by parent loader we would load it again
-                // (see comment in loadClass)
-                return !name.startsWith("java.") && !name.startsWith("javax.") && !name.startsWith("jakarta.") && ((classNames == null) || !classNames.contains(name));
-            }
-        }
-
-        @Override
-        protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
-            if (shouldOverrideLoadClass(name)) {
-                // First, check if the class has already been loaded.
-                // Note that the check only for classes loaded by this loader,
-                // it doesn't return true if the class has been loaded by parent loader
-                // (forced to live with that because findLoadedClass method defined as final protected:
-                //  neither can override it nor call it on the parent loader)
-                Class c = findLoadedClass(name);
-                if (c == null) {
-                    c = findClass(name);
-                }
-                if (resolve) {
-                    resolveClass(c);
-                }
-                return c;
-            } else {
-                return super.loadClass(name, resolve);
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/eclipse/persistence/internal/jpa/metadata/accessors/objects/MetadataAsmFactory.java b/jakarta/src/patch/java/org/eclipse/persistence/internal/jpa/metadata/accessors/objects/MetadataAsmFactory.java
deleted file mode 100644
index 04fce33..0000000
--- a/jakarta/src/patch/java/org/eclipse/persistence/internal/jpa/metadata/accessors/objects/MetadataAsmFactory.java
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 1998, 2018 Hans Harz, Andrew Rustleund, IBM Corporation. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- */
-
-// Contributors:
-//     James Sutherland - initial impl
-//     05/14/2010-2.1 Guy Pelletier
-//       - 253083: Add support for dynamic persistence using ORM.xml/eclipselink-orm.xml
-//     Hans Harz, Andrew Rustleund - Bug 324862 - IndexOutOfBoundsException in
-//           DatabaseSessionImpl.initializeDescriptors because @MapKey Annotation is not found.
-//     04/21/2011-2.3 dclarke: Upgraded to support ASM 3.3.1
-//     08/10/2011-2.3 Lloyd Fernandes : Bug 336133 - Validation error during processing on parameterized generic OneToMany Entity relationship from MappedSuperclass
-//     10/05/2012-2.4.1 Guy Pelletier
-//       - 373092: Exceptions using generics, embedded key and entity inheritance
-//     19/04/2014-2.6 Lukas Jungmann
-//       - 429992: JavaSE 8/ASM 5.0.1 support (EclipseLink silently ignores Entity classes with lambda expressions)
-//     11/05/2015-2.6 Dalia Abo Sheasha
-//       - 480787 : Wrap several privileged method calls with a doPrivileged block
-package org.eclipse.persistence.internal.jpa.metadata.accessors.objects;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.persistence.internal.helper.Helper;
-import org.eclipse.persistence.internal.jpa.metadata.MetadataDescriptor;
-import org.eclipse.persistence.internal.jpa.metadata.MetadataLogger;
-import org.eclipse.persistence.internal.libraries.asm.AnnotationVisitor;
-import org.eclipse.persistence.internal.libraries.asm.Attribute;
-import org.eclipse.persistence.internal.libraries.asm.ClassReader;
-import org.eclipse.persistence.internal.libraries.asm.ClassVisitor;
-import org.eclipse.persistence.internal.libraries.asm.EclipseLinkClassReader;
-import org.eclipse.persistence.internal.libraries.asm.FieldVisitor;
-import org.eclipse.persistence.internal.libraries.asm.MethodVisitor;
-import org.eclipse.persistence.internal.libraries.asm.Opcodes;
-import org.eclipse.persistence.internal.libraries.asm.Type;
-import org.eclipse.persistence.internal.localization.ExceptionLocalization;
-import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
-import org.eclipse.persistence.logging.AbstractSessionLog;
-import org.eclipse.persistence.logging.SessionLog;
-import org.eclipse.persistence.logging.SessionLogEntry;
-
-/**
- * INTERNAL: A metadata factory that uses ASM technology and no reflection
- * whatsoever to process the metadata model.
- *
- * @author James Sutherland
- * @since EclipseLink 1.2
- */
-public class MetadataAsmFactory extends MetadataFactory {
-    /** Set of primitive type codes. */
-    public static final String PRIMITIVES = "VJIBZCSFD";
-    /** Set of desc token characters. */
-    public static final String TOKENS = "()<>;";
-
-    /**
-     * INTERNAL:
-     */
-    public MetadataAsmFactory(MetadataLogger logger, ClassLoader loader) {
-        super(logger, loader);
-
-        addMetadataClass("I", new MetadataClass(this, int.class));
-        addMetadataClass("J", new MetadataClass(this, long.class));
-        addMetadataClass("S", new MetadataClass(this, short.class));
-        addMetadataClass("Z", new MetadataClass(this, boolean.class));
-        addMetadataClass("F", new MetadataClass(this, float.class));
-        addMetadataClass("D", new MetadataClass(this, double.class));
-        addMetadataClass("C", new MetadataClass(this, char.class));
-        addMetadataClass("B", new MetadataClass(this, byte.class));
-    }
-
-    /**
-     * Build the class metadata for the class name using ASM to read the class
-     * byte codes.
-     */
-    protected void buildClassMetadata(MetadataClass metadataClass, String className, boolean isLazy) {
-        ClassMetadataVisitor visitor = new ClassMetadataVisitor(metadataClass, isLazy);
-        InputStream stream = null;
-        try {
-            String resourceString = className.replace('.', '/') + ".class";
-            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
-                final String f_resourceString = resourceString;
-                stream = AccessController.doPrivileged(new PrivilegedAction<InputStream>() {
-                    @Override
-                    public InputStream run() {
-                        return m_loader.getResourceAsStream(f_resourceString);
-                    }
-                });
-            } else {
-                stream = m_loader.getResourceAsStream(resourceString);
-            }
-
-            ClassReader reader = new ClassReader(stream);
-            Attribute[] attributes = new Attribute[0];
-            reader.accept(visitor, attributes, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
-        } catch (IllegalArgumentException iae) {
-            // class was probably compiled with some newer than officially
-            // supported and tested JDK
-            // in such case log a warning and try to re-read the class
-            // without class version check
-            SessionLog log = getLogger().getSession() != null
-                    ? getLogger().getSession().getSessionLog() : AbstractSessionLog.getLog();
-            if (log.shouldLog(SessionLog.SEVERE, SessionLog.METADATA)) {
-                SessionLogEntry entry = new SessionLogEntry(getLogger().getSession(), SessionLog.SEVERE, SessionLog.METADATA, iae);
-                entry.setMessage(ExceptionLocalization.buildMessage("unsupported_classfile_version", new Object[] { className }));
-                log.log(entry);
-            }
-            if (stream != null) {
-                try {
-                    ClassReader reader = new EclipseLinkClassReader(stream);
-                    Attribute[] attributes = new Attribute[0];
-                    reader.accept(visitor, attributes, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
-                } catch (Exception e) {
-                    if (log.shouldLog(SessionLog.SEVERE, SessionLog.METADATA)) {
-                        SessionLogEntry entry = new SessionLogEntry(getLogger().getSession(), SessionLog.SEVERE, SessionLog.METADATA, e);
-                        entry.setMessage(ExceptionLocalization.buildMessage("unsupported_classfile_version", new Object[] { className }));
-                        log.log(entry);
-                    }
-                    addMetadataClass(getVirtualMetadataClass(className));
-                }
-            } else {
-                addMetadataClass(getVirtualMetadataClass(className));
-            }
-        } catch (Exception exception) {
-            SessionLog log = getLogger().getSession() != null
-                    ? getLogger().getSession().getSessionLog() : AbstractSessionLog.getLog();
-            if (log.shouldLog(SessionLog.FINEST, SessionLog.METADATA)) {
-                log.logThrowable(SessionLog.FINEST, SessionLog.METADATA, exception);
-            }
-            addMetadataClass(getVirtualMetadataClass(className));
-        } finally {
-            try {
-                if (stream != null) {
-                    stream.close();
-                }
-            } catch (IOException ignore) {
-                // Ignore.
-            }
-        }
-    }
-
-    /**
-     * Return the class metadata for the class name.
-     */
-    @Override
-    public MetadataClass getMetadataClass(String className) {
-        return getMetadataClass(className, false);
-    }
-
-    /**
-     * Return the class metadata for the class name.
-     */
-    @Override
-    public MetadataClass getMetadataClass(String className, boolean isLazy) {
-        if (className == null) {
-            return null;
-        }
-
-        MetadataClass metaClass = m_metadataClasses.get(className);
-        if ((metaClass == null) || (!isLazy && metaClass.isLazy())) {
-            if (metaClass != null) {
-                metaClass.setIsLazy(false);
-            }
-            buildClassMetadata(metaClass, className, isLazy);
-            metaClass = m_metadataClasses.get(className);
-        }
-
-        return metaClass;
-    }
-
-    /**
-     * INTERNAL: This method resolves generic types based on the ASM class
-     * metadata. Unless every other factory (e.g. APT mirror factory) respects
-     * the generic format as built from ASM this method will not work since it
-     * is very tied to it.
-     */
-    @Override
-    public void resolveGenericTypes(MetadataClass child, List<String> genericTypes, MetadataClass parent, MetadataDescriptor descriptor) {
-        // If we have a generic parent we need to grab our generic types
-        // that may be used (and therefore need to be resolved) to map
-        // accessors correctly.
-        if (genericTypes != null) {
-            // The generic types provided map to its parents generic types. The
-            // generics also include the superclass, and interfaces. The parent
-            // generics include the type and ":" and class.
-
-            List<String> parentGenericTypes = parent.getGenericType();
-            if (parentGenericTypes != null) {
-                List genericParentTemp = new ArrayList(genericTypes);
-                genericParentTemp.removeAll(child.getInterfaces());
-
-                int size = genericParentTemp.size();
-                int parentIndex = 0;
-
-                for (int index = genericTypes.indexOf(parent.getName()) + 1; index < size; index++) {
-                    String actualTypeArgument = genericTypes.get(index);
-                    // Ignore extra types on the end of the child, such as
-                    // interface generics.
-                    if (parentIndex >= parentGenericTypes.size()) {
-                        break;
-                    }
-                    String variable = parentGenericTypes.get(parentIndex);
-
-                    // if we get as far as the superclass name in the parent generic type list,
-                    // there is nothing more to process.  We have processed all the generics in the type definition
-                    if (variable.equals(parent.getSuperclassName())){
-                        break;
-                    }
-                    parentIndex = parentIndex + 3;
-
-                    // We are building bottom up and need to link up any
-                    // TypeVariables with the actual class from the originating
-                    // entity.
-                    if (actualTypeArgument.length() == 1) {
-                        index++;
-                        actualTypeArgument = genericTypes.get(index);
-                        descriptor.addGenericType(variable, descriptor.getGenericType(actualTypeArgument));
-                    } else {
-                        descriptor.addGenericType(variable, actualTypeArgument);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Walk the class byte codes and collect the class info.
-     */
-    public class ClassMetadataVisitor extends ClassVisitor {
-
-        private boolean isLazy;
-        private boolean processedMemeber;
-        private MetadataClass classMetadata;
-
-        ClassMetadataVisitor(MetadataClass metadataClass, boolean isLazy) {
-            super(Opcodes.ASM7);
-            this.isLazy = isLazy;
-            this.classMetadata = metadataClass;
-        }
-
-        @Override
-        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
-            String className = toClassName(name);
-            if ((this.classMetadata == null) || !this.classMetadata.getName().equals(className)) {
-                this.classMetadata = new MetadataClass(MetadataAsmFactory.this, className, isLazy);
-                addMetadataClass(this.classMetadata);
-            }
-            this.classMetadata.setName(className);
-            this.classMetadata.setSuperclassName(toClassName(superName));
-            this.classMetadata.setModifiers(access);
-            this.classMetadata.setGenericType(processDescription(signature, true));
-
-            for (String interfaceName : interfaces) {
-                this.classMetadata.addInterface(toClassName(interfaceName));
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
-            this.processedMemeber = true;
-            if (this.classMetadata.isLazy()) {
-                return null;
-            }
-            return new MetadataFieldVisitor(this.classMetadata, access, name, desc, signature, value);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
-            this.processedMemeber = true;
-            if (this.classMetadata.isLazy() || name.indexOf("init>") != -1) {
-                return null;
-            }
-            return new MetadataMethodVisitor(this.classMetadata, access, name, signature, desc, exceptions);
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            boolean isJPA = false;
-            if (desc.startsWith("Lkotlin")) {
-                //ignore kotlin annotations
-                return null;
-            }
-            if (desc.startsWith("Ljava")) {
-                char c = desc.charAt(5);
-                //ignore annotations from 'java' namespace
-                if (c == '/') {
-                    return null;
-                }
-                //ignore annotations from other then 'javax/persistence' namespace
-                if (desc.regionMatches(5, "x/", 0, 2)) {
-                    if (desc.regionMatches(7, "persistence", 0, "persistence".length())) {
-                        isJPA = true;
-                    } else {
-                        return null;
-                    }
-                }
-            }
-            if (desc.startsWith("Ljakarta")) {
-                //ignore annotations from other then 'jakarta/persistence' namespace
-                    if (desc.regionMatches(9, "persistence", 0, "persistence".length())) {
-                        isJPA = true;
-                    } else {
-                        return null;
-                    }
-            }
-            if (!this.processedMemeber && this.classMetadata.isLazy()) {
-                this.classMetadata.setIsLazy(false);
-            }
-            //this currently forbids us to use meta-annotations defined in EclipseLink packages
-            return new MetadataAnnotationVisitor(this.classMetadata, desc, isJPA || desc.startsWith("Lorg/eclipse/persistence"));
-        }
-
-    }
-
-    /**
-     * {@link AnnotationVisitor} used to process class, field , and method
-     * annotations populating a {@link MetadataAnnotation} and its nested state.
-     *
-     * @see MetadataAnnotationArrayVisitor for population of array attributes
-     */
-    class MetadataAnnotationVisitor extends AnnotationVisitor {
-
-        /**
-         * Element the annotation is being applied to. If this is null the
-         * {@link MetadataAnnotation} being constructed is a nested annotation
-         * and is already referenced from its parent.
-         */
-        private MetadataAnnotatedElement element;
-
-        /**
-         * {@link MetadataAnnotation} being populated
-         */
-        private MetadataAnnotation annotation;
-
-        MetadataAnnotationVisitor(MetadataAnnotatedElement element, String name) {
-            this(element, name, true);
-        }
-
-        MetadataAnnotationVisitor(MetadataAnnotatedElement element, String name, boolean isRegular) {
-            super(Opcodes.ASM7);
-            this.element = element;
-            this.annotation = new MetadataAnnotation();
-            this.annotation.setName(processDescription(name, false).get(0));
-            this.annotation.setIsMeta(!isRegular);
-        }
-
-        public MetadataAnnotationVisitor(MetadataAnnotation annotation) {
-            super(Opcodes.ASM7);
-            this.annotation = annotation;
-        }
-
-        @Override
-        public void visit(String name, Object value) {
-            this.annotation.addAttribute(name, annotationValue(null, value));
-        }
-
-        @Override
-        public void visitEnum(String name, String desc, String value) {
-            this.annotation.addAttribute(name, annotationValue(desc, value));
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String name, String desc) {
-            MetadataAnnotation mda = new MetadataAnnotation();
-            mda.setName(processDescription(desc, false).get(0));
-            this.annotation.addAttribute(name, mda);
-            return new MetadataAnnotationVisitor(mda);
-        }
-
-        @Override
-        public AnnotationVisitor visitArray(String name) {
-            return new MetadataAnnotationArrayVisitor(this.annotation, name);
-        }
-
-        @Override
-        public void visitEnd() {
-            if (this.element != null) {
-                if (this.annotation.isMeta()) {
-                    this.element.addMetaAnnotation(this.annotation);
-                } else {
-                    this.element.addAnnotation(this.annotation);
-                }
-            }
-        }
-    }
-
-    /**
-     * Specialized visitor to handle the population of arrays of annotation
-     * values.
-     */
-    class MetadataAnnotationArrayVisitor extends AnnotationVisitor {
-
-        private MetadataAnnotation annotation;
-
-        private String attributeName;
-
-        private List<Object> values;
-
-        public MetadataAnnotationArrayVisitor(MetadataAnnotation annotation, String name) {
-            super(Opcodes.ASM7);
-            this.annotation = annotation;
-            this.attributeName = name;
-            this.values = new ArrayList<Object>();
-        }
-
-        @Override
-        public void visit(String name, Object value) {
-            this.values.add(annotationValue(null, value));
-        }
-
-        @Override
-        public void visitEnum(String name, String desc, String value) {
-            this.values.add(annotationValue(desc, value));
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String name, String desc) {
-            MetadataAnnotation mda = new MetadataAnnotation();
-            mda.setName(processDescription(desc, false).get(0));
-            this.values.add(mda);
-            return new MetadataAnnotationVisitor(mda);
-        }
-
-        @Override
-        public void visitEnd() {
-            this.annotation.addAttribute(this.attributeName, this.values.toArray());
-        }
-    }
-
-    /**
-     * Factory for the creation of {@link MetadataField} handling basic type,
-     * generics, and annotations.
-     */
-    class MetadataFieldVisitor extends FieldVisitor {
-
-        private MetadataField field;
-
-        public MetadataFieldVisitor(MetadataClass classMetadata, int access, String name, String desc, String signature, Object value) {
-            super(Opcodes.ASM7);
-            this.field = new MetadataField(classMetadata);
-            this.field.setModifiers(access);
-            this.field.setName(name);
-            this.field.setAttributeName(name);
-            this.field.setGenericType(processDescription(signature, true));
-            this.field.setType(processDescription(desc, false).get(0));
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            if (desc.startsWith("Ljavax/persistence") || desc.startsWith("Ljakarta/persistence")
-                    || desc.startsWith("Lorg/eclipse/persistence")) {
-                return new MetadataAnnotationVisitor(this.field, desc);
-            }
-            return null;
-        }
-
-        @Override
-        public void visitEnd() {
-            this.field.getDeclaringClass().addField(this.field);
-        }
-    }
-
-    /**
-     * Factory for the creation of {@link MetadataMethod} handling basic type,
-     * generics, and annotations.
-     */
-    // Note: Subclassed EmptyListener to minimize signature requirements for
-    // ignored MethodVisitor API
-    class MetadataMethodVisitor extends MethodVisitor {
-
-        private MetadataMethod method;
-
-        public MetadataMethodVisitor(MetadataClass classMetadata, int access, String name, String desc, String signature, String[] exceptions) {
-            super(Opcodes.ASM7);
-            this.method = new MetadataMethod(MetadataAsmFactory.this, classMetadata);
-
-            this.method.setName(name);
-            this.method.setAttributeName(Helper.getAttributeNameFromMethodName(name));
-            this.method.setModifiers(access);
-
-            this.method.setGenericType(processDescription(desc, true));
-
-            List<String> argumentNames = processDescription(signature, false);
-            if (argumentNames != null && !argumentNames.isEmpty()) {
-                this.method.setReturnType(argumentNames.get(argumentNames.size() - 1));
-                argumentNames.remove(argumentNames.size() - 1);
-                this.method.setParameters(argumentNames);
-            }
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            if (desc.startsWith("Ljavax/persistence") || desc.startsWith("Ljakarta/persistence")
-                    || desc.startsWith("Lorg/eclipse/persistence")) {
-                return new MetadataAnnotationVisitor(this.method, desc);
-            }
-            return null;
-        }
-
-        /**
-         * At the end of visiting this method add it to the
-         * {@link MetadataClass} and handle duplicate method names by chaining
-         * them.
-         */
-        @Override
-        public void visitEnd() {
-            MetadataClass classMetadata = this.method.getMetadataClass();
-
-            MetadataMethod existing = classMetadata.getMethods().get(this.method.getName());
-            if (existing == null) {
-                classMetadata.getMethods().put(this.method.getName(), this.method);
-            } else {
-                // Handle methods with the same name.
-                while (existing.getNext() != null) {
-                    existing = existing.getNext();
-                }
-                existing.setNext(this.method);
-            }
-        }
-
-    }
-
-    /**
-     * Get MetadataClass for a class which can not be found
-     * @param className class which has not been found
-     * @return MetadataClass
-     */
-    private MetadataClass getVirtualMetadataClass(String className) {
-        // Some basic types can't be found, so can just be registered
-        // (i.e. arrays). Also, VIRTUAL classes may also not exist,
-        // therefore, tag the MetadataClass as loadable false. This will be
-        // used to determine if a class will be dynamically created or not.
-        MetadataClass metadataClass = new MetadataClass(this, className, false);
-        // If the class is a JDK class, then maybe there is a class loader
-        // issues,
-        // since it is a JDK class, just use reflection.
-        if ((className.length() > 5) && className.substring(0, 5).equals("java.")) {
-            try {
-                Class reflectClass = Class.forName(className);
-                if (reflectClass.getSuperclass() != null) {
-                    metadataClass.setSuperclassName(reflectClass.getSuperclass().getName());
-                }
-                for (Class reflectInterface : reflectClass.getInterfaces()) {
-                    metadataClass.addInterface(reflectInterface.getName());
-                }
-            } catch (Exception failed) {
-                SessionLog log = getLogger().getSession() != null
-                        ? getLogger().getSession().getSessionLog() : AbstractSessionLog.getLog();
-                if (log.shouldLog(SessionLog.FINE, SessionLog.METADATA)) {
-                    log.logThrowable(SessionLog.FINE, SessionLog.METADATA, failed);
-                }
-                metadataClass.setIsAccessible(false);
-            }
-        } else {
-            metadataClass.setIsAccessible(false);
-        }
-        return metadataClass;
-    }
-
-    /**
-     * Process the byte-code argument description and return the array of Java
-     * class names. i.e.
-     * "(Lorg/foo/Bar;Z)Ljava/lang/Boolean;"=>[org.foo.Bar,boolean
-     * ,java.lang.Boolean]
-     */
-    private static List<String> processDescription(String desc, boolean isGeneric) {
-        if (desc == null) {
-            return null;
-        }
-        List<String> arguments = new ArrayList<String>();
-        int index = 0;
-        int length = desc.length();
-        boolean isGenericTyped=false;
-        // PERF: Use char array to make char index faster (note this is a heavily optimized method, be very careful on changes)
-        char[] chars = desc.toCharArray();
-        while (index < length) {
-            char next = chars[index];
-            if (('(' != next) && (')' != next) && ('<' != next) && ('>' != next) && (';' != next)) {
-                if (next == 'L') {
-                    index++;
-                    int start = index;
-                    next = chars[index];
-                    while (('(' != next) && (')' != next) && ('<' != next) && ('>' != next) && (';' != next)) {
-                        index++;
-                        next = chars[index];
-                    }
-                    arguments.add(toClassName(desc.substring(start, index)));
-                    if(isGenericTyped) {
-                        isGenericTyped=false;
-                        if(next == '<') {
-                            int cnt = 1;
-                            while((cnt > 0) && (++index<desc.length())) {
-                               switch (desc.charAt(index)) {
-                                    case '<': cnt ++; break;
-                                    case '>': cnt --; break;
-                               }
-                            }
-                         }
-                     }
-                } else if (!isGeneric && (PRIMITIVES.indexOf(next) != -1)) {
-                    // Primitives.
-                    arguments.add(getPrimitiveName(next));
-                } else if (next == '[') {
-                    // Arrays.
-                    int start = index;
-                    index++;
-                    next = chars[index];
-                    // Nested arrays.
-                    while (next == '[') {
-                        index++;
-                        next = chars[index];
-                    }
-                    if (PRIMITIVES.indexOf(next) == -1) {
-                        while (next != ';') {
-                            index++;
-                            next = chars[index];
-                        }
-                        arguments.add(toClassName(desc.substring(start, index + 1)));
-                    } else {
-                        arguments.add(desc.substring(start, index + 1));
-                    }
-                } else {
-                    // Is a generic type variable.
-                    int start = index;
-                    int end = start;
-
-                    char myNext = next;
-
-                    while (':' != myNext && '(' != myNext && ')' != myNext && '<' != myNext && '>' != myNext && ';' != myNext && end < length - 1) {
-                        end++;
-                        myNext = chars[end];
-                    }
-
-                    if (myNext == ':') {
-                        arguments.add(desc.substring(start, end));
-                        isGenericTyped=true;
-                        index = end;
-                        arguments.add(":");
-                        if(desc.charAt(index+1)==':') {
-                            index ++;
-                        }
-                    } else if (myNext == ';' && next == 'T') {
-                        arguments.add(new String(new char[] { next }));
-                        arguments.add(desc.substring(start + 1, end));
-                        index = end - 1;
-                    } else {
-                        arguments.add(new String(new char[] { next }));
-                    }
-                }
-            }
-            index++;
-        }
-        return arguments;
-
-    }
-
-    /**
-     * Return the Java type name for the primitive code.
-     */
-    private static String getPrimitiveName(char primitive) {
-        if (primitive == 'V') {
-            return "void";
-        } else if (primitive == 'I') {
-            return "int";
-        } else if (primitive == 'Z') {
-            return "boolean";
-        } else if (primitive == 'J') {
-            return "long";
-        } else if (primitive == 'F') {
-            return "float";
-        } else if (primitive == 'D') {
-            return "double";
-        } else if (primitive == 'B') {
-            return "byte";
-        } else if (primitive == 'C') {
-            return "char";
-        } else if (primitive == 'S') {
-            return "short";
-        } else {
-            return new String(new char[] { primitive });
-        }
-    }
-
-    private static String toClassName(String classDescription) {
-        if (classDescription == null) {
-            return "void";
-        }
-        return classDescription.replace('/', '.');
-    }
-
-    /**
-     * Convert the annotation value into the value used in the meta model
-     */
-    private static Object annotationValue(String description, Object value) {
-        if (value instanceof Type) {
-            return ((Type) value).getClassName();
-        }
-        return value;
-    }
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/eclipse/persistence/internal/jpa/metadata/accessors/objects/MetadataClass.java b/jakarta/src/patch/java/org/eclipse/persistence/internal/jpa/metadata/accessors/objects/MetadataClass.java
deleted file mode 100644
index 0670e30..0000000
--- a/jakarta/src/patch/java/org/eclipse/persistence/internal/jpa/metadata/accessors/objects/MetadataClass.java
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- */
-
-// Contributors:
-//     Oracle - initial API and implementation from Oracle TopLink
-//     05/16/2008-1.0M8 Guy Pelletier
-//       - 218084: Implement metadata merging functionality between mapping files
-//     03/08/2010-2.1 Guy Pelletier
-//       - 303632: Add attribute-type for mapping attributes to EclipseLink-ORM
-//     05/04/2010-2.1 Guy Pelletier
-//       - 309373: Add parent class attribute to EclipseLink-ORM
-//     05/14/2010-2.1 Guy Pelletier
-//       - 253083: Add support for dynamic persistence using ORM.xml/eclipselink-orm.xml
-//     01/25/2011-2.3 Guy Pelletier
-//       - 333488: Serializable attribute being defaulted to a variable one to one mapping and causing exception
-//     07/16/2013-2.5.1 Guy Pelletier
-//       - 412384: Applying Converter for parameterized basic-type for joda-time's DateTime does not work
-package org.eclipse.persistence.internal.jpa.metadata.accessors.objects;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.persistence.internal.helper.Helper;
-import org.eclipse.persistence.internal.libraries.asm.Opcodes;
-
-/**
- * INTERNAL:
- * An object to hold onto a valid JPA decorated class.
- *
- * @author Guy Pelletier
- * @since TopLink 10.1.3/EJB 3.0 Preview
- */
-public class MetadataClass extends MetadataAnnotatedElement {
-    protected boolean m_isLazy;
-    protected boolean m_isAccessible;
-    protected boolean m_isPrimitive;
-    protected boolean m_isJDK;
-    protected int m_modifiers;
-
-    // Stores the implements interfaces of this class.
-    protected List<String> m_interfaces;
-
-    // Stores a list of enclosed classes found inside this metadata class.
-    // E.g. inner classes, enums etc.
-    protected List<MetadataClass> m_enclosedClasses;
-
-    // Store the classes field metadata, keyed by the field's name.
-    protected Map<String, MetadataField> m_fields;
-
-    // Store the classes method metadata, keyed by the method's name.
-    // Method's next is used if multiple method with the same name.
-    protected Map<String, MetadataMethod> m_methods;
-
-    protected MetadataClass m_superclass;
-    protected String m_superclassName;
-
-    /**
-     * Create the metadata class with the class name.
-     */
-    public MetadataClass(MetadataFactory factory, String name, boolean isLazy) {
-        super(factory);
-        setName(name);
-
-        // By default, set the type to be the same as the name. The canonical
-        // model generator relies on types which in most cases is the name, but
-        // the generator resolves generic types a little differently to
-        // correctly generate model classes.
-        setType(name);
-
-        m_isAccessible = true;
-        m_isLazy = isLazy;
-    }
-
-    /**
-     * Create the metadata class with the class name.
-     */
-    public MetadataClass(MetadataFactory factory, String name) {
-        this(factory, name, false);
-    }
-
-    /**
-     * Create the metadata class based on the class.
-     * Mainly used for primitive defaults.
-     */
-    public MetadataClass(MetadataFactory factory, Class cls) {
-        this(factory, cls.getName(), false);
-        m_isPrimitive = cls.isPrimitive();
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public void addEnclosedClass(MetadataClass enclosedClass) {
-        if (m_enclosedClasses == null) {
-            m_enclosedClasses = new ArrayList<MetadataClass>();
-        }
-
-        m_enclosedClasses.add(enclosedClass);
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public void addField(MetadataField field) {
-        if (m_fields == null) {
-            m_fields = new HashMap<String, MetadataField>();
-        }
-
-        m_fields.put(field.getName(), field);
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public void addInterface(String interfaceName) {
-        if (m_interfaces == null) {
-            m_interfaces = new ArrayList<String>();
-        }
-
-        m_interfaces.add(interfaceName);
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public void addMethod(MetadataMethod method) {
-        if (m_methods == null) {
-            m_methods = new HashMap<String, MetadataMethod>();
-        }
-
-        m_methods.put(method.getName(), method);
-    }
-
-    /**
-     * Allow comparison to Java classes and Metadata classes.
-     */
-    @Override
-    public boolean equals(Object object) {
-        if (object instanceof Class) {
-            if (getName() == null) {
-                // Void's name is null.
-                return ((Class)object).getName() == null;
-            }
-
-            return getName().equals(((Class)object).getName());
-        }
-
-        return super.equals(object);
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this class is or extends, or super class extends the class.
-     */
-    public boolean extendsClass(Class javaClass) {
-        return extendsClass(javaClass.getName());
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this class is or extends, or super class extends the class.
-     */
-    public boolean extendsClass(String className) {
-        if (getName() == null) {
-            return className == null;
-        }
-
-        if (getName().equals(className)) {
-            return true;
-        }
-
-        if (getSuperclassName() == null) {
-            return false;
-        }
-
-        if (getSuperclassName().equals(className)) {
-            return true;
-        }
-
-        return getSuperclass().extendsClass(className);
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this class is or extends, or super class extends the interface.
-     */
-    public boolean extendsInterface(Class javaClass) {
-        return extendsInterface(javaClass.getName());
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this class is or extends, or super class extends the interface.
-     */
-    public boolean extendsInterface(String className) {
-        if (getName() == null) {
-            return false;
-        }
-
-        if (getName().equals(className)) {
-            return true;
-        }
-
-        if (getInterfaces().contains(className)) {
-            return true;
-        }
-
-        for (String interfaceName : getInterfaces()) {
-            if (getMetadataClass(interfaceName).extendsInterface(className)) {
-                return true;
-            }
-        }
-
-        if (getSuperclassName() == null) {
-            return false;
-        }
-
-        return getSuperclass().extendsInterface(className);
-    }
-
-    /**
-     * INTERNAL:
-     * Return the list of classes defined within this metadata class. E.g.
-     * enums and inner classes.
-     */
-    public List<MetadataClass> getEnclosedClasses() {
-        if (m_enclosedClasses == null) {
-            m_enclosedClasses = new ArrayList<MetadataClass>();
-        }
-
-        return m_enclosedClasses;
-    }
-
-    /**
-     * INTERNAL:
-     * Return the field with the name.
-     * Search for any declared or inherited field.
-     */
-    public MetadataField getField(String name) {
-        return getField(name, true);
-    }
-
-    /**
-     * INTERNAL:
-     * Return the field with the name.
-     * Search for any declared or inherited field.
-     */
-    public MetadataField getField(String name, boolean checkSuperClass) {
-        MetadataField field = getFields().get(name);
-
-        if (checkSuperClass && (field == null) && (getSuperclassName() != null)) {
-            return getSuperclass().getField(name);
-        }
-
-        return field;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public Map<String, MetadataField> getFields() {
-        if (m_fields == null) {
-            m_fields = new HashMap<String, MetadataField>();
-
-            if (m_isLazy) {
-                m_factory.getMetadataClass(getName(), false);
-            }
-        }
-
-        return m_fields;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public List<String> getInterfaces() {
-        if (m_interfaces == null) {
-            m_interfaces = new ArrayList<String>();
-        }
-
-        return m_interfaces;
-    }
-
-    /**
-     * INTERNAL:
-     * Return the method with the name and no arguments.
-     */
-    protected MetadataMethod getMethod(String name) {
-        return getMethods().get(name);
-    }
-
-    /**
-     * INTERNAL:
-     * Return the method with the name and argument types.
-     */
-    public MetadataMethod getMethod(String name, Class[] arguments) {
-        List<String> argumentNames = new ArrayList<String>(arguments.length);
-
-        for (int index = 0; index < arguments.length; index++) {
-            argumentNames.add(arguments[index].getName());
-        }
-
-        return getMethod(name, argumentNames);
-    }
-
-    /**
-     * INTERNAL:
-     * Return the method with the name and argument types (class names).
-     */
-    public MetadataMethod getMethod(String name, List<String> arguments) {
-        return getMethod(name, arguments, true);
-    }
-
-    /**
-     * INTERNAL:
-     * Return the method with the name and argument types (class names).
-     */
-    public MetadataMethod getMethod(String name, List<String> arguments, boolean checkSuperClass) {
-        MetadataMethod method = getMethods().get(name);
-
-        while ((method != null) && !method.getParameters().equals(arguments)) {
-            method = method.getNext();
-        }
-
-        if (checkSuperClass && (method == null) && (getSuperclassName() != null)) {
-            return getSuperclass().getMethod(name, arguments);
-        }
-
-        return method;
-    }
-
-    /**
-     * INTERNAL:
-     * Return the method with the name and argument types (class names).
-     */
-    public MetadataMethod getMethod(String name, String[] arguments) {
-        return getMethod(name, Arrays.asList(arguments));
-    }
-
-    /**
-     * INTERNAL:
-     * Return the method for the given property name.
-     */
-    public MetadataMethod getMethodForPropertyName(String propertyName) {
-        MetadataMethod method;
-
-        String leadingChar = String.valueOf(propertyName.charAt(0)).toUpperCase();
-        String restOfName = propertyName.substring(1);
-
-        // Look for a getPropertyName() method
-        method = getMethod(Helper.GET_PROPERTY_METHOD_PREFIX.concat(leadingChar).concat(restOfName), new String[]{});
-
-        if (method == null) {
-            // Look for an isPropertyName() method
-            method = getMethod(Helper.IS_PROPERTY_METHOD_PREFIX.concat(leadingChar).concat(restOfName), new String[]{});
-        }
-
-        if (method != null) {
-            method.setSetMethod(method.getSetMethod(this));
-        }
-
-        return method;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public Map<String, MetadataMethod> getMethods() {
-        if (m_methods == null) {
-            m_methods = new HashMap<String, MetadataMethod>();
-
-            if (m_isLazy) {
-                m_factory.getMetadataClass(getName(), false);
-            }
-        }
-        return m_methods;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    @Override
-    public int getModifiers() {
-        return m_modifiers;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public MetadataClass getSuperclass() {
-        if (m_superclass == null) {
-            m_superclass = getMetadataClass(m_superclassName);
-        }
-
-        return m_superclass;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public String getSuperclassName() {
-        return m_superclassName;
-    }
-
-    /**
-     * Return the ASM type name.
-     */
-    public String getTypeName() {
-        if (isArray()) {
-            return getName().replace('.', '/');
-        } else if (isPrimitive()) {
-            if (getName().equals("int")) {
-                return "I";
-            } else if (getName().equals("long")) {
-                return "J";
-            } else if (getName().equals("short")) {
-                return "S";
-            } else if (getName().equals("boolean")) {
-                return "Z";
-            } else if (getName().equals("float")) {
-                return "F";
-            } else if (getName().equals("double")) {
-                return "D";
-            } else if (getName().equals("char")) {
-                return "C";
-            } else if (getName().equals("byte")) {
-                return "B";
-            }
-        }
-        return "L" + getName().replace('.', '/') + ";";
-    }
-
-    /**
-     * INTERNAL:
-     * Return true is this class accessible to be found.
-     */
-    public boolean isAccessible() {
-        return m_isAccessible;
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this class is an array type.
-     */
-    public boolean isArray() {
-        return (getName() != null) && (getName().charAt(0) == '[');
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this is extends Collection.
-     */
-    public boolean isCollection() {
-        return extendsInterface(Collection.class);
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this is extends Enum.
-     */
-    public boolean isEnum() {
-        return extendsClass(Enum.class);
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this is an interface (super is null).
-     */
-    public boolean isInterface() {
-        return (Opcodes.ACC_INTERFACE & m_modifiers) != 0;
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this is a JDK (java/javax) class.
-     */
-    public boolean isJDK() {
-        return m_isJDK;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public boolean isLazy() {
-        return m_isLazy;
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this is extends List.
-     */
-    public boolean isList() {
-        return extendsInterface(List.class);
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this is extends Map.
-     */
-    public boolean isMap() {
-        return extendsInterface(Map.class);
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this is Object class.
-     */
-    public boolean isObject() {
-        return getName().equals(Object.class.getName());
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this is a primitive.
-     */
-    public boolean isPrimitive() {
-        return m_isPrimitive;
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this class extends Serializable or is an array type.
-     */
-    public boolean isSerializable() {
-        if (isArray()) {
-            return true;
-        }
-
-        return extendsInterface(Serializable.class);
-    }
-
-    /**
-     * INTENAL:
-     * Return true is this class is the Serializable.class interface.
-     */
-    public boolean isSerializableInterface() {
-        return getName().equals(Serializable.class.getName());
-    }
-
-    /**
-     * INTERNAL:
-     * Return true if this extends Set.
-     */
-    public boolean isSet() {
-        return extendsInterface(Set.class);
-    }
-
-    /**
-     * INTERNAL:
-     * Return if this is the void class.
-     */
-    public boolean isVoid() {
-        return getName().equals(void.class.getName()) || getName().equals(Void.class.getName());
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public void setIsAccessible(boolean isAccessible) {
-        m_isAccessible = isAccessible;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public void setIsJDK(boolean isJDK) {
-        m_isJDK = isJDK;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public void setIsLazy(boolean isLazy) {
-        m_isLazy = isLazy;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    @Override
-    public void setModifiers(int modifiers) {
-        m_modifiers = modifiers;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    @Override
-    public void setName(String name) {
-        super.setName(name);
-
-        if ((!MetadataFactory.ALLOW_JDK) && (name.startsWith("java.")
-                || name.startsWith("javax.") || name.startsWith("jakarta.")
-                || name.startsWith("org.eclipse.persistence.internal."))) {
-            setIsJDK(true);
-        }
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public void setSuperclass(MetadataClass superclass) {
-        m_superclass = superclass;
-    }
-
-    /**
-     * INTERNAL:
-     */
-    public void setSuperclassName(String superclass) {
-        m_superclassName = superclass;
-    }
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/eclipse/persistence/jaxb/javamodel/Helper.java b/jakarta/src/patch/java/org/eclipse/persistence/jaxb/javamodel/Helper.java
deleted file mode 100644
index a8318eb..0000000
--- a/jakarta/src/patch/java/org/eclipse/persistence/jaxb/javamodel/Helper.java
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- */
-
-// Contributors:
-//     Oracle - initial API and implementation from Oracle TopLink
-package org.eclipse.persistence.jaxb.javamodel;
-
-import static org.eclipse.persistence.jaxb.JAXBContextFactory.PKG_SEPARATOR;
-import static org.eclipse.persistence.jaxb.compiler.XMLProcessor.DEFAULT;
-
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
-
-import jakarta.xml.bind.JAXBElement;
-
-import org.eclipse.persistence.internal.oxm.Constants;
-
-/**
- * INTERNAL:
- * <p><b>Purpose:</b>To provide helper methods and constants to assist
- * in integrating TopLink JAXB 2.0 Generation with the JDEV JOT APIs.
- * <p><b>Responsibilities:</b>
- * <ul>
- * <li>Make available a map of JOT - XML type pairs</li>
- * <li>Redirect method calls to the current JavaModel implementation as
- * required</li>
- * <li>Provide methods for accessing generics, annotations, etc. on a
- * given implementaiton's classes</li>
- * <li>Provide a dynamic proxy instance for a given JavaAnnotation in
- * the JOT implementation (for reflection a Java SDK annotation is
- * returned)</li>
- * </ul>
- *
- * @since Oracle TopLink 11.1.1.0.0
- * @see JavaModel
- * @see AnnotationProxy
- *
- */
-public class Helper {
-    protected ClassLoader loader;
-    protected JavaModel jModel;
-    private HashMap xmlToJavaTypeMap;
-    private boolean facets;
-
-    public final static String APBYTE = "byte[]";
-    public final static String BIGDECIMAL = "java.math.BigDecimal";
-    public final static String BIGINTEGER = "java.math.BigInteger";
-    public final static String PBOOLEAN = "boolean";
-    public final static String PBYTE = "byte";
-    public final static String CALENDAR = "java.util.Calendar";
-    public final static String CHARACTER = "java.lang.Character";
-    public final static String CHAR = "char";
-    public final static String OBJECT = "java.lang.Object";
-    public final static String CLASS = "java.lang.Class";
-    public final static String PDOUBLE = "double";
-    public final static String PFLOAT = "float";
-    public final static String PINT = "int";
-    public final static String PLONG = "long";
-    public final static String PSHORT = "short";
-    public final static String QNAME_CLASS = "javax.xml.namespace.QName";
-    public final static String STRING = "java.lang.String";
-    public final static String ABYTE = "java.lang.Byte[]";
-    public final static String BOOLEAN = "java.lang.Boolean";
-    public final static String BYTE = "java.lang.Byte";
-    public final static String GREGORIAN_CALENDAR = "java.util.GregorianCalendar";
-    public final static String DOUBLE = "java.lang.Double";
-    public final static String FLOAT = "java.lang.Float";
-    public final static String INTEGER = "java.lang.Integer";
-    public final static String UUID = "java.util.UUID";
-    public final static String LONG = "java.lang.Long";
-    public final static String SHORT = "java.lang.Short";
-    public final static String UTIL_DATE = "java.util.Date";
-    public final static String SQL_DATE = "java.sql.Date";
-    public final static String SQL_TIME = "java.sql.Time";
-    public final static String SQL_TIMESTAMP = "java.sql.Timestamp";
-    public final static String DURATION = "javax.xml.datatype.Duration";
-    public final static String XMLGREGORIANCALENDAR = "javax.xml.datatype.XMLGregorianCalendar";
-    public final static String URI = "java.net.URI";
-    public final static String URL = "java.net.URL";
-    protected final static String JAVA_PKG = "java.";
-    protected final static String JAVAX_PKG = "javax.";
-    protected final static String JAKARTA_PKG = "jakarta.";
-    protected final static String JAVAX_WS_PKG = "javax.xml.ws.";
-    protected final static String JAKARTA_WS_PKG = "jakarta.xml.ws.";
-    protected final static String JAVAX_RPC_PKG = "javax.xml.rpc.";
-    protected final static String JAKARTA_RPC_PKG = "jakarta.xml.rpc.";
-
-    private JavaClass collectionClass;
-    private JavaClass setClass;
-    private JavaClass listClass;
-    private JavaClass mapClass;
-    private JavaClass jaxbElementClass;
-    private JavaClass objectClass;
-
-    /**
-     * INTERNAL:
-     * This is the preferred constructor.
-     *
-     * This constructor builds the map of XML-Java type pairs,
-     * and sets the JavaModel and ClassLoader.
-     *
-     * @param model
-     */
-    public Helper(JavaModel model) {
-        xmlToJavaTypeMap = buildXMLToJavaTypeMap();
-        setJavaModel(model);
-        setClassLoader(model.getClassLoader());
-        collectionClass = getJavaClass(CoreClassConstants.Collection_Class);
-        listClass = getJavaClass(CoreClassConstants.List_Class);
-        setClass = getJavaClass(CoreClassConstants.Set_Class);
-        mapClass = getJavaClass(CoreClassConstants.Map_Class);
-        jaxbElementClass = getJavaClass(JAXBElement.class);
-        objectClass = getJavaClass(CoreClassConstants.OBJECT);
-    }
-
-    /**
-     * Builds a map of Java types to XML types.
-     *
-     * @return
-     */
-    private HashMap buildXMLToJavaTypeMap() {
-        HashMap javaTypes = new HashMap();
-        // jaxb 2.0 spec pairs
-        javaTypes.put(APBYTE, Constants.BASE_64_BINARY_QNAME);
-        javaTypes.put(BIGDECIMAL, Constants.DECIMAL_QNAME);
-        javaTypes.put(BIGINTEGER, Constants.INTEGER_QNAME);
-        javaTypes.put(PBOOLEAN, Constants.BOOLEAN_QNAME);
-        javaTypes.put(PBYTE, Constants.BYTE_QNAME);
-        javaTypes.put(CALENDAR, Constants.DATE_TIME_QNAME);
-        javaTypes.put(PDOUBLE, Constants.DOUBLE_QNAME);
-        javaTypes.put(PFLOAT, Constants.FLOAT_QNAME);
-        javaTypes.put(PINT, Constants.INT_QNAME);
-        javaTypes.put(PLONG, Constants.LONG_QNAME);
-        javaTypes.put(PSHORT, Constants.SHORT_QNAME);
-        javaTypes.put(QNAME_CLASS, Constants.QNAME_QNAME);
-        javaTypes.put(STRING, Constants.STRING_QNAME);
-        javaTypes.put(CHAR, Constants.STRING_QNAME);
-        javaTypes.put(CHARACTER, Constants.STRING_QNAME);
-        // other pairs
-        javaTypes.put(ABYTE, Constants.BYTE_QNAME);
-        javaTypes.put(BOOLEAN, Constants.BOOLEAN_QNAME);
-        javaTypes.put(BYTE, Constants.BYTE_QNAME);
-        javaTypes.put(CLASS, Constants.STRING_QNAME);
-        javaTypes.put(GREGORIAN_CALENDAR, Constants.DATE_TIME_QNAME);
-        javaTypes.put(DOUBLE, Constants.DOUBLE_QNAME);
-        javaTypes.put(FLOAT, Constants.FLOAT_QNAME);
-        javaTypes.put(INTEGER, Constants.INT_QNAME);
-        javaTypes.put(LONG, Constants.LONG_QNAME);
-        javaTypes.put(OBJECT, Constants.ANY_TYPE_QNAME);
-        javaTypes.put(SHORT, Constants.SHORT_QNAME);
-        javaTypes.put(UTIL_DATE, Constants.DATE_TIME_QNAME);
-        javaTypes.put(SQL_DATE, Constants.DATE_QNAME);
-        javaTypes.put(SQL_TIME, Constants.TIME_QNAME);
-        javaTypes.put(SQL_TIMESTAMP, Constants.DATE_TIME_QNAME);
-        javaTypes.put(DURATION, Constants.DURATION_QNAME);
-        javaTypes.put(UUID, Constants.STRING_QNAME);
-        javaTypes.put(URI, Constants.STRING_QNAME);
-        javaTypes.put(URL, Constants.ANY_URI_QNAME);
-        return javaTypes;
-    }
-
-    /**
-     * Return a given method's generic return type as a JavaClass.
-     *
-     * @param meth
-     * @return
-     */
-    public JavaClass getGenericReturnType(JavaMethod meth) {
-        JavaClass result = meth.getReturnType();
-        JavaClass jClass = null;
-        if (result == null) { return null; }
-
-        Collection args = result.getActualTypeArguments();
-        if (args.size() >0) {
-            jClass = (JavaClass) args.iterator().next();
-        }
-        return jClass;
-    }
-
-    /**
-     * Return a JavaClass instance created based the provided class.
-     * This assumes that the provided class exists on the classpath
-     * - null is returned otherwise.
-     *
-     * @param javaClass
-     * @return
-     */
-    public JavaClass getJavaClass(Class javaClass) {
-        return jModel.getClass(javaClass);
-    }
-
-    /**
-     * Return array of JavaClass instances created based on the provided classes.
-     * This assumes provided classes exist on the classpath.
-     *
-     * @param classes
-     * @return JavaClass array
-     */
-    public JavaClass[] getJavaClassArray(Class... classes) {
-        if (0 == classes.length) {
-            return new JavaClass[0];
-        }
-        JavaClass[] result = new JavaClass[classes.length];
-        int i = 0;
-        for (Class clazz : classes) {
-            result[i++] = getJavaClass(clazz);
-        }
-        return result;
-    }
-
-    /**
-     * Return a JavaClass instance created based on fully qualified
-     * class name.  This assumes that a class with the provided name
-     * exists on the classpath - null is returned otherwise.
-     *
-     * @param javaClassName
-     * @return
-     */
-    public JavaClass getJavaClass(String javaClassName) {
-        return jModel.getClass(javaClassName);
-    }
-
-    /**
-     * Return a map of default Java types to XML types.
-     * @return
-     */
-    public HashMap getXMLToJavaTypeMap() {
-        return xmlToJavaTypeMap;
-    }
-
-    /**
-     * Returns a either a dynamic proxy instance that allows an element
-     * to be treated as an annotation (for JOT), or a Java annotation
-     * (for Reflection), or null if the specified annotation does not
-     * exist.
-     * Intended to be used in conjunction with isAnnotationPresent.
-     *
-     * @param element
-     * @param annotationClass
-     * @return
-     * @see #isAnnotationPresent
-     */
-    public Annotation getAnnotation(JavaHasAnnotations element, Class annotationClass) {
-        JavaAnnotation janno = element.getAnnotation(jModel.getClass(annotationClass));
-        if (janno == null) {
-            return null;
-        }
-        return jModel.getAnnotation(janno, annotationClass);
-    }
-
-    /**
-     * Returns a JavaClass instance wrapping the provided field's resolved
-     * type.
-     *
-     * @param field
-     * @return
-     */
-    public JavaClass getType(JavaField field) {
-        JavaClass type = field.getResolvedType();
-        try {
-            return jModel.getClass(type.getRawName());
-        } catch (Exception x) {}
-        return null;
-    }
-
-    /**
-     * Return a JavaClass instance based on the @see jakarta.xml.bind.JAXBElement .
-     *
-     * Replacement of direct access to JAXBELEMENT_CLASS field.
-     *
-     * @return
-     */
-    public JavaClass getJaxbElementClass() {
-        return jaxbElementClass;
-    }
-
-    /**
-     * Return a JavaClass instance based on the @see java.lang.Object .
-     *
-     * Replacement of direct access to OBJECT_CLASS field.
-     *
-     * @return
-     */
-    public JavaClass getObjectClass() {
-        return objectClass;
-    }
-
-    /**
-     * Indicates if element contains a given annotation.
-     *
-     * @param element
-     * @param annotationClass
-     * @return
-     */
-    public boolean isAnnotationPresent(JavaHasAnnotations element, Class annotationClass) {
-        if (element == null || annotationClass == null) {
-            return false;
-        }
-        return (element.getAnnotation(jModel.getClass(annotationClass)) != null);
-    }
-
-    /**
-     * Indicates if a given JavaClass is a built-in Java type.
-     *
-     * A JavaClass is considered to be a built-in type if:
-     * 1 - the XMLToJavaTypeMap map contains a key equal to the provided
-     *     JavaClass' raw name
-     * 2 - the provided JavaClass' raw name starts with "java."
-     * 3 - the provided JavaClass' raw name starts with "javax.", with
-     *     the exception of "jakarta.xml.ws." and "javax.xml.rpc"
-     * @param jClass
-     * @return
-     */
-    public boolean isBuiltInJavaType(JavaClass jClass) {
-        String rawName = jClass.getRawName();
-        if(null == rawName) {
-            return true;
-        }
-        return (getXMLToJavaTypeMap().containsKey(rawName) || rawName.startsWith(JAVA_PKG) || ((rawName.startsWith(JAVAX_PKG) || rawName.startsWith(JAKARTA_PKG)) && !(
-                rawName.startsWith(JAVAX_WS_PKG) ||
-                rawName.startsWith(JAVAX_RPC_PKG) ||
-                rawName.startsWith(JAKARTA_WS_PKG) ||
-                rawName.startsWith(JAKARTA_RPC_PKG)
-        )));
-    }
-
-    public void setClassLoader(ClassLoader loader) {
-        this.loader = loader;
-    }
-
-    public void setJavaModel(JavaModel model) {
-        jModel = model;
-    }
-    public ClassLoader getClassLoader() {
-        return loader;
-    }
-
-    public Class getClassForJavaClass(JavaClass javaClass){
-        String javaClassName = javaClass.getRawName();
-        if (javaClass.isPrimitive() || javaClass.isArray() && javaClass.getComponentType().isPrimitive()){
-            if (CoreClassConstants.APBYTE.getCanonicalName().equals(javaClassName)){
-                return Byte[].class;
-            }
-            if (CoreClassConstants.PBYTE.getCanonicalName().equals(javaClassName)){
-                return Byte.class;
-            }
-            if (CoreClassConstants.PBOOLEAN.getCanonicalName().equals(javaClassName)){
-                return Boolean.class;
-            }
-            if (CoreClassConstants.PSHORT.getCanonicalName().equals(javaClassName)){
-                return Short.class;
-            }
-            if (CoreClassConstants.PFLOAT.getCanonicalName().equals(javaClassName)){
-                return Float.class;
-            }
-            if (CoreClassConstants.PCHAR.getCanonicalName().equals(javaClassName)){
-                return Character.class;
-            }
-            if (CoreClassConstants.PDOUBLE.getCanonicalName().equals(javaClassName)){
-                return Double.class;
-            }
-            if (CoreClassConstants.PINT.getCanonicalName().equals(javaClassName)){
-                return Integer.class;
-            }
-            if (CoreClassConstants.PLONG.getCanonicalName().equals(javaClassName)){
-                return Long.class;
-            }
-            return null;
-        }
-        return org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(javaClass.getQualifiedName(), loader);
-    }
-
-    /**
-     * Convenience method to determine if a class exists in a given ArrayList.
-     */
-    public boolean classExistsInArray(JavaClass theClass, List<JavaClass> existingClasses) {
-        for (JavaClass jClass : existingClasses) {
-            if (areClassesEqual(jClass, theClass)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Convenience method to determine if two JavaClass instances are equal.
-     *
-     * @param classA
-     * @param classB
-     * @return
-     */
-    private boolean areClassesEqual(JavaClass classA, JavaClass classB) {
-        if (classA == classB) {
-            return true;
-        }
-        if (!(classA.getQualifiedName().equals(classB.getQualifiedName()))) {
-            return false;
-        }
-
-        Collection classAargs = classA.getActualTypeArguments();
-        Collection classBargs = classB.getActualTypeArguments();
-        if (classAargs != null) {
-            if (classBargs == null) {
-                return false;
-            }
-            if (classAargs.size() != classBargs.size()) {
-                return false;
-            }
-
-            Iterator classAargsIter = classAargs.iterator();
-            Iterator classBargsIter = classBargs.iterator();
-
-            while(classAargsIter.hasNext()){
-                JavaClass nestedClassA = (JavaClass) classAargsIter.next();
-                JavaClass nestedClassB = (JavaClass) classBargsIter.next();
-                if (!areClassesEqual(nestedClassA, nestedClassB)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        if (classBargs == null) {
-            return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * Prepends a package name to a given java type name, if it is not already present.
-     *
-     * @param javaTypeName Java type name that may/may not contain 'packageName'
-     * @param packageName package name to prepend to javaTypeName if not already
-     * @return fully qualified java type name
-     */
-    public static String getQualifiedJavaTypeName(String javaTypeName, String packageName) {
-        // prepend the package name if not already present
-        if (packageName != null && packageName.length() > 0 && !packageName.equals(DEFAULT) && !javaTypeName.contains(PKG_SEPARATOR)) {
-            return packageName + PKG_SEPARATOR + javaTypeName;
-        }
-        return javaTypeName;
-    }
-
-    public boolean isCollectionType(JavaClass type) {
-     if (collectionClass.isAssignableFrom(type)
-             || listClass.isAssignableFrom(type)
-             || setClass.isAssignableFrom(type)) {
-             return true;
-         }
-         return false;
-    }
-
-    public boolean isMapType(JavaClass type) {
-        return mapClass.isAssignableFrom(type);
-    }
-
-    public boolean isFacets() {
-        return facets;
-    }
-
-    public void setFacets(boolean facets) {
-        this.facets = facets;
-    }
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/eclipse/persistence/jaxb/javamodel/reflection/JavaClassImpl.java b/jakarta/src/patch/java/org/eclipse/persistence/jaxb/javamodel/reflection/JavaClassImpl.java
deleted file mode 100644
index a1c74ba..0000000
--- a/jakarta/src/patch/java/org/eclipse/persistence/jaxb/javamodel/reflection/JavaClassImpl.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- */
-
-// Contributors:
-//     Oracle - initial API and implementation from Oracle TopLink
-package org.eclipse.persistence.jaxb.javamodel.reflection;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.eclipse.persistence.exceptions.JAXBException;
-import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
-import org.eclipse.persistence.jaxb.javamodel.JavaAnnotation;
-import org.eclipse.persistence.jaxb.javamodel.JavaClass;
-import org.eclipse.persistence.jaxb.javamodel.JavaClassInstanceOf;
-import org.eclipse.persistence.jaxb.javamodel.JavaConstructor;
-import org.eclipse.persistence.jaxb.javamodel.JavaField;
-import org.eclipse.persistence.jaxb.javamodel.JavaMethod;
-import org.eclipse.persistence.jaxb.javamodel.JavaPackage;
-
-/**
- * INTERNAL:
- * <p><b>Purpose:</b>A wrapper class for a JDK Class.  This implementation
- * of the EclipseLink JAXB 2.X Java model simply makes reflective calls on the
- * underlying JDK object.
- *
- * <p><b>Responsibilities:</b>
- * <ul>
- * <li>Provide access to the underlying JDK Class' name, package,
- * method/field names and parameters, annotations, etc.</li>
- * </ul>
- *
- * @since Oracle TopLink 11.1.1.0.0
- * @see org.eclipse.persistence.jaxb.javamodel.JavaClass
- * @see java.lang.Class
- */
-public class JavaClassImpl implements JavaClass {
-
-    protected ParameterizedType jType;
-    protected Class jClass;
-    protected JavaModelImpl javaModelImpl;
-    protected boolean isMetadataComplete;
-    protected JavaClass superClassOverride;
-
-    protected static final String XML_REGISTRY_CLASS_NAME = "jakarta.xml.bind.annotation.XmlRegistry";
-
-    public JavaClassImpl(Class javaClass, JavaModelImpl javaModelImpl) {
-        this.jClass = javaClass;
-        this.javaModelImpl = javaModelImpl;
-        isMetadataComplete = false;
-    }
-
-    public JavaClassImpl(ParameterizedType javaType, Class javaClass, JavaModelImpl javaModelImpl) {
-        this.jType = javaType;
-        this.jClass = javaClass;
-        this.javaModelImpl = javaModelImpl;
-        isMetadataComplete = false;
-    }
-
-    public void setJavaModelImpl(JavaModelImpl javaModel) {
-        this.javaModelImpl = javaModel;
-    }
-    public Collection getActualTypeArguments() {
-        ArrayList<JavaClass> argCollection = new ArrayList<JavaClass>();
-        if (jType != null) {
-            Type[] params = jType.getActualTypeArguments();
-            for (Type type : params) {
-                if (type instanceof ParameterizedType) {
-                    ParameterizedType pt = (ParameterizedType) type;
-                    argCollection.add(new JavaClassImpl(pt, (Class) pt.getRawType(), javaModelImpl));
-                } else if(type instanceof WildcardType){
-                    Type[] upperTypes = ((WildcardType)type).getUpperBounds();
-                    if(upperTypes.length >0){
-                        Type upperType = upperTypes[0];
-                        if(upperType instanceof Class){
-                            argCollection.add(javaModelImpl.getClass((Class) upperType));
-                        }
-                    }
-                } else if (type instanceof Class) {
-                    argCollection.add(javaModelImpl.getClass((Class) type));
-                } else if(type instanceof GenericArrayType) {
-                    Class genericTypeClass = (Class)((GenericArrayType)type).getGenericComponentType();
-                    genericTypeClass = java.lang.reflect.Array.newInstance(genericTypeClass, 0).getClass();
-                    argCollection.add(javaModelImpl.getClass(genericTypeClass));
-                } else if(type instanceof TypeVariable) {
-                    Type[] boundTypes = ((TypeVariable) type).getBounds();
-                    if(boundTypes.length > 0) {
-                        Type boundType = boundTypes[0];
-                        if(boundType instanceof Class) {
-                            argCollection.add(javaModelImpl.getClass((Class) boundType));
-                        }
-                    }
-                }
-            }
-        }
-        return argCollection;
-    }
-
-    public String toString() {
-        return getName();
-    }
-
-    /**
-     * Assumes JavaType is a JavaClassImpl instance
-     */
-    public JavaAnnotation getAnnotation(JavaClass arg0) {
-        // the only annotation we will return if isMetadataComplete == true is XmlRegistry
-        if (arg0 != null && (!isMetadataComplete || arg0.getQualifiedName().equals(XML_REGISTRY_CLASS_NAME))) {
-            Class annotationClass = ((JavaClassImpl) arg0).getJavaClass();
-            if (javaModelImpl.getAnnotationHelper().isAnnotationPresent(getAnnotatedElement(), annotationClass)) {
-                return new JavaAnnotationImpl(this.javaModelImpl.getAnnotationHelper().getAnnotation(getAnnotatedElement(), annotationClass));
-            }
-        }
-        return null;
-    }
-
-    public Collection<JavaAnnotation> getAnnotations() {
-        List<JavaAnnotation> annotationCollection = new ArrayList<JavaAnnotation>();
-        if (!isMetadataComplete) {
-            Annotation[] annotations = javaModelImpl.getAnnotationHelper().getAnnotations(getAnnotatedElement());
-            for (Annotation annotation : annotations) {
-                annotationCollection.add(new JavaAnnotationImpl(annotation));
-            }
-        }
-        return annotationCollection;
-    }
-
-    public Collection<JavaClass> getDeclaredClasses() {
-        List<JavaClass> classCollection = new ArrayList<JavaClass>();
-        Class[] classes = jClass.getDeclaredClasses();
-        for (Class javaClass : classes) {
-            classCollection.add(javaModelImpl.getClass(javaClass));
-        }
-        return classCollection;
-    }
-
-    public JavaField getDeclaredField(String arg0) {
-        try {
-            return getJavaField(jClass.getDeclaredField(arg0));
-        } catch (NoSuchFieldException nsfe) {
-            return null;
-        }
-    }
-
-    public Collection<JavaField> getDeclaredFields() {
-        List<JavaField> fieldCollection = new ArrayList<JavaField>();
-        Field[] fields = PrivilegedAccessHelper.getDeclaredFields(jClass);
-
-        for (Field field : fields) {
-            field.setAccessible(true);
-            fieldCollection.add(getJavaField(field));
-        }
-        return fieldCollection;
-    }
-
-    /**
-     * Assumes JavaType[] contains JavaClassImpl instances
-     */
-    public JavaMethod getDeclaredMethod(String arg0, JavaClass[] arg1) {
-        if (arg1 == null) {
-            arg1 = new JavaClass[0];
-        }
-        Class[] params = new Class[arg1.length];
-        for (int i=0; i<arg1.length; i++) {
-            JavaClass jType = arg1[i];
-            if (jType != null) {
-                params[i] = ((JavaClassImpl) jType).getJavaClass();
-            }
-        }
-        try {
-            return getJavaMethod(jClass.getDeclaredMethod(arg0, params));
-        } catch (NoSuchMethodException nsme) {
-            return null;
-        }
-    }
-
-    public Collection getDeclaredMethods() {
-        ArrayList<JavaMethod> methodCollection = new ArrayList<JavaMethod>();
-        Method[] methods = jClass.getDeclaredMethods();
-        for (Method method : methods) {
-            methodCollection.add(getJavaMethod(method));
-        }
-        return methodCollection;
-    }
-
-    public JavaConstructor getConstructor(JavaClass[] paramTypes) {
-        if (paramTypes == null) {
-            paramTypes = new JavaClass[0];
-        }
-        Class[] params = new Class[paramTypes.length];
-        for (int i=0; i<paramTypes.length; i++) {
-            JavaClass jType = paramTypes[i];
-            if (jType != null) {
-                params[i] = ((JavaClassImpl) jType).getJavaClass();
-            }
-        }
-        try {
-            Constructor constructor = PrivilegedAccessHelper.getConstructorFor(jClass, params, true);
-            return new JavaConstructorImpl(constructor, javaModelImpl);
-        } catch (NoSuchMethodException nsme) {
-            return null;
-        }
-    }
-
-    public JavaConstructor getDeclaredConstructor(JavaClass[] paramTypes) {
-        if (paramTypes == null) {
-            paramTypes = new JavaClass[0];
-        }
-        Class[] params = new Class[paramTypes.length];
-        for (int i=0; i<paramTypes.length; i++) {
-            JavaClass jType = paramTypes[i];
-            if (jType != null) {
-                params[i] = ((JavaClassImpl) jType).getJavaClass();
-            }
-        }
-        try {
-            return new JavaConstructorImpl(PrivilegedAccessHelper.getDeclaredConstructorFor(this.jClass, params, true), javaModelImpl);
-        } catch (NoSuchMethodException nsme) {
-            return null;
-        }
-    }
-
-    public Collection getConstructors() {
-        Constructor[] constructors = this.jClass.getConstructors();
-        ArrayList<JavaConstructor> constructorCollection = new ArrayList(constructors.length);
-        for(Constructor next:constructors) {
-            constructorCollection.add(new JavaConstructorImpl(next, javaModelImpl));
-        }
-        return constructorCollection;
-    }
-
-    public Collection getDeclaredConstructors() {
-        Constructor[] constructors = this.jClass.getDeclaredConstructors();
-        ArrayList<JavaConstructor> constructorCollection = new ArrayList(constructors.length);
-        for(Constructor next:constructors) {
-            constructorCollection.add(new JavaConstructorImpl(next, javaModelImpl));
-        }
-        return constructorCollection;
-    }
-
-    public JavaField getField(String arg0) {
-        try {
-            Field field = PrivilegedAccessHelper.getField(jClass, arg0, true);
-            return getJavaField(field);
-        } catch (NoSuchFieldException nsfe) {
-            return null;
-        }
-    }
-
-    public Collection getFields() {
-        ArrayList<JavaField> fieldCollection = new ArrayList<JavaField>();
-        Field[] fields = PrivilegedAccessHelper.getFields(jClass);
-        for (Field field : fields) {
-            fieldCollection.add(getJavaField(field));
-        }
-        return fieldCollection;
-    }
-
-    public Class getJavaClass() {
-        return jClass;
-    }
-
-    /**
-     * Assumes JavaType[] contains JavaClassImpl instances
-     */
-    public JavaMethod getMethod(String arg0, JavaClass[] arg1) {
-        if (arg1 == null) {
-            arg1 = new JavaClass[0];
-        }
-        Class[] params = new Class[arg1.length];
-        for (int i=0; i<arg1.length; i++) {
-            JavaClass jType = arg1[i];
-            if (jType != null) {
-                params[i] = ((JavaClassImpl) jType).getJavaClass();
-            }
-        }
-        try {
-            Method method = PrivilegedAccessHelper.getMethod(jClass, arg0, params, true);
-            return getJavaMethod(method);
-        } catch (NoSuchMethodException nsme) {
-            return null;
-        }
-    }
-
-    public Collection getMethods() {
-        ArrayList<JavaMethod> methodCollection = new ArrayList<JavaMethod>();
-        Method[] methods = PrivilegedAccessHelper.getMethods(jClass);
-        for (Method method : methods) {
-            methodCollection.add(getJavaMethod(method));
-        }
-        return methodCollection;
-    }
-
-    public String getName() {
-        return jClass.getName();
-    }
-
-    public JavaPackage getPackage() {
-        return new JavaPackageImpl(jClass.getPackage(), javaModelImpl, isMetadataComplete);
-    }
-
-    public String getPackageName() {
-        if(jClass.getPackage() != null){
-            return jClass.getPackage().getName();
-        }else{
-            Class nonInnerClass = jClass;
-            Class enclosingClass = jClass.getEnclosingClass();
-            while(enclosingClass != null){
-                nonInnerClass = enclosingClass;
-                enclosingClass = nonInnerClass.getEnclosingClass();
-            }
-            String className = nonInnerClass.getCanonicalName();
-            if(className !=null){
-                int index = className.lastIndexOf('.');
-                if(index > -1){
-                    return className.substring(0, index);
-                }
-            }
-        }
-        return null;
-    }
-
-    public String getQualifiedName() {
-        return jClass.getName();
-    }
-
-    public String getRawName() {
-        return jClass.getCanonicalName();
-    }
-
-    public JavaClass getSuperclass() {
-        if(this.superClassOverride != null) {
-            return this.superClassOverride;
-        }
-        if(jClass.isInterface()) {
-            Class[] superInterfaces = jClass.getInterfaces();
-            if(superInterfaces != null) {
-                if(superInterfaces.length == 1) {
-                    return javaModelImpl.getClass(superInterfaces[0]);
-                } else {
-                    Class parent = null;
-                    for(Class next:superInterfaces) {
-                        if(!(next.getName().startsWith("java.")
-                                || next.getName().startsWith("javax.")
-                                || next.getName().startsWith("jakarta."))) {
-                            if(parent == null) {
-                                parent = next;
-                            } else {
-                                throw JAXBException.invalidInterface(jClass.getName());
-                            }
-                        }
-                    }
-                    return javaModelImpl.getClass(parent);
-                }
-            }
-        }
-        return javaModelImpl.getClass(jClass.getSuperclass());
-    }
-
-    @Override
-    public Type[] getGenericInterfaces() {
-        return jClass.getGenericInterfaces();
-    }
-
-    public Type getGenericSuperclass() {
-        return jClass.getGenericSuperclass();
-    }
-
-    public boolean hasActualTypeArguments() {
-        return getActualTypeArguments().size() > 0;
-    }
-
-    public JavaField getJavaField(Field field) {
-        return new JavaFieldImpl(field, javaModelImpl, isMetadataComplete);
-    }
-
-    public JavaMethod getJavaMethod(Method method) {
-        return new JavaMethodImpl(method, javaModelImpl, isMetadataComplete);
-    }
-
-    public JavaClass getOwningClass() {
-        return javaModelImpl.getClass(jClass.getEnclosingClass());
-    }
-
-    public boolean isAnnotation() {
-        return jClass.isAnnotation();
-    }
-
-    public boolean isArray() {
-        return jClass.isArray();
-    }
-
-    public AnnotatedElement getAnnotatedElement() {
-        return jClass;
-    }
-
-    public boolean isAssignableFrom(JavaClass arg0) {
-        if (!(arg0 instanceof JavaClassImpl)) {
-            return false;
-        }
-        if(hasCustomSuperClass(arg0)) {
-            return this.customIsAssignableFrom(arg0);
-        }
-        return jClass.isAssignableFrom(((JavaClassImpl) arg0).getJavaClass());
-    }
-
-    private boolean customIsAssignableFrom(JavaClass arg0) {
-        JavaClassImpl jClass = (JavaClassImpl)arg0;
-        Class cls = jClass.getJavaClass();
-
-        if(cls == this.jClass) {
-            return true;
-        }
-        Class[] interfaces = cls.getInterfaces();
-        for(Class nextInterface:interfaces) {
-            if(nextInterface == this.jClass) {
-                return true;
-            }
-            if(customIsAssignableFrom(javaModelImpl.getClass(nextInterface))) {
-                return true;
-            }
-        }
-
-        if(!(jClass.isInterface())) {
-            JavaClassImpl superJavaClass = (JavaClassImpl)jClass.getSuperclass();
-            if(superJavaClass.getName().equals("java.lang.Object")) {
-                return this.jClass == superJavaClass.getJavaClass();
-            }
-            return customIsAssignableFrom(superJavaClass);
-        }
-        return false;
-    }
-
-    private boolean hasCustomSuperClass(JavaClass arg0) {
-        if(arg0 == null) {
-            return false;
-        }
-        if(!this.javaModelImpl.hasXmlBindings()) {
-            return false;
-        }
-        if(!(arg0.getClass() == this.getClass())) {
-            return false;
-        }
-        if(arg0.getName().equals("java.lang.Object")) {
-            return false;
-        }
-        JavaClassImpl jClass = (JavaClassImpl)arg0;
-        return jClass.getSuperClassOverride() != null || hasCustomSuperClass(jClass.getSuperclass());
-    }
-
-    public boolean isEnum() {
-        return jClass.isEnum();
-    }
-
-    public boolean isInterface() {
-        return jClass.isInterface();
-    }
-
-    public boolean isMemberClass() {
-        return jClass.isMemberClass();
-    }
-
-    public boolean isPrimitive() {
-        return jClass.isPrimitive();
-    }
-
-    public boolean isAbstract() {
-        return Modifier.isAbstract(getModifiers());
-    }
-
-    public boolean isPrivate() {
-        return Modifier.isPrivate(getModifiers());
-    }
-
-    public boolean isProtected() {
-        return Modifier.isProtected(getModifiers());
-    }
-
-    public boolean isPublic() {
-        return Modifier.isPublic(getModifiers());
-    }
-
-    public boolean isStatic() {
-        return Modifier.isStatic(getModifiers());
-    }
-
-    public int getModifiers() {
-        return jClass.getModifiers();
-    }
-
-    public boolean isFinal() {
-        return Modifier.isFinal(getModifiers());
-    }
-
-    public boolean isSynthetic() {
-        return jClass.isSynthetic();
-    }
-
-    @Override
-    public JavaClassInstanceOf instanceOf() {
-        return JavaClassInstanceOf.JAVA_CLASS_IMPL;
-    }
-
-    public JavaClass getComponentType() {
-        if(!isArray()) {
-            return null;
-        }
-        return javaModelImpl.getClass(this.jClass.getComponentType());
-    }
-
-    public JavaClass getSuperClassOverride() {
-        return superClassOverride;
-    }
-
-    public void setSuperClassOverride(JavaClass superClassOverride) {
-        this.superClassOverride = superClassOverride;
-    }
-    /**
-     * Set the indicator for XML metadata complete - if true,
-     * annotations will be ignored.
-     *
-     * @param isMetadataComplete
-     */
-    void setIsMetadataComplete(Boolean isMetadataComplete) {
-       if(isMetadataComplete != null){
-            this.isMetadataComplete = isMetadataComplete;
-        }
-    }
-
-    public JavaAnnotation getDeclaredAnnotation(JavaClass arg0) {
-        // the only annotation we will return if isMetadataComplete == true is XmlRegistry
-        if (arg0 != null && (!isMetadataComplete || arg0.getQualifiedName().equals(XML_REGISTRY_CLASS_NAME))) {
-            Class annotationClass = ((JavaClassImpl) arg0).getJavaClass();
-            Annotation[] annotations = javaModelImpl.getAnnotationHelper().getDeclaredAnnotations(getAnnotatedElement());
-            for (Annotation annotation : annotations) {
-                if (annotation.annotationType().equals(annotationClass)) {
-                    return new JavaAnnotationImpl(annotation);
-                }
-            }
-        }
-        return null;
-    }
-
-    public Collection getDeclaredAnnotations() {
-        List<JavaAnnotation> annotationCollection = new ArrayList<JavaAnnotation>();
-        if (!isMetadataComplete) {
-            Annotation[] annotations = javaModelImpl.getAnnotationHelper().getDeclaredAnnotations(getAnnotatedElement());
-            for (Annotation annotation : annotations) {
-                annotationCollection.add(new JavaAnnotationImpl(annotation));
-            }
-        }
-        return annotationCollection;
-    }
-
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/eclipse/persistence/jaxb/rs/MOXyJsonProvider.java b/jakarta/src/patch/java/org/eclipse/persistence/jaxb/rs/MOXyJsonProvider.java
deleted file mode 100644
index 7bce14a..0000000
--- a/jakarta/src/patch/java/org/eclipse/persistence/jaxb/rs/MOXyJsonProvider.java
+++ /dev/null
@@ -1,986 +0,0 @@
-/*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- */
-
-// Contributors:
-//     Blaise Doughan - 2.4 - initial implementation
-package org.eclipse.persistence.jaxb.rs;
-
-import java.io.File;
-import java.io.IOException;
-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.Array;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.WildcardType;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.NavigableSet;
-import java.util.Queue;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import jakarta.activation.DataSource;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.WebApplicationException;
-import jakarta.ws.rs.core.Context;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.MultivaluedMap;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.Response.ResponseBuilder;
-import jakarta.ws.rs.core.Response.Status;
-import jakarta.ws.rs.core.StreamingOutput;
-import jakarta.ws.rs.ext.ContextResolver;
-import jakarta.ws.rs.ext.MessageBodyReader;
-import jakarta.ws.rs.ext.MessageBodyWriter;
-import jakarta.ws.rs.ext.Provider;
-import jakarta.ws.rs.ext.Providers;
-import jakarta.xml.bind.JAXBContext;
-import jakarta.xml.bind.JAXBElement;
-import jakarta.xml.bind.JAXBException;
-import jakarta.xml.bind.JAXBIntrospector;
-import jakarta.xml.bind.Marshaller;
-import jakarta.xml.bind.UnmarshalException;
-import jakarta.xml.bind.Unmarshaller;
-import javax.xml.namespace.QName;
-import javax.xml.transform.stream.StreamSource;
-
-import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
-import org.eclipse.persistence.internal.helper.Helper;
-import org.eclipse.persistence.internal.oxm.Constants;
-import org.eclipse.persistence.internal.queries.CollectionContainerPolicy;
-import org.eclipse.persistence.internal.queries.ContainerPolicy;
-import org.eclipse.persistence.jaxb.JAXBContextFactory;
-import org.eclipse.persistence.jaxb.MarshallerProperties;
-import org.eclipse.persistence.jaxb.UnmarshallerProperties;
-import org.eclipse.persistence.logging.AbstractSessionLog;
-import org.eclipse.persistence.logging.SessionLog;
-import org.eclipse.persistence.oxm.JSONWithPadding;
-
-/**
- * <p>This is an implementation of <i>MessageBodyReader</i>/<i>MessageBodyWriter
- * </i> that can be used to enable EclipseLink JAXB (MOXy) as the JSON
- * provider.</p>
- * <p>
- * <b>Supported Media Type Patterns</b>
- * <ul>
- * <li>*&#47;json (i.e. application/json and text/json)</li>
- * <li>*&#47;*+json</li>
- * </ul>
- *
- * <p>Below are some different usage options.</p>
- *
- * <b>Option #1 - <i>MOXyJsonProvider</i> Default Behavior</b>
- * <p>You can use the <i>Application</i> class to specify that
- * <i>MOXyJsonProvider</i> should be used with your JAX-RS application.</p>
- * <pre>
- * package org.example;
-
- * import java.util.*;
- * import javax.ws.rs.core.Application;
- * import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
- *
- * public class ExampleApplication  extends Application {
- *
- *     &#64;Override
- *     public Set&lt;Class&lt;?&gt;&gt; getClasses() {
- *         HashSet&lt;Class&lt;?&gt;&gt; set = new HashSet&lt;Class&lt;?&gt;&gt;(2);
- *         set.add(MOXyJsonProvider.class);
- *         set.add(ExampleService.class);
- *         return set;
- *     }
- *
- * }
- * </pre>
- *
- * <b>Option #2 - Customize <i>MOXyJsonProvider</i></b>
- * <p>You can use the <i>Application</i> class to specify a configured instance
- * of <i>MOXyJsonProvider</i> should be used with your JAX-RS application.</p>
- * <pre>
- * package org.example;
- *
- * import java.util.*;
- * import javax.ws.rs.core.Application;
- * import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
- *
- * public class CustomerApplication  extends Application {
- *
- *     &#64;Override
- *     public Set&lt;Class&lt;?&gt;&gt; getClasses() {
- *         HashSet&lt;Class&lt;?&gt;&gt; set = new HashSet&lt;Class&lt;?&gt;&gt;(1);
- *         set.add(ExampleService.class);
- *         return set;
- *     }
-
- *     &#64;Override
- *     public Set&lt;Object&gt; getSingletons() {
- *         moxyJsonProvider moxyJsonProvider = new MOXyJsonProvider();
- *         moxyJsonProvider.setFormattedOutput(true);
- *         moxyJsonProvider.setIncludeRoot(true);
- *
- *         HashSet&lt;Object&gt; set = new HashSet&lt;Object&gt;(2);
- *         set.add(moxyJsonProvider);
- *         return set;
- *     }
- *
- * }
- * </pre>
- * <b>Option #3 - Extend MOXyJsonProvider</b>
- * <p>You can use MOXyJsonProvider for creating your own
- * <i>MessageBodyReader</i>/<i>MessageBodyWriter</i>.</p>
- * <pre>
- * package org.example;
- *
- * import java.lang.annotation.Annotation;
- * import java.lang.reflect.Type;
- *
- * import javax.ws.rs.*;
- * import javax.ws.rs.core.*;
- * import javax.ws.rs.ext.Provider;
- * import javax.xml.bind.*;
- *
- * import org.eclipse.persistence.jaxb.MarshallerProperties;
- * import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
- *
- * &#64;Provider
- * &#64;Produces(MediaType.APPLICATION_JSON)
- * &#64;Consumes(MediaType.APPLICATION_JSON)
- * public class CustomerJSONProvider extends MOXyJsonProvider {
-
- *     &#64;Override
- *     public boolean isReadable(Class&lt;?&gt; type, Type genericType,
- *             Annotation[] annotations, MediaType mediaType) {
- *         return getDomainClass(genericType) == Customer.class;
- *     }
- *
- *     &#64;Override
- *     public boolean isWriteable(Class&lt;?&gt; type, Type genericType,
- *             Annotation[] annotations, MediaType mediaType) {
- *         return isReadable(type, genericType, annotations, mediaType);
- *     }
- *
- *     &#64;Override
- *     protected void preReadFrom(Class&lt;Object&gt; type, Type genericType,
- *             Annotation[] annotations, MediaType mediaType,
- *             MultivaluedMap&lt;String, String&gt; httpHeaders,
- *             Unmarshaller unmarshaller) throws JAXBException {
- *         unmarshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER, "$");
- *     }
- *
- *     &#64;Override
- *     protected void preWriteTo(Object object, Class&lt;?&gt; type, Type genericType,
- *             Annotation[] annotations, MediaType mediaType,
- *             MultivaluedMap&lt;String, Object&gt; httpHeaders, Marshaller marshaller)
- *             throws JAXBException {
- *         marshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER, "$");
- *     }
- *
- * }
- * </pre>
- * @since 2.4
- */
-@Produces({MediaType.APPLICATION_JSON, MediaType.WILDCARD, "application/x-javascript"})
-@Consumes({MediaType.APPLICATION_JSON, MediaType.WILDCARD})
-public class MOXyJsonProvider implements MessageBodyReader<Object>, MessageBodyWriter<Object>{
-
-    private static final String APPLICATION_XJAVASCRIPT = "application/x-javascript";
-    private static final String CHARSET = "charset";
-    private static final QName EMPTY_STRING_QNAME = new QName("");
-    private static final String JSON = "json";
-    private static final String PLUS_JSON = "+json";
-
-    @Context
-    protected Providers providers;
-
-    private String attributePrefix = null;
-    private Map<Set<Class<?>>, JAXBContext> contextCache = new HashMap<Set<Class<?>>, JAXBContext>();
-    private boolean formattedOutput = false;
-    private boolean includeRoot = false;
-    private boolean marshalEmptyCollections = true;
-    private Map<String, String> namespacePrefixMapper;
-    private char namespaceSeperator = Constants.DOT;
-    private String valueWrapper;
-    private boolean wrapperAsArrayName = false;
-
-    /**
-     * The value that will be prepended to all keys that are mapped to an XML
-     * attribute.  By default there is no attribute prefix.
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_ATTRIBUTE_PREFIX
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_ATTRIBUTE_PREFIX
-     */
-    public String getAttributePrefix() {
-        return attributePrefix;
-    }
-
-    /**
-     * A convenience method to get the domain class (i.e. <i>Customer</i> or <i>Foo, Bar</i>) from
-     * the parameter/return type (i.e. <i>Customer</i>, <i>List&lt;Customer&gt;</i>,
-     * <i>JAXBElement&lt;Customer&gt;</i>, <i>JAXBElement&lt;? extends Customer&gt;</i>,
-     * <i>List&lt;JAXBElement&lt;Customer&gt;&gt;</i>, or
-     * <i>List&lt;JAXBElement&lt;? extends Customer&gt;&gt;</i>
-     * <i>List&lt;Foo&lt;Bar&gt;&gt;</i>).
-     * @param genericType - The parameter/return type of the JAX-RS operation.
-     * @return The corresponding domain classes.
-     */
-    protected Set<Class<?>> getDomainClasses(Type genericType) {
-        if(null == genericType) {
-            return asSet(Object.class);
-        }
-        if(genericType instanceof Class && genericType != JAXBElement.class) {
-            Class<?> clazz = (Class<?>) genericType;
-            if(clazz.isArray()) {
-                return getDomainClasses(clazz.getComponentType());
-            }
-            return asSet(clazz);
-        } else if(genericType instanceof ParameterizedType) {
-            Set<Class<?>> result = new LinkedHashSet<Class<?>>();
-            result.add((Class<?>)((ParameterizedType) genericType).getRawType());
-            Type[] types = ((ParameterizedType) genericType).getActualTypeArguments();
-            if(types.length > 0){
-                for (Type upperType : types) {
-                    result.addAll(getDomainClasses(upperType));
-                }
-            }
-            return result;
-        } else if (genericType instanceof GenericArrayType) {
-            GenericArrayType genericArrayType = (GenericArrayType) genericType;
-            return getDomainClasses(genericArrayType.getGenericComponentType());
-        } else if(genericType instanceof WildcardType) {
-            Set<Class<?>> result = new LinkedHashSet<Class<?>>();
-            Type[] upperTypes = ((WildcardType)genericType).getUpperBounds();
-            if(upperTypes.length > 0){
-                for (Type upperType : upperTypes) {
-                    result.addAll(getDomainClasses(upperType));
-                }
-            } else {
-                result.add(Object.class);
-            }
-            return result;
-        } else {
-            return asSet(Object.class);
-        }
-    }
-
-    private Set<Class<?>> asSet(Class<?> clazz) {
-        Set<Class<?>> result = new LinkedHashSet<>();
-        result.add(clazz);
-        return result;
-    }
-
-    /**
-     * Return the <i>JAXBContext</i> that corresponds to the domain class.  This
-     * method does the following:
-     * <ol>
-     * <li>If an EclipseLink JAXB (MOXy) <i>JAXBContext</i> is available from
-     * a <i>ContextResolver</i> then use it.</li>
-     * <li>If an existing <i>JAXBContext</i> was not found in step one, then
-     * create a new one on the domain class.</li>
-     * </ol>
-     * @param domainClasses - The domain classes we need a <i>JAXBContext</i> for.
-     * @param annotations - The annotations corresponding to domain object.
-     * @param mediaType - The media type for the HTTP entity.
-     * @param httpHeaders - HTTP headers associated with HTTP entity.
-     * @return
-     * @throws JAXBException
-     */
-    protected JAXBContext getJAXBContext(Set<Class<?>> domainClasses, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, ?> httpHeaders) throws JAXBException {
-
-        JAXBContext jaxbContext = contextCache.get(domainClasses);
-        if(null != jaxbContext) {
-            return jaxbContext;
-        }
-
-        synchronized (contextCache) {
-            jaxbContext = contextCache.get(domainClasses);
-            if(null != jaxbContext) {
-                return jaxbContext;
-            }
-
-            ContextResolver<JAXBContext> resolver = null;
-            if(null != providers) {
-                resolver = providers.getContextResolver(JAXBContext.class, mediaType);
-            }
-
-            if (null != resolver && domainClasses.size() == 1) {
-                jaxbContext = resolver.getContext(domainClasses.iterator().next());
-            }
-
-            if(null == jaxbContext) {
-                jaxbContext = JAXBContextFactory.createContext(domainClasses.toArray(new Class[0]), null);
-                contextCache.put(domainClasses, jaxbContext);
-                return jaxbContext;
-            } else if (jaxbContext instanceof org.eclipse.persistence.jaxb.JAXBContext) {
-                return jaxbContext;
-            } else {
-                jaxbContext = JAXBContextFactory.createContext(domainClasses.toArray(new Class[0]), null);
-                contextCache.put(domainClasses, jaxbContext);
-                return jaxbContext;
-            }
-        }
-    }
-
-    private JAXBContext getJAXBContext(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
-        if(null == genericType) {
-            genericType = type;
-        }
-
-        try {
-            Set<Class<?>> domainClasses = getDomainClasses(genericType);
-            return getJAXBContext(domainClasses, annotations, mediaType, null);
-        } catch(JAXBException e) {
-            AbstractSessionLog.getLog().logThrowable(SessionLog.WARNING, SessionLog.MOXY, e);
-            return null;
-        }
-    }
-
-    /**
-     * By default the JSON-binding will ignore namespace qualification. If this
-     * property is set the portion of the key before the namespace separator
-     * will be used to determine the namespace URI.
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#NAMESPACE_PREFIX_MAPPER
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_NAMESPACE_PREFIX_MAPPER
-     */
-    public Map<String, String> getNamespacePrefixMapper() {
-        return namespacePrefixMapper;
-    }
-
-    /**
-     * This character (default is '.') separates the prefix from the key name.
-     * It is only used if namespace qualification has been enabled be setting a
-     * namespace prefix mapper.
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_NAMESPACE_SEPARATOR
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_NAMESPACE_SEPARATOR
-     */
-    public char getNamespaceSeparator() {
-        return this.namespaceSeperator;
-    }
-
-    /*
-     * @return -1 since the size of the JSON message is not known.
-     * @see javax.ws.rs.ext.MessageBodyWriter#getSize(java.lang.Object, java.lang.Class, java.lang.reflect.Type, java.lang.annotation.Annotation[], javax.ws.rs.core.MediaType)
-     */
-    @Override
-    public long getSize(Object t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
-        return -1;
-    }
-
-    /**
-     * The key that will correspond to the property mapped with @XmlValue.  This
-     * key will only be used if there are other mapped properties.
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_VALUE_WRAPPER
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_VALUE_WRAPPER
-     */
-    public String getValueWrapper() {
-        return valueWrapper;
-    }
-
-    /**
-     * @return true if the JSON output should be formatted (default is false).
-     */
-    public boolean isFormattedOutput() {
-        return formattedOutput;
-    }
-
-    /**
-     * @return true if the root node is included in the JSON message (default is
-     * false).
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_INCLUDE_ROOT
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_INCLUDE_ROOT
-     */
-    public boolean isIncludeRoot() {
-        return includeRoot;
-    }
-
-    /**
-     * If true empty collections will be marshalled as empty arrays, else the
-     * collection will not be marshalled to JSON (default is true).
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_MARSHAL_EMPTY_COLLECTIONS
-     */
-    public boolean isMarshalEmptyCollections() {
-        return marshalEmptyCollections;
-    }
-
-    /**
-     * @return true indicating that <i>MOXyJsonProvider</i> will
-     * be used for the JSON binding if the media type is of the following
-     * patterns *&#47;json or *&#47;*+json, and the type is not assignable from
-     * any of (or a Collection or JAXBElement of) the following:
-     * <ul>
-     * <li>byte[]</li>
-     * <li>java.io.File</li>
-     * <li>java.io.InputStream</li>
-     * <li>java.io.Reader</li>
-     * <li>java.lang.Object</li>
-     * <li>java.lang.String</li>
-     * <li>javax.activation.DataSource</li>
-     * </ul>
-     */
-    @Override
-    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
-        if(!supportsMediaType(mediaType)) {
-            return false;
-        } else if(CoreClassConstants.APBYTE == type || CoreClassConstants.STRING == type) {
-            return false;
-        } else if(Map.class.isAssignableFrom(type)) {
-            return false;
-        } else if(File.class.isAssignableFrom(type)) {
-            return false;
-        } else if(DataSource.class.isAssignableFrom(type)) {
-            return false;
-        } else if(InputStream.class.isAssignableFrom(type)) {
-            return false;
-        } else if(Reader.class.isAssignableFrom(type)) {
-            return false;
-        } else if(Object.class == type) {
-            return false;
-        } else if(type.isPrimitive()) {
-            return false;
-        } else if(type.isArray() && (type.getComponentType().isArray() || type.getComponentType().isPrimitive() || type.getComponentType().getPackage().getName().startsWith("java."))) {
-            return false;
-        } else if(JAXBElement.class.isAssignableFrom(type)) {
-            Set<Class<?>> domainClasses = getDomainClasses(genericType);
-            for (Class<?> domainClass : domainClasses) {
-                if (isReadable(domainClass, null, annotations, mediaType) || String.class == domainClass) {
-                    return true;
-                }
-            }
-            return false;
-        } else if(Collection.class.isAssignableFrom(type)) {
-            Set<Class<?>> domainClasses = getDomainClasses(genericType);
-            for (Class<?> domainClass : domainClasses) {
-                if (isReadable(domainClass, null, annotations, mediaType) || String.class == domainClass) {
-                    return true;
-                }
-            }
-            return false;
-        } else {
-            return null != getJAXBContext(type, genericType, annotations, mediaType);
-        }
-    }
-
-    /**
-     * If true the grouping element will be used as the JSON key.
-     *
-     * <p><b>Example</b></p>
-     * <p>Given the following class:</p>
-     * <pre>
-     * &#64;XmlAccessorType(XmlAccessType.FIELD)
-     * public class Customer {
-     *
-     *     &#64;XmlElementWrapper(name="phone-numbers")
-     *     &#64;XmlElement(name="phone-number")
-     *     private {@literal List<PhoneNumber>} phoneNumbers;
-     *
-     * }
-     * </pre>
-     * <p>If the property is set to false (the default) the JSON output will be:</p>
-     * <pre>
-     * {
-     *     "phone-numbers" : {
-     *         "phone-number" : [ {
-     *             ...
-     *         }, {
-     *             ...
-     *         }]
-     *     }
-     * }
-     * </pre>
-     * <p>And if the property is set to true, then the JSON output will be:</p>
-     * <pre>
-     * {
-     *     "phone-numbers" : [ {
-     *         ...
-     *     }, {
-     *         ...
-     *     }]
-     * }
-     * </pre>
-     * @since 2.4.2
-     * @see org.eclipse.persistence.jaxb.JAXBContextProperties#JSON_WRAPPER_AS_ARRAY_NAME
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_WRAPPER_AS_ARRAY_NAME
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_WRAPPER_AS_ARRAY_NAME
-     */
-    public boolean isWrapperAsArrayName() {
-        return wrapperAsArrayName;
-    }
-
-    /**
-     * @return true indicating that <i>MOXyJsonProvider</i> will
-     * be used for the JSON binding if the media type is of the following
-     * patterns *&#47;json or *&#47;*+json, and the type is not assignable from
-     * any of (or a Collection or JAXBElement of) the following:
-     * <ul>
-     * <li>byte[]</li>
-     * <li>java.io.File</li>
-     * <li>java.lang.Object</li>
-     * <li>java.lang.String</li>
-     * <li>jakarta.activation.DataSource</li>
-     * <li>jakarta.ws.rs.core.StreamingOutput</li>
-     * </ul>
-     */
-    @Override
-    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
-        if(type == JSONWithPadding.class && APPLICATION_XJAVASCRIPT.equals(mediaType.toString())) {
-            return true;
-        }
-        if(!supportsMediaType(mediaType)) {
-            return false;
-        } else if(CoreClassConstants.APBYTE == type || CoreClassConstants.STRING == type || type.isPrimitive()) {
-            return false;
-        } else if(Map.class.isAssignableFrom(type)) {
-            return false;
-        } else if(File.class.isAssignableFrom(type)) {
-            return false;
-        } else if(DataSource.class.isAssignableFrom(type)) {
-            return false;
-        } else if(StreamingOutput.class.isAssignableFrom(type)) {
-            return false;
-        } else if(Object.class == type) {
-            return false;
-        } else if(type.isPrimitive()) {
-            return false;
-        } else if(type.isArray() && (String.class.equals(type.getComponentType()) || type.getComponentType().isPrimitive() || Helper.isPrimitiveWrapper(type.getComponentType()))) {
-                return true;
-        } else if(type.isArray() && (type.getComponentType().isArray() || type.getComponentType().isPrimitive() || type.getComponentType().getPackage().getName().startsWith("java."))) {
-            return false;
-        } else if(JAXBElement.class.isAssignableFrom(type)) {
-            Set<Class<?>> domainClasses = getDomainClasses(genericType);
-
-            for (Class<?> domainClass : domainClasses) {
-                if (isWriteable(domainClass, null, annotations, mediaType) || domainClass == String.class) {
-                    return true;
-                }
-            }
-
-            return false;
-        } else if(Collection.class.isAssignableFrom(type)) {
-            Set<Class<?>> domainClasses = getDomainClasses(genericType);
-
-            //special case for List<JAXBElement<String>>
-            //this is quick fix, MOXyJsonProvider should be refactored as stated in issue #459541
-            if (domainClasses.size() == 3) {
-                Class[] domainArray = domainClasses.toArray(new Class[domainClasses.size()]);
-                if (JAXBElement.class.isAssignableFrom(domainArray[1]) && String.class == domainArray[2]) {
-                    return true;
-                }
-            }
-
-            for (Class<?> domainClass : domainClasses) {
-
-                if (String.class.equals(domainClass) || domainClass.isPrimitive() || Helper.isPrimitiveWrapper(domainClass)) {
-                    return true;
-                }
-
-                    String packageName = domainClass.getPackage().getName();
-                if(null == packageName || !packageName.startsWith("java.")) {
-                    if (isWriteable(domainClass, null, annotations, mediaType)) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-         } else {
-             return null != getJAXBContext(type, genericType, annotations, mediaType);
-        }
-    }
-
-    /**
-     * Subclasses of <i>MOXyJsonProvider</i> can override this method to
-     * customize the instance of <i>Unmarshaller</i> that will be used to
-     * unmarshal the JSON message in the readFrom call.
-     * @param type - The Class to be unmarshalled (i.e. <i>Customer</i> or
-     * <i>List</i>)
-     * @param genericType - The type of object to be unmarshalled (i.e
-     * <i>Customer</i> or <i>List&lt;Customer&gt;</i>).
-     * @param annotations - The annotations corresponding to domain object.
-     * @param mediaType - The media type for the HTTP entity.
-     * @param httpHeaders - HTTP headers associated with HTTP entity.
-     * @param unmarshaller - The instance of <i>Unmarshaller</i> that will be
-     * used to unmarshal the JSON message.
-     * @throws JAXBException
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties
-     */
-    protected void preReadFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, Unmarshaller unmarshaller) throws JAXBException {
-    }
-
-    /**
-     * Subclasses of <i>MOXyJsonProvider</i> can override this method to
-     * customize the instance of <i>Marshaller</i> that will be used to marshal
-     * the domain objects to JSON in the writeTo call.
-     * @param object - The domain object that will be marshalled to JSON.
-     * @param type - The Class to be marshalled (i.e. <i>Customer</i> or
-     * <i>List</i>)
-     * @param genericType - The type of object to be marshalled (i.e
-     * <i>Customer</i> or <i>List&lt;Customer&gt;</i>).
-     * @param annotations - The annotations corresponding to domain object.
-     * @param mediaType - The media type for the HTTP entity.
-     * @param httpHeaders - HTTP headers associated with HTTP entity.
-     * @param marshaller - The instance of <i>Marshaller</i> that will be used
-     * to marshal the domain object to JSON.
-     * @throws JAXBException
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties
-     */
-    protected void preWriteTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, Marshaller marshaller) throws JAXBException {
-    }
-
-    /*
-     * @see javax.ws.rs.ext.MessageBodyReader#readFrom(java.lang.Class, java.lang.reflect.Type, java.lang.annotation.Annotation[], javax.ws.rs.core.MediaType, javax.ws.rs.core.MultivaluedMap, java.io.InputStream)
-     */
-    @Override
-    public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
-        try {
-            if(null == genericType) {
-                genericType = type;
-            }
-
-            Set<Class<?>> domainClasses = getDomainClasses(genericType);
-            JAXBContext jaxbContext = getJAXBContext(domainClasses, annotations, mediaType, httpHeaders);
-            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
-            unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
-            unmarshaller.setProperty(UnmarshallerProperties.JSON_ATTRIBUTE_PREFIX, attributePrefix);
-            unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, includeRoot);
-            unmarshaller.setProperty(UnmarshallerProperties.JSON_NAMESPACE_PREFIX_MAPPER, namespacePrefixMapper);
-            unmarshaller.setProperty(UnmarshallerProperties.JSON_NAMESPACE_SEPARATOR, namespaceSeperator);
-            if(null != valueWrapper) {
-                unmarshaller.setProperty(UnmarshallerProperties.JSON_VALUE_WRAPPER, valueWrapper);
-            }
-            unmarshaller.setProperty(UnmarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, wrapperAsArrayName);
-            preReadFrom(type, genericType, annotations, mediaType, httpHeaders, unmarshaller);
-
-            StreamSource jsonSource;
-            Map<String, String> mediaTypeParameters = null;
-            if(null != mediaType) {
-                mediaTypeParameters = mediaType.getParameters();
-            }
-            if(null != mediaTypeParameters && mediaTypeParameters.containsKey(CHARSET)) {
-                String charSet = mediaTypeParameters.get(CHARSET);
-                Reader entityReader = new InputStreamReader(entityStream, charSet);
-                jsonSource = new StreamSource(entityReader);
-            } else {
-                jsonSource = new StreamSource(entityStream);
-            }
-
-            Class<?> domainClass = getDomainClass(domainClasses);
-            JAXBElement<?> jaxbElement = unmarshaller.unmarshal(jsonSource, domainClass);
-            if(type.isAssignableFrom(JAXBElement.class)) {
-                return jaxbElement;
-            } else {
-                Object value = jaxbElement.getValue();
-                if(value instanceof ArrayList) {
-                    if(type.isArray()) {
-                        ArrayList<Object> arrayList = (ArrayList<Object>) value;
-                        int arrayListSize = arrayList.size();
-                        boolean wrapItemInJAXBElement = wrapItemInJAXBElement(genericType);
-                        Object array;
-                        if(wrapItemInJAXBElement) {
-                            array = Array.newInstance(JAXBElement.class, arrayListSize);
-                        } else {
-                            array = Array.newInstance(domainClass, arrayListSize);
-                        }
-                        for(int x=0; x<arrayListSize; x++) {
-                            Object element = handleJAXBElement(arrayList.get(x), domainClass, wrapItemInJAXBElement);
-                            Array.set(array, x, element);
-                        }
-                        return array;
-                    } else {
-                        ContainerPolicy containerPolicy;
-                        if(type.isAssignableFrom(List.class) || type.isAssignableFrom(ArrayList.class) || type.isAssignableFrom(Collection.class)) {
-                            containerPolicy = new CollectionContainerPolicy(ArrayList.class);
-                        } else if(type.isAssignableFrom(Set.class)) {
-                            containerPolicy = new CollectionContainerPolicy(HashSet.class);
-                        } else if(type.isAssignableFrom(Deque.class) || type.isAssignableFrom(Queue.class)) {
-                            containerPolicy = new CollectionContainerPolicy(LinkedList.class);
-                        } else if(type.isAssignableFrom(NavigableSet.class) || type.isAssignableFrom(SortedSet.class)) {
-                            containerPolicy = new CollectionContainerPolicy(TreeSet.class);
-                        } else {
-                            containerPolicy = new CollectionContainerPolicy(type);
-                        }
-                        Object container = containerPolicy.containerInstance();
-                        boolean wrapItemInJAXBElement = wrapItemInJAXBElement(genericType);
-                        for(Object element : (Collection<Object>) value) {
-                            element = handleJAXBElement(element, domainClass, wrapItemInJAXBElement);
-                            containerPolicy.addInto(element, container, null);
-                        }
-                        return container;
-                    }
-                } else {
-                    return value;
-                }
-            }
-        } catch(UnmarshalException unmarshalException) {
-            ResponseBuilder builder = Response.status(Status.BAD_REQUEST);
-            throw new WebApplicationException(unmarshalException, builder.build());
-        } catch(JAXBException jaxbException) {
-            throw new WebApplicationException(jaxbException);
-        }
-    }
-
-    /**
-     * Get first non java class if exists.
-     *
-     * @param domainClasses
-     * @return first domain class or first generic class or just the first class from the list
-     */
-    public Class<?> getDomainClass(Set<Class<?>> domainClasses) {
-
-        if (domainClasses.size() == 1) {
-            return domainClasses.iterator().next();
-        }
-
-        boolean isStringPresent = false;
-
-        for (Class<?> clazz : domainClasses) {
-            if (!clazz.getName().startsWith("java.")
-                    && !clazz.getName().startsWith("javax.")
-                    && !clazz.getName().startsWith("jakarta.")
-                    && !java.util.List.class.isAssignableFrom(clazz)) {
-                return clazz;
-            } else if (clazz == String.class) {
-                isStringPresent = true;
-            }
-        }
-
-        if (isStringPresent) {
-            return String.class;
-        }
-
-        //handle simple generic case
-        if (domainClasses.size() >= 2) {
-            Iterator<Class<?>> it = domainClasses.iterator();
-            it.next();
-            return it.next();
-        }
-
-        return domainClasses.iterator().next();
-    }
-
-    private boolean wrapItemInJAXBElement(Type genericType) {
-        if(genericType == JAXBElement.class) {
-            return true;
-        } else if(genericType instanceof GenericArrayType) {
-            return wrapItemInJAXBElement(((GenericArrayType) genericType).getGenericComponentType());
-        } else if(genericType instanceof ParameterizedType) {
-            ParameterizedType parameterizedType = (ParameterizedType) genericType;
-            Type actualType = parameterizedType.getActualTypeArguments()[0];
-            return wrapItemInJAXBElement(parameterizedType.getOwnerType()) || wrapItemInJAXBElement(parameterizedType.getRawType()) || wrapItemInJAXBElement(actualType);
-        } else {
-            return false;
-        }
-    }
-
-    private Object handleJAXBElement(Object element, Class domainClass, boolean wrapItemInJAXBElement) {
-        if(wrapItemInJAXBElement) {
-            if(element instanceof JAXBElement) {
-                return element;
-            } else {
-                return new JAXBElement(EMPTY_STRING_QNAME, domainClass, element);
-            }
-        } else {
-            return JAXBIntrospector.getValue(element);
-        }
-    }
-
-    /**
-     * Specify a value that will be prepended to all keys that are mapped to an
-     * XML attribute.  By default there is no attribute prefix.
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_ATTRIBUTE_PREFIX
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_ATTRIBUTE_PREFIX
-     */
-    public void setAttributePrefix(String attributePrefix) {
-        this.attributePrefix = attributePrefix;
-    }
-
-    /**
-     * Specify if the JSON output should be formatted (default is false).
-     * @param formattedOutput - true if the output should be formatted, else
-     * false.
-     */
-    public void setFormattedOutput(boolean formattedOutput) {
-        this.formattedOutput = formattedOutput;
-    }
-
-    /**
-     * Specify if the root node should be included in the JSON message (default
-     * is false).
-     * @param includeRoot - true if the message includes the root node, else
-     * false.
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_INCLUDE_ROOT
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_INCLUDE_ROOT
-     */
-    public void setIncludeRoot(boolean includeRoot) {
-        this.includeRoot = includeRoot;
-    }
-
-    /**
-     * If true empty collections will be marshalled as empty arrays, else the
-     * collection will not be marshalled to JSON (default is true).
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_MARSHAL_EMPTY_COLLECTIONS
-     */
-    public void setMarshalEmptyCollections(boolean marshalEmptyCollections) {
-        this.marshalEmptyCollections = marshalEmptyCollections;
-    }
-
-   /**
-     * By default the JSON-binding will ignore namespace qualification. If this
-     * property is set then a prefix corresponding to the namespace URI and a
-     * namespace separator will be prefixed to the key.
-     * include it you can specify a Map of namespace URI to prefix.
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#NAMESPACE_PREFIX_MAPPER
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_NAMESPACE_PREFIX_MAPPER
-     */
-    public void setNamespacePrefixMapper(Map<String, String> namespacePrefixMapper) {
-        this.namespacePrefixMapper = namespacePrefixMapper;
-    }
-
-    /**
-     * This character (default is '.') separates the prefix from the key name.
-     * It is only used if namespace qualification has been enabled be setting a
-     * namespace prefix mapper.
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_NAMESPACE_SEPARATOR
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_NAMESPACE_SEPARATOR
-     */
-    public void setNamespaceSeparator(char namespaceSeparator) {
-        this.namespaceSeperator = namespaceSeparator;
-    }
-
-    /**
-     * If true the grouping element will be used as the JSON key.
-     *
-     * <p><b>Example</b></p>
-     * <p>Given the following class:</p>
-     * <pre>
-     * &#64;XmlAccessorType(XmlAccessType.FIELD)
-     * public class Customer {
-     *
-     *     &#64;XmlElementWrapper(name="phone-numbers")
-     *     &#64;XmlElement(name="phone-number")
-     *     private {@literal List<PhoneNumber>} phoneNumbers;
-     *
-     * }
-     * </pre>
-     * <p>If the property is set to false (the default) the JSON output will be:</p>
-     * <pre>
-     * {
-     *     "phone-numbers" : {
-     *         "phone-number" : [ {
-     *             ...
-     *         }, {
-     *             ...
-     *         }]
-     *     }
-     * }
-     * </pre>
-     * <p>And if the property is set to true, then the JSON output will be:</p>
-     * <pre>
-     * {
-     *     "phone-numbers" : [ {
-     *         ...
-     *     }, {
-     *         ...
-     *     }]
-     * }
-     * </pre>
-     * @since 2.4.2
-     * @see org.eclipse.persistence.jaxb.JAXBContextProperties#JSON_WRAPPER_AS_ARRAY_NAME
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_WRAPPER_AS_ARRAY_NAME
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_WRAPPER_AS_ARRAY_NAME
-     */
-    public void setWrapperAsArrayName(boolean wrapperAsArrayName) {
-        this.wrapperAsArrayName = wrapperAsArrayName;
-    }
-
-    /**
-     * Specify the key that will correspond to the property mapped with
-     * {@literal @XmlValue}.  This key will only be used if there are other mapped
-     * properties.
-     * @see org.eclipse.persistence.jaxb.MarshallerProperties#JSON_VALUE_WRAPPER
-     * @see org.eclipse.persistence.jaxb.UnmarshallerProperties#JSON_VALUE_WRAPPER
-     */
-    public void setValueWrapper(String valueWrapper) {
-        this.valueWrapper = valueWrapper;
-    }
-
-    /**
-     * @return true for all media types of the pattern *&#47;json and
-     * *&#47;*+json.
-     */
-    protected boolean supportsMediaType(MediaType mediaType) {
-        if(null == mediaType) {
-            return true;
-        }
-        String subtype = mediaType.getSubtype();
-        return subtype.equals(JSON) || subtype.endsWith(PLUS_JSON);
-    }
-
-    /**
-     * @see javax.ws.rs.ext.MessageBodyWriter#writeTo(java.lang.Object, java.lang.Class, java.lang.reflect.Type, java.lang.annotation.Annotation[], javax.ws.rs.core.MediaType, javax.ws.rs.core.MultivaluedMap, java.io.OutputStream)
-     */
-    @Override
-    public void writeTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
-        try {
-            if(null == genericType) {
-                genericType = type;
-            }
-
-            Set<Class<?>> domainClasses = getDomainClasses(genericType);
-            JAXBContext jaxbContext = getJAXBContext(domainClasses, annotations, mediaType, httpHeaders);
-            Marshaller marshaller = jaxbContext.createMarshaller();
-            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, formattedOutput);
-            marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
-            marshaller.setProperty(MarshallerProperties.JSON_ATTRIBUTE_PREFIX, attributePrefix);
-            marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, includeRoot);
-            marshaller.setProperty(MarshallerProperties.JSON_MARSHAL_EMPTY_COLLECTIONS, marshalEmptyCollections);
-            marshaller.setProperty(MarshallerProperties.JSON_NAMESPACE_SEPARATOR, namespaceSeperator);
-            if(null != valueWrapper) {
-                marshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER, valueWrapper);
-            }
-            marshaller.setProperty(MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, wrapperAsArrayName);
-            marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespacePrefixMapper);
-
-            Map<String, String> mediaTypeParameters = null;
-            if(null != mediaType) {
-                mediaTypeParameters = mediaType.getParameters();
-            }
-            if(null != mediaTypeParameters && mediaTypeParameters.containsKey(CHARSET)) {
-                String charSet = mediaTypeParameters.get(CHARSET);
-                marshaller.setProperty(Marshaller.JAXB_ENCODING, charSet);
-            }
-
-            preWriteTo(object, type, genericType, annotations, mediaType, httpHeaders, marshaller);
-            if (domainClasses.size() == 1) {
-                Class<?> domainClass = domainClasses.iterator().next();
-                if(!(List.class.isAssignableFrom(type) ||  type.isArray()) && domainClass.getPackage().getName().startsWith("java.")) {
-                    object = new JAXBElement(new QName((String) marshaller.getProperty(MarshallerProperties.JSON_VALUE_WRAPPER)), domainClass, object);
-                }
-            }
-
-            marshaller.marshal(object, entityStream);
-        } catch(JAXBException jaxbException) {
-            throw new WebApplicationException(jaxbException);
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/eclipse/persistence/jpa/rs/PersistenceFactoryBase.java b/jakarta/src/patch/java/org/eclipse/persistence/jpa/rs/PersistenceFactoryBase.java
deleted file mode 100644
index c83fdf6..0000000
--- a/jakarta/src/patch/java/org/eclipse/persistence/jpa/rs/PersistenceFactoryBase.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- */
-
-// Contributors:
-//         dclarke/tware - initial implementation
-//      gonural - version based persistence context
-//      Dmitry Kornilov - JPARS 2.0 related changes
-package org.eclipse.persistence.jpa.rs;
-
-import java.net.URI;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import jakarta.persistence.EntityManagerFactory;
-import jakarta.persistence.Persistence;
-
-import org.eclipse.persistence.config.PersistenceUnitProperties;
-import org.eclipse.persistence.dynamic.DynamicClassLoader;
-import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
-import org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl;
-import org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor;
-import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
-import org.eclipse.persistence.jpa.Archive;
-import org.eclipse.persistence.jpa.rs.exceptions.JPARSException;
-import org.eclipse.persistence.jpa.rs.features.ServiceVersion;
-import org.eclipse.persistence.jpa.rs.util.JPARSLogger;
-
-/**
- * Manages the PersistenceContexts that are used by a JPA-RS deployment.  Provides a single point to bootstrap
- * and look up PersistenceContexts.
- *
- * @author tware
- */
-public class PersistenceFactoryBase implements PersistenceContextFactory {
-    protected final Map<String, Set<PersistenceContext>> dynamicPersistenceContexts = new HashMap<>();
-
-    /**
-     * Bootstrap a PersistenceContext based on an pre-existing EntityManagerFactory.
-     *
-     * @param name      persistence context name
-     * @param emf       entity manager factory
-     * @param baseURI   base URI
-     * @param version   JPARS version. See {@link ServiceVersion} for more details.
-     * @param replace   Indicates that existing persistence context with given name and version must be replaced
-     *                  with the newly created one. If false passed the newly created context is not added to cache at all.
-     * @return newly created persistence context
-     */
-    public PersistenceContext bootstrapPersistenceContext(String name, EntityManagerFactory emf, URI baseURI, String version, boolean replace) {
-        final PersistenceContext persistenceContext = new PersistenceContext(name, (EntityManagerFactoryImpl) emf, baseURI, ServiceVersion.fromCode(version));
-
-        if (replace) {
-            addReplacePersistenceContext(persistenceContext);
-        }
-
-        return persistenceContext;
-    }
-
-    /**
-     * Stop the factory. Remove all the PersistenceContexts.
-     */
-    @Override
-    public void close() {
-        synchronized (this) {
-            for (Set<PersistenceContext> contextSet : dynamicPersistenceContexts.values()) {
-                if (contextSet != null) {
-                    for (PersistenceContext context : contextSet) {
-                        context.stop();
-                    }
-                }
-            }
-            dynamicPersistenceContexts.clear();
-        }
-    }
-
-    /**
-     * Close the PersistenceContext of a given name and clean it out of our list of PersistenceContexts.
-     *
-     * @param name name of the persistence context to close.
-     */
-    @Override
-    public void closePersistenceContext(String name) {
-        synchronized (this) {
-            Set<PersistenceContext> contextSet = dynamicPersistenceContexts.get(name);
-            if (contextSet != null) {
-                for (PersistenceContext context : contextSet) {
-                    context.stop();
-                }
-            }
-            dynamicPersistenceContexts.remove(name);
-        }
-    }
-
-    /**
-     * Close the PersistenceContext and clean it out of our list of PersistenceContexts.
-     *
-     * @param name name of the persistence context to close.
-     * @param version persistence context version
-     */
-    public void closePersistenceContext(String name, String version) {
-        synchronized (this) {
-            final Set<PersistenceContext> contextSet = dynamicPersistenceContexts.get(name);
-            if (contextSet != null) {
-                for (Iterator<PersistenceContext> iter = contextSet.iterator(); iter.hasNext();) {
-                    PersistenceContext context = iter.next();
-                    if (context.getVersion().equals(version)) {
-                        context.stop();
-                        iter.remove();
-                        break;
-                    }
-                }
-
-                if (contextSet.size() == 0) {
-                    dynamicPersistenceContexts.remove(name);
-                } else {
-                    dynamicPersistenceContexts.put(name, contextSet);
-                }
-            }
-        }
-    }
-
-    /**
-     * Provide an initial set of properties for bootstrapping PersistenceContexts.
-     * @param dcl
-     * @param originalProperties
-     * @return
-     */
-    protected static Map<String, Object> createProperties(DynamicClassLoader dcl, Map<String, ?> originalProperties) {
-        Map<String, Object> properties = new HashMap<>();
-
-        properties.put(PersistenceUnitProperties.CLASSLOADER, dcl);
-        properties.put(PersistenceUnitProperties.WEAVING, "static");
-
-        // For now we'll copy the connection info from admin PU
-        for (Map.Entry<String, ?> entry : originalProperties.entrySet()) {
-            if (entry.getKey().startsWith("javax") || entry.getKey().startsWith("jakarta") || entry.getKey().startsWith("eclipselink.log") || entry.getKey().startsWith("eclipselink.target-server")) {
-                properties.put(entry.getKey(), entry.getValue());
-            }
-        }
-        return properties;
-    }
-
-    /**
-     * Gets existing persistence context or create new based on given parameters if it doesn't exist.
-     */
-    @Override
-    public PersistenceContext get(String persistenceUnitName, URI defaultURI, String version, Map<String, Object> initializationProperties) {
-        PersistenceContext persistenceContext = getDynamicPersistenceContext(persistenceUnitName, version);
-
-        if (persistenceContext == null) {
-            try {
-                DynamicClassLoader dcl = new DynamicClassLoader(Thread.currentThread().getContextClassLoader());
-                Map<String, Object> properties = new HashMap<>();
-                properties.put(PersistenceUnitProperties.CLASSLOADER, dcl);
-                if (initializationProperties != null) {
-                    properties.putAll(initializationProperties);
-                }
-
-                EntityManagerFactoryImpl factory = (EntityManagerFactoryImpl) Persistence.createEntityManagerFactory(persistenceUnitName, properties);
-                ClassLoader sessionLoader = factory.getServerSession().getLoader();
-                if (!DynamicClassLoader.class.isAssignableFrom(sessionLoader.getClass())) {
-                    properties = new HashMap<>();
-                    dcl = new DynamicClassLoader(sessionLoader);
-                    properties.put(PersistenceUnitProperties.CLASSLOADER, dcl);
-                    if (initializationProperties != null) {
-                        properties.putAll(initializationProperties);
-                    }
-                    factory.refreshMetadata(properties);
-                }
-
-                persistenceContext = bootstrapPersistenceContext(persistenceUnitName, factory, defaultURI, version, true);
-            } catch (Exception e) {
-                JPARSLogger.exception("exception_creating_persistence_context", new Object[] { persistenceUnitName, e.toString() }, e);
-            }
-        }
-
-        if ((persistenceContext != null) && (!persistenceContext.isWeavingEnabled())) {
-            JPARSLogger.error(persistenceContext.getServerSession().getSessionLog(), "weaving_required_for_relationships", new Object[] {});
-            throw JPARSException.invalidConfiguration();
-        }
-
-        return persistenceContext;
-    }
-
-    /**
-     * Returns names of all currently cached persistence contexts.
-     */
-    @Override
-    public Set<String> getPersistenceContextNames() {
-        Set<String> contextNames = new HashSet<>();
-        try {
-            Set<Archive> archives = PersistenceUnitProcessor.findPersistenceArchives();
-            for (Archive archive : archives) {
-                List<SEPersistenceUnitInfo> infos = PersistenceUnitProcessor.processPersistenceArchive(archive, Thread.currentThread().getContextClassLoader());
-                for (SEPersistenceUnitInfo info : infos) {
-                    if (!info.getPersistenceUnitName().equals("jpa-rs")) {
-                        if (EntityManagerSetupImpl.mustBeCompositeMember(info)) {
-                            continue;
-                        }
-                        contextNames.add(info.getPersistenceUnitName());
-                    }
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        contextNames.addAll(dynamicPersistenceContexts.keySet());
-        return contextNames;
-    }
-
-    /**
-     * Gets cached persistence context by its name and JPARS version.
-     *
-     * @param name      persistent unit name.
-     * @param version   JPARS version. See {@link ServiceVersion} for more details.
-     * @return persistence context or null if doesn't exist.
-     */
-    public PersistenceContext getDynamicPersistenceContext(String name, String version) {
-        synchronized (this) {
-            Set<PersistenceContext> persistenceContextSet = dynamicPersistenceContexts.get(name);
-            if (persistenceContextSet != null) {
-                for (PersistenceContext persistenceContext : persistenceContextSet) {
-                    if ((name != null) && (version != null)) {
-                        if ((name.equals(persistenceContext.getName())) && (version.equals(persistenceContext.getVersion()))) {
-                            return persistenceContext;
-                        }
-                    } else if (((version == null) && (persistenceContext.getVersion() == null)) &&
-                            ((name != null) && (name.equals(persistenceContext.getName())))) {
-                        return persistenceContext;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    protected void addReplacePersistenceContext(PersistenceContext persistenceContext) {
-        synchronized (this) {
-            final PersistenceContext existingContext = getDynamicPersistenceContext(persistenceContext.getName(), persistenceContext.getVersion());
-
-            Set<PersistenceContext> persistenceContextSet = dynamicPersistenceContexts.get(persistenceContext.getName());
-            if (persistenceContextSet == null) {
-                persistenceContextSet = new HashSet<>();
-            }
-
-            if (existingContext != null) {
-                persistenceContextSet.remove(existingContext);
-            }
-
-            persistenceContextSet.add(persistenceContext);
-            dynamicPersistenceContexts.put(persistenceContext.getName(), persistenceContextSet);
-        }
-    }
-}
\ No newline at end of file
diff --git a/jakarta/src/patch/java/org/quartz/core/QuartzSchedulerMBeanImpl.java b/jakarta/src/patch/java/org/quartz/core/QuartzSchedulerMBeanImpl.java
deleted file mode 100644
index 9bce351..0000000
--- a/jakarta/src/patch/java/org/quartz/core/QuartzSchedulerMBeanImpl.java
+++ /dev/null
@@ -1,1011 +0,0 @@
-package org.apache.openejb.quartz.core;
-
-import static org.apache.openejb.quartz.JobKey.jobKey;
-import static org.apache.openejb.quartz.TriggerKey.triggerKey;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.MethodDescriptor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.NotCompliantMBeanException;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.StandardMBean;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-
-import org.apache.openejb.quartz.JobDataMap;
-import org.apache.openejb.quartz.JobDetail;
-import org.apache.openejb.quartz.JobExecutionContext;
-import org.apache.openejb.quartz.JobExecutionException;
-import org.apache.openejb.quartz.JobKey;
-import org.apache.openejb.quartz.JobListener;
-import org.apache.openejb.quartz.SchedulerException;
-import org.apache.openejb.quartz.SchedulerListener;
-import org.apache.openejb.quartz.Trigger;
-import org.apache.openejb.quartz.Trigger.TriggerState;
-import org.apache.openejb.quartz.TriggerKey;
-import org.apache.openejb.quartz.core.jmx.JobDetailSupport;
-import org.apache.openejb.quartz.core.jmx.JobExecutionContextSupport;
-import org.apache.openejb.quartz.core.jmx.QuartzSchedulerMBean;
-import org.apache.openejb.quartz.core.jmx.TriggerSupport;
-import org.apache.openejb.quartz.impl.matchers.GroupMatcher;
-import org.apache.openejb.quartz.impl.triggers.AbstractTrigger;
-import org.apache.openejb.quartz.spi.OperableTrigger;
-
-public class QuartzSchedulerMBeanImpl extends StandardMBean implements
-        NotificationEmitter, QuartzSchedulerMBean, JobListener,
-        SchedulerListener {
-    private static final MBeanNotificationInfo[] NOTIFICATION_INFO;
-
-    private final QuartzScheduler scheduler;
-    private boolean sampledStatisticsEnabled;
-    private SampledStatistics sampledStatistics;
-
-    private final static SampledStatistics NULL_SAMPLED_STATISTICS = new NullSampledStatisticsImpl();
-
-    static {
-        final String[] notifTypes = new String[] { SCHEDULER_STARTED,
-                SCHEDULER_PAUSED, SCHEDULER_SHUTDOWN, };
-        final String name = Notification.class.getName();
-        final String description = "QuartzScheduler JMX Event";
-        NOTIFICATION_INFO = new MBeanNotificationInfo[] { new MBeanNotificationInfo(
-                notifTypes, name, description), };
-    }
-
-    /**
-     * emitter
-     */
-    protected final Emitter emitter = new Emitter();
-
-    /**
-     * sequenceNumber
-     */
-    protected final AtomicLong sequenceNumber = new AtomicLong();
-
-    /**
-     * QuartzSchedulerMBeanImpl
-     *
-     * @throws NotCompliantMBeanException
-     */
-    protected QuartzSchedulerMBeanImpl(QuartzScheduler scheduler)
-            throws NotCompliantMBeanException {
-        super(QuartzSchedulerMBean.class);
-        this.scheduler = scheduler;
-        this.scheduler.addInternalJobListener(this);
-        this.scheduler.addInternalSchedulerListener(this);
-        this.sampledStatistics = NULL_SAMPLED_STATISTICS;
-        this.sampledStatisticsEnabled = false;
-    }
-
-    public TabularData getCurrentlyExecutingJobs() throws Exception {
-        try {
-            List<JobExecutionContext> currentlyExecutingJobs = scheduler.getCurrentlyExecutingJobs();
-            return JobExecutionContextSupport.toTabularData(currentlyExecutingJobs);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public TabularData getAllJobDetails() throws Exception {
-        try {
-            List<JobDetail> detailList = new ArrayList<JobDetail>();
-            for (String jobGroupName : scheduler.getJobGroupNames()) {
-                for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(jobGroupName))) {
-                    detailList.add(scheduler.getJobDetail(jobKey));
-                }
-            }
-            return JobDetailSupport.toTabularData(detailList.toArray(new JobDetail[detailList.size()]));
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public List<CompositeData> getAllTriggers() throws Exception {
-        try {
-            List<Trigger> triggerList = new ArrayList<Trigger>();
-            for (String triggerGroupName : scheduler.getTriggerGroupNames()) {
-                for (TriggerKey triggerKey : scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(triggerGroupName))) {
-                    triggerList.add(scheduler.getTrigger(triggerKey));
-                }
-            }
-            return TriggerSupport.toCompositeList(triggerList);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void addJob(CompositeData jobDetail, boolean replace) throws Exception {
-        try {
-            scheduler.addJob(JobDetailSupport.newJobDetail(jobDetail), replace);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    private static void invokeSetter(Object target, String attribute, Object value) throws Exception {
-        String setterName = "set" + Character.toUpperCase(attribute.charAt(0)) + attribute.substring(1);
-        Class<?>[] argTypes = {value.getClass()};
-        Method setter = findMethod(target.getClass(), setterName, argTypes);
-        if(setter != null) {
-            setter.invoke(target, value);
-        } else {
-            throw new Exception("Unable to find setter for attribute '" + attribute
-                    + "' and value '" + value + "'");
-        }
-    }
-
-    private static Class<?> getWrapperIfPrimitive(Class<?> c) {
-        Class<?> result = c;
-        try {
-            Field f = c.getField("TYPE");
-            f.setAccessible(true);
-            result = (Class<?>) f.get(null);
-        } catch (Exception e) {
-            /**/
-        }
-        return result;
-    }
-
-    private static Method findMethod(Class<?> targetType, String methodName,
-            Class<?>[] argTypes) throws IntrospectionException {
-        BeanInfo beanInfo = Introspector.getBeanInfo(targetType);
-        if (beanInfo != null) {
-            for(MethodDescriptor methodDesc: beanInfo.getMethodDescriptors()) {
-                Method method = methodDesc.getMethod();
-                Class<?>[] parameterTypes = method.getParameterTypes();
-                if (methodName.equals(method.getName()) && argTypes.length == parameterTypes.length) {
-                    boolean matchedArgTypes = true;
-                    for (int i = 0; i < argTypes.length; i++) {
-                        if (getWrapperIfPrimitive(argTypes[i]) != parameterTypes[i]) {
-                            matchedArgTypes = false;
-                            break;
-                        }
-                    }
-                    if (matchedArgTypes) {
-                        return method;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    public void scheduleBasicJob(Map<String, Object> jobDetailInfo,
-            Map<String, Object> triggerInfo) throws Exception {
-        try {
-            JobDetail jobDetail = JobDetailSupport.newJobDetail(jobDetailInfo);
-            OperableTrigger trigger = TriggerSupport.newTrigger(triggerInfo);
-            scheduler.deleteJob(jobDetail.getKey());
-            scheduler.scheduleJob(jobDetail, trigger);
-        } catch (ParseException pe) {
-            throw pe;
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void scheduleJob(Map<String, Object> abstractJobInfo,
-            Map<String, Object> abstractTriggerInfo) throws Exception {
-        try {
-            String triggerClassName = (String) abstractTriggerInfo.remove("triggerClass");
-            if(triggerClassName == null) {
-                throw new IllegalArgumentException("No triggerClass specified");
-            }
-            Class<?> triggerClass = Class.forName(triggerClassName);
-            Trigger trigger = (Trigger) triggerClass.newInstance();
-
-            String jobDetailClassName = (String) abstractJobInfo.remove("jobDetailClass");
-            if(jobDetailClassName == null) {
-                throw new IllegalArgumentException("No jobDetailClass specified");
-            }
-            Class<?> jobDetailClass = Class.forName(jobDetailClassName);
-            JobDetail jobDetail = (JobDetail) jobDetailClass.newInstance();
-
-            String jobClassName = (String) abstractJobInfo.remove("jobClass");
-            if(jobClassName == null) {
-                throw new IllegalArgumentException("No jobClass specified");
-            }
-            Class<?> jobClass = Class.forName(jobClassName);
-            abstractJobInfo.put("jobClass", jobClass);
-
-            for(Map.Entry<String, Object> entry : abstractTriggerInfo.entrySet()) {
-                String key = entry.getKey();
-                Object value = entry.getValue();
-                if("jobDataMap".equals(key)) {
-                    value = new JobDataMap((Map<?, ?>)value);
-                }
-                invokeSetter(trigger, key, value);
-            }
-
-            for(Map.Entry<String, Object> entry : abstractJobInfo.entrySet()) {
-                String key = entry.getKey();
-                Object value = entry.getValue();
-                if("jobDataMap".equals(key)) {
-                    value = new JobDataMap((Map<?, ?>)value);
-                }
-                invokeSetter(jobDetail, key, value);
-            }
-
-            AbstractTrigger<?> at = (AbstractTrigger<?>)trigger;
-            at.setKey(new TriggerKey(at.getName(), at.getGroup()));
-
-            Date startDate = at.getStartTime();
-            if(startDate == null || startDate.before(new Date())) {
-                at.setStartTime(new Date());
-            }
-
-            scheduler.deleteJob(jobDetail.getKey());
-            scheduler.scheduleJob(jobDetail, trigger);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void scheduleJob(String jobName, String jobGroup,
-            Map<String, Object> abstractTriggerInfo) throws Exception {
-        try {
-            JobKey jobKey = new JobKey(jobName, jobGroup);
-            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
-            if(jobDetail == null) {
-                throw new IllegalArgumentException("No such job '" + jobKey + "'");
-            }
-
-            String triggerClassName = (String) abstractTriggerInfo.remove("triggerClass");
-            if(triggerClassName == null) {
-                throw new IllegalArgumentException("No triggerClass specified");
-            }
-            Class<?> triggerClass = Class.forName(triggerClassName);
-            Trigger trigger = (Trigger) triggerClass.newInstance();
-
-            for(Map.Entry<String, Object> entry : abstractTriggerInfo.entrySet()) {
-                String key = entry.getKey();
-                Object value = entry.getValue();
-                if("jobDataMap".equals(key)) {
-                    value = new JobDataMap((Map<?, ?>)value);
-                }
-                invokeSetter(trigger, key, value);
-            }
-
-            AbstractTrigger<?> at = (AbstractTrigger<?>)trigger;
-            at.setKey(new TriggerKey(at.getName(), at.getGroup()));
-
-            Date startDate = at.getStartTime();
-            if(startDate == null || startDate.before(new Date())) {
-                at.setStartTime(new Date());
-            }
-
-            scheduler.scheduleJob(trigger);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void addJob(Map<String, Object> abstractJobInfo,    boolean replace) throws Exception {
-        try {
-            String jobDetailClassName = (String) abstractJobInfo.remove("jobDetailClass");
-            if(jobDetailClassName == null) {
-                throw new IllegalArgumentException("No jobDetailClass specified");
-            }
-            Class<?> jobDetailClass = Class.forName(jobDetailClassName);
-            JobDetail jobDetail = (JobDetail) jobDetailClass.newInstance();
-
-            String jobClassName = (String) abstractJobInfo.remove("jobClass");
-            if(jobClassName == null) {
-                throw new IllegalArgumentException("No jobClass specified");
-            }
-            Class<?> jobClass = Class.forName(jobClassName);
-            abstractJobInfo.put("jobClass", jobClass);
-
-            for(Map.Entry<String, Object> entry : abstractJobInfo.entrySet()) {
-                String key = entry.getKey();
-                Object value = entry.getValue();
-                if("jobDataMap".equals(key)) {
-                    value = new JobDataMap((Map<?, ?>)value);
-                }
-                invokeSetter(jobDetail, key, value);
-            }
-
-            scheduler.addJob(jobDetail, replace);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    private Exception newPlainException(Exception e) {
-        String type = e.getClass().getName();
-        if(type.startsWith("java.") || type.startsWith("javax.") || type.startsWith("jakarta.")) {
-            return e;
-        } else {
-            Exception result = new Exception(e.getMessage());
-            result.setStackTrace(e.getStackTrace());
-            return result;
-        }
-    }
-
-    public void deleteCalendar(String calendarName) throws Exception {
-        try {
-            scheduler.deleteCalendar(calendarName);
-        } catch(Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public boolean deleteJob(String jobName, String jobGroupName) throws Exception {
-        try {
-            return scheduler.deleteJob(jobKey(jobName, jobGroupName));
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public List<String> getCalendarNames()    throws Exception {
-        try {
-            return scheduler.getCalendarNames();
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public CompositeData getJobDetail(String jobName, String jobGroupName)
-      throws Exception {
-        try {
-            JobDetail jobDetail = scheduler.getJobDetail(jobKey(jobName, jobGroupName));
-            return JobDetailSupport.toCompositeData(jobDetail);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public List<String> getJobGroupNames()    throws Exception {
-        try {
-            return scheduler.getJobGroupNames();
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public List<String> getJobNames(String groupName) throws Exception {
-        try {
-            List<String> jobNames = new ArrayList<String>();
-            for(JobKey key: scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
-                jobNames.add(key.getName());
-            }
-            return jobNames;
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public String getJobStoreClassName() {
-        return scheduler.getJobStoreClass().getName();
-    }
-
-    public Set<String> getPausedTriggerGroups() throws Exception {
-        try {
-            return scheduler.getPausedTriggerGroups();
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public CompositeData getTrigger(String name, String groupName) throws Exception {
-        try {
-            Trigger trigger = scheduler.getTrigger(triggerKey(name, groupName));
-            return TriggerSupport.toCompositeData(trigger);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public List<String> getTriggerGroupNames()    throws Exception {
-        try {
-            return scheduler.getTriggerGroupNames();
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public List<String> getTriggerNames(String groupName) throws Exception {
-        try {
-            List<String> triggerNames = new ArrayList<String>();
-            for(TriggerKey key: scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(groupName))) {
-                triggerNames.add(key.getName());
-            }
-            return triggerNames;
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public String getTriggerState(String triggerName, String triggerGroupName) throws Exception {
-        try {
-            TriggerKey triggerKey = triggerKey(triggerName, triggerGroupName);
-            TriggerState ts = scheduler.getTriggerState(triggerKey);
-            return ts.name();
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public List<CompositeData> getTriggersOfJob(String jobName, String jobGroupName) throws Exception {
-        try {
-            JobKey jobKey = jobKey(jobName, jobGroupName);
-            return TriggerSupport.toCompositeList(scheduler.getTriggersOfJob(jobKey));
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public boolean interruptJob(String jobName, String jobGroupName) throws Exception {
-        try {
-            return scheduler.interrupt(jobKey(jobName, jobGroupName));
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public boolean interruptJob(String fireInstanceId) throws Exception {
-        try {
-            return scheduler.interrupt(fireInstanceId);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public Date scheduleJob(String jobName, String jobGroup,
-            String triggerName, String triggerGroup) throws Exception {
-        try {
-            JobKey jobKey = jobKey(jobName, jobGroup);
-            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
-            if (jobDetail == null) {
-                throw new IllegalArgumentException("No such job: " + jobKey);
-            }
-            TriggerKey triggerKey = triggerKey(triggerName, triggerGroup);
-            Trigger trigger = scheduler.getTrigger(triggerKey);
-            if (trigger == null) {
-                throw new IllegalArgumentException("No such trigger: " + triggerKey);
-            }
-            return scheduler.scheduleJob(jobDetail, trigger);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public boolean unscheduleJob(String triggerName, String triggerGroup) throws Exception {
-        try {
-            return scheduler.unscheduleJob(triggerKey(triggerName, triggerGroup));
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-   public void clear() throws Exception {
-       try {
-           scheduler.clear();
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public String getVersion() {
-        return scheduler.getVersion();
-    }
-
-    public boolean isShutdown() {
-        return scheduler.isShutdown();
-    }
-
-    public boolean isStarted() {
-        return scheduler.isStarted();
-    }
-
-    public void start() throws Exception {
-        try {
-            scheduler.start();
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void shutdown() {
-        scheduler.shutdown();
-    }
-
-    public void standby() {
-        scheduler.standby();
-    }
-
-    public boolean isStandbyMode() {
-        return scheduler.isInStandbyMode();
-    }
-
-    public String getSchedulerName() {
-        return scheduler.getSchedulerName();
-    }
-
-    public String getSchedulerInstanceId() {
-        return scheduler.getSchedulerInstanceId();
-    }
-
-    public String getThreadPoolClassName() {
-        return scheduler.getThreadPoolClass().getName();
-    }
-
-    public int getThreadPoolSize() {
-        return scheduler.getThreadPoolSize();
-    }
-
-    public void pauseJob(String jobName, String jobGroup) throws Exception {
-        try {
-            scheduler.pauseJob(jobKey(jobName, jobGroup));
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void pauseJobs(GroupMatcher<JobKey> matcher) throws Exception {
-        try {
-            scheduler.pauseJobs(matcher);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void pauseJobGroup(String jobGroup) throws Exception {
-        pauseJobs(GroupMatcher.<JobKey>groupEquals(jobGroup));
-    }
-
-    public void pauseJobsStartingWith(String jobGroupPrefix) throws Exception {
-        pauseJobs(GroupMatcher.<JobKey>groupStartsWith(jobGroupPrefix));
-    }
-
-    public void pauseJobsEndingWith(String jobGroupSuffix) throws Exception {
-        pauseJobs(GroupMatcher.<JobKey>groupEndsWith(jobGroupSuffix));
-    }
-
-    public void pauseJobsContaining(String jobGroupToken) throws Exception {
-        pauseJobs(GroupMatcher.<JobKey>groupContains(jobGroupToken));
-    }
-
-    public void pauseJobsAll() throws Exception {
-        pauseJobs(GroupMatcher.anyJobGroup());
-    }
-
-    public void pauseAllTriggers() throws Exception {
-        try {
-            scheduler.pauseAll();
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    private void pauseTriggers(GroupMatcher<TriggerKey> matcher) throws Exception {
-        try {
-            scheduler.pauseTriggers(matcher);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void pauseTriggerGroup(String triggerGroup) throws Exception {
-        pauseTriggers(GroupMatcher.<TriggerKey>groupEquals(triggerGroup));
-    }
-
-    public void pauseTriggersStartingWith(String triggerGroupPrefix) throws Exception {
-        pauseTriggers(GroupMatcher.<TriggerKey>groupStartsWith(triggerGroupPrefix));
-    }
-
-    public void pauseTriggersEndingWith(String triggerGroupSuffix) throws Exception {
-        pauseTriggers(GroupMatcher.<TriggerKey>groupEndsWith(triggerGroupSuffix));
-    }
-
-    public void pauseTriggersContaining(String triggerGroupToken) throws Exception {
-        pauseTriggers(GroupMatcher.<TriggerKey>groupContains(triggerGroupToken));
-    }
-
-    public void pauseTriggersAll() throws Exception {
-        pauseTriggers(GroupMatcher.anyTriggerGroup());
-    }
-
-    public void pauseTrigger(String triggerName, String triggerGroup) throws Exception {
-        try {
-            scheduler.pauseTrigger(triggerKey(triggerName, triggerGroup));
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void resumeAllTriggers() throws Exception {
-        try {
-            scheduler.resumeAll();
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void resumeJob(String jobName, String jobGroup) throws Exception {
-        try {
-            scheduler.resumeJob(jobKey(jobName, jobGroup));
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void resumeJobs(GroupMatcher<JobKey> matcher) throws Exception {
-        try {
-            scheduler.resumeJobs(matcher);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void resumeJobGroup(String jobGroup) throws Exception {
-        resumeJobs(GroupMatcher.<JobKey>groupEquals(jobGroup));
-    }
-
-    public void resumeJobsStartingWith(String jobGroupPrefix) throws Exception {
-        resumeJobs(GroupMatcher.<JobKey>groupStartsWith(jobGroupPrefix));
-    }
-
-    public void resumeJobsEndingWith(String jobGroupSuffix) throws Exception {
-        resumeJobs(GroupMatcher.<JobKey>groupEndsWith(jobGroupSuffix));
-    }
-
-    public void resumeJobsContaining(String jobGroupToken) throws Exception {
-        resumeJobs(GroupMatcher.<JobKey>groupContains(jobGroupToken));
-    }
-
-    public void resumeJobsAll() throws Exception {
-        resumeJobs(GroupMatcher.anyJobGroup());
-    }
-
-    public void resumeTrigger(String triggerName, String triggerGroup) throws Exception {
-        try {
-            scheduler.resumeTrigger(triggerKey(triggerName, triggerGroup));
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    private void resumeTriggers(GroupMatcher<TriggerKey> matcher) throws Exception {
-        try {
-            scheduler.resumeTriggers(matcher);
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void resumeTriggerGroup(String triggerGroup) throws Exception {
-        resumeTriggers(GroupMatcher.<TriggerKey>groupEquals(triggerGroup));
-    }
-
-    public void resumeTriggersStartingWith(String triggerGroupPrefix) throws Exception {
-        resumeTriggers(GroupMatcher.<TriggerKey>groupStartsWith(triggerGroupPrefix));
-    }
-
-    public void resumeTriggersEndingWith(String triggerGroupSuffix) throws Exception {
-        resumeTriggers(GroupMatcher.<TriggerKey>groupEndsWith(triggerGroupSuffix));
-    }
-
-    public void resumeTriggersContaining(String triggerGroupToken) throws Exception {
-        resumeTriggers(GroupMatcher.<TriggerKey>groupContains(triggerGroupToken));
-    }
-
-    public void resumeTriggersAll() throws Exception {
-        resumeTriggers(GroupMatcher.anyTriggerGroup());
-    }
-
-    public void triggerJob(String jobName, String jobGroup, Map<String, String> jobDataMap)
-            throws Exception {
-        try {
-            scheduler.triggerJob(jobKey(jobName, jobGroup), new JobDataMap(jobDataMap));
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    public void triggerJob(CompositeData trigger) throws Exception {
-        try {
-            scheduler.triggerJob(TriggerSupport.newTrigger(trigger));
-        } catch (Exception e) {
-            throw newPlainException(e);
-        }
-    }
-
-    // ScheduleListener
-
-    public void jobAdded(JobDetail jobDetail) {
-        sendNotification(JOB_ADDED, JobDetailSupport.toCompositeData(jobDetail));
-    }
-
-    public void jobDeleted(JobKey jobKey) {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("jobName", jobKey.getName());
-        map.put("jobGroup", jobKey.getGroup());
-        sendNotification(JOB_DELETED, map);
-    }
-
-    public void jobScheduled(Trigger trigger) {
-        sendNotification(JOB_SCHEDULED, TriggerSupport.toCompositeData(trigger));
-    }
-
-    public void jobUnscheduled(TriggerKey triggerKey) {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("triggerName", triggerKey.getName());
-        map.put("triggerGroup", triggerKey.getGroup());
-        sendNotification(JOB_UNSCHEDULED, map);
-    }
-
-    public void schedulingDataCleared() {
-        sendNotification(SCHEDULING_DATA_CLEARED);
-    }
-
-    public void jobPaused(JobKey jobKey) {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("jobName", jobKey.getName());
-        map.put("jobGroup", jobKey.getGroup());
-        sendNotification(JOBS_PAUSED, map);
-    }
-
-    public void jobsPaused(String jobGroup) {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("jobName", null);
-        map.put("jobGroup", jobGroup);
-        sendNotification(JOBS_PAUSED, map);
-    }
-
-    public void jobsResumed(String jobGroup) {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("jobName", null);
-        map.put("jobGroup", jobGroup);
-        sendNotification(JOBS_RESUMED, map);
-    }
-
-    public void jobResumed(JobKey jobKey) {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("jobName", jobKey.getName());
-        map.put("jobGroup", jobKey.getGroup());
-        sendNotification(JOBS_RESUMED, map);
-    }
-
-    public void schedulerError(String msg, SchedulerException cause) {
-        sendNotification(SCHEDULER_ERROR, cause.getMessage());
-    }
-
-    public void schedulerStarted() {
-        sendNotification(SCHEDULER_STARTED);
-    }
-
-    //not doing anything, just like schedulerShuttingdown
-    public void schedulerStarting() {
-    }
-
-    public void schedulerInStandbyMode() {
-        sendNotification(SCHEDULER_PAUSED);
-    }
-
-    public void schedulerShutdown() {
-        scheduler.removeInternalSchedulerListener(this);
-        scheduler.removeInternalJobListener(getName());
-
-        sendNotification(SCHEDULER_SHUTDOWN);
-    }
-
-    public void schedulerShuttingdown() {
-    }
-
-    public void triggerFinalized(Trigger trigger) {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("triggerName", trigger.getKey().getName());
-        map.put("triggerGroup", trigger.getKey().getGroup());
-        sendNotification(TRIGGER_FINALIZED, map);
-    }
-
-    public void triggersPaused(String triggerGroup) {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("triggerName", null);
-        map.put("triggerGroup", triggerGroup);
-        sendNotification(TRIGGERS_PAUSED, map);
-    }
-
-    public void triggerPaused(TriggerKey triggerKey) {
-        Map<String, String> map = new HashMap<String, String>();
-        if(triggerKey != null) {
-            map.put("triggerName", triggerKey.getName());
-            map.put("triggerGroup", triggerKey.getGroup());
-        }
-        sendNotification(TRIGGERS_PAUSED, map);
-    }
-
-    public void triggersResumed(String triggerGroup) {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("triggerName", null);
-        map.put("triggerGroup", triggerGroup);
-        sendNotification(TRIGGERS_RESUMED, map);
-    }
-
-    public void triggerResumed(TriggerKey triggerKey) {
-        Map<String, String> map = new HashMap<String, String>();
-        if(triggerKey != null) {
-            map.put("triggerName", triggerKey.getName());
-            map.put("triggerGroup", triggerKey.getGroup());
-        }
-        sendNotification(TRIGGERS_RESUMED, map);
-    }
-
-    // JobListener
-
-    public String getName() {
-        return "QuartzSchedulerMBeanImpl.listener";
-    }
-
-    public void jobExecutionVetoed(JobExecutionContext context) {
-        try {
-            sendNotification(JOB_EXECUTION_VETOED, JobExecutionContextSupport
-                    .toCompositeData(context));
-        } catch (Exception e) {
-            throw new RuntimeException(newPlainException(e));
-        }
-    }
-
-    public void jobToBeExecuted(JobExecutionContext context) {
-        try {
-            sendNotification(JOB_TO_BE_EXECUTED, JobExecutionContextSupport
-                    .toCompositeData(context));
-        } catch (Exception e) {
-            throw new RuntimeException(newPlainException(e));
-        }
-    }
-
-    public void jobWasExecuted(JobExecutionContext context,
-            JobExecutionException jobException) {
-        try {
-            sendNotification(JOB_WAS_EXECUTED, JobExecutionContextSupport
-                    .toCompositeData(context));
-        } catch (Exception e) {
-            throw new RuntimeException(newPlainException(e));
-        }
-    }
-
-    // NotificationBroadcaster
-
-    /**
-     * sendNotification
-     *
-     * @param eventType
-     */
-    public void sendNotification(String eventType) {
-        sendNotification(eventType, null, null);
-    }
-
-    /**
-     * sendNotification
-     *
-     * @param eventType
-     * @param data
-     */
-    public void sendNotification(String eventType, Object data) {
-        sendNotification(eventType, data, null);
-    }
-
-    /**
-     * sendNotification
-     *
-     * @param eventType
-     * @param data
-     * @param msg
-     */
-    public void sendNotification(String eventType, Object data, String msg) {
-        Notification notif = new Notification(eventType, this, sequenceNumber
-                .incrementAndGet(), System.currentTimeMillis(), msg);
-        if (data != null) {
-            notif.setUserData(data);
-        }
-        emitter.sendNotification(notif);
-    }
-
-    /**
-     * @author gkeim
-     */
-    private class Emitter extends NotificationBroadcasterSupport {
-        /**
-         * @see javax.management.NotificationBroadcasterSupport#getNotificationInfo()
-         */
-        @Override
-        public MBeanNotificationInfo[] getNotificationInfo() {
-            return QuartzSchedulerMBeanImpl.this.getNotificationInfo();
-        }
-    }
-
-    /**
-     * @see javax.management.NotificationBroadcaster#addNotificationListener(javax.management.NotificationListener,
-     *      javax.management.NotificationFilter, java.lang.Object)
-     */
-    public void addNotificationListener(NotificationListener notif,
-            NotificationFilter filter, Object callBack) {
-        emitter.addNotificationListener(notif, filter, callBack);
-    }
-
-    /**
-     * @see javax.management.NotificationBroadcaster#getNotificationInfo()
-     */
-    public MBeanNotificationInfo[] getNotificationInfo() {
-        return NOTIFICATION_INFO;
-    }
-
-    /**
-     * @see javax.management.NotificationBroadcaster#removeNotificationListener(javax.management.NotificationListener)
-     */
-    public void removeNotificationListener(NotificationListener listener)
-            throws ListenerNotFoundException {
-        emitter.removeNotificationListener(listener);
-    }
-
-    /**
-     * @see javax.management.NotificationEmitter#removeNotificationListener(javax.management.NotificationListener,
-     *      javax.management.NotificationFilter, java.lang.Object)
-     */
-    public void removeNotificationListener(NotificationListener notif,
-            NotificationFilter filter, Object callBack)
-            throws ListenerNotFoundException {
-        emitter.removeNotificationListener(notif, filter, callBack);
-    }
-
-    public synchronized boolean isSampledStatisticsEnabled() {
-        return sampledStatisticsEnabled;
-    }
-
-    public void setSampledStatisticsEnabled(boolean enabled) {
-        if (enabled != this.sampledStatisticsEnabled) {
-            this.sampledStatisticsEnabled = enabled;
-            if(enabled) {
-                this.sampledStatistics = new SampledStatisticsImpl(scheduler);
-            }
-            else {
-                 this.sampledStatistics.shutdown();
-                 this.sampledStatistics = NULL_SAMPLED_STATISTICS;
-            }
-            sendNotification(SAMPLED_STATISTICS_ENABLED, Boolean.valueOf(enabled));
-        }
-    }
-
-    public long getJobsCompletedMostRecentSample() {
-        return this.sampledStatistics.getJobsCompletedMostRecentSample();
-    }
-
-    public long getJobsExecutedMostRecentSample() {
-        return this.sampledStatistics.getJobsExecutingMostRecentSample();
-    }
-
-    public long getJobsScheduledMostRecentSample() {
-        return this.sampledStatistics.getJobsScheduledMostRecentSample();
-    }
-
-    public Map<String, Long> getPerformanceMetrics() {
-        Map<String, Long> result = new HashMap<String, Long>();
-        result.put("JobsCompleted", Long
-                .valueOf(getJobsCompletedMostRecentSample()));
-        result.put("JobsExecuted", Long
-                .valueOf(getJobsExecutedMostRecentSample()));
-        result.put("JobsScheduled", Long
-                .valueOf(getJobsScheduledMostRecentSample()));
-        return result;
-    }
-}
diff --git a/pom.xml b/pom.xml
index 86003ff..32f2051 100644
--- a/pom.xml
+++ b/pom.xml
@@ -592,7 +592,6 @@
         <module>arquillian</module>
         <module>utils</module>
         <module>tomee</module>
-        <module>jakarta</module>
       </modules>
       <repositories>
         <repository>
