diff --git a/src/main/java/catalina/deployer/WebappDeployer.java b/src/main/java/catalina/deployer/WebappDeployer.java
new file mode 100644
index 0000000..a2a03e3
--- /dev/null
+++ b/src/main/java/catalina/deployer/WebappDeployer.java
@@ -0,0 +1,244 @@
+/*
+ * 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 catalina.deployer;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Engine;
+import org.apache.catalina.Service;
+import org.apache.catalina.core.StandardHost;
+import org.apache.catalina.core.StandardServer;
+import org.apache.catalina.util.ContextName;
+import org.apache.openejb.NoSuchApplicationException;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.UndeployException;
+import org.apache.openejb.assembler.Deployer;
+import org.apache.openejb.assembler.classic.AppInfo;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.DeploymentExceptionManager;
+import org.apache.openejb.assembler.classic.WebAppBuilder;
+import org.apache.openejb.loader.IO;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.tomcat.util.modeler.Registry;
+import org.apache.tomee.catalina.TomEERuntimeException;
+import org.apache.tomee.catalina.TomcatWebAppBuilder;
+import org.apache.tomee.loader.TomcatHelper;
+
+import javax.ejb.Lock;
+import javax.ejb.LockType;
+import javax.ejb.Remote;
+import javax.ejb.Singleton;
+import javax.ejb.TransactionManagement;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import java.io.File;
+import java.util.Collection;
+import java.util.Properties;
+
+import static javax.ejb.TransactionManagementType.BEAN;
+
+@Lock(LockType.READ)
+@Singleton(name = "openejb/WebappDeployer")
+@Remote(Deployer.class)
+@TransactionManagement(BEAN)
+public class WebappDeployer implements Deployer {
+
+	private static final String WEBAPPS = "webapps";
+	private static final String OPENEJB_HOME = "openejb.home";
+	private final TomcatWebAppBuilder webappBuilder;
+	private final Assembler assembler;
+	private final MBeanServer mBeanServer;
+
+	public WebappDeployer() {
+		assembler = (Assembler) SystemInstance.get().getComponent(org.apache.openejb.spi.Assembler.class);
+		webappBuilder = (TomcatWebAppBuilder) SystemInstance.get().getComponent(WebAppBuilder.class);
+		mBeanServer = Registry.getRegistry(null, null).getMBeanServer();
+	}
+
+	@Override
+    public String getUniqueFile() {
+		throw new TomEERuntimeException("This method is not used");
+	}
+
+	@Override
+    public Collection<AppInfo> getDeployedApps() {
+		return assembler.getDeployedApplications();
+	}
+
+	@Override
+    public AppInfo deploy(final String location) throws OpenEJBException {
+		return deploy(location, null);
+	}
+
+	@Override
+    public AppInfo deploy(final Properties properties) throws OpenEJBException {
+		return deploy(null, properties);
+	}
+
+	@Override
+    public AppInfo deploy(String location, Properties properties) throws OpenEJBException {
+		try {
+			if (location == null && properties == null) {
+				throw new NullPointerException("location and properties are null");
+			}
+			if (location == null) {
+				location = properties.getProperty(FILENAME);
+			}
+
+			final File source = new File(location);
+			final File destination = new File(
+                System.getProperty(OPENEJB_HOME) + File.separator + WEBAPPS + File.separator + source.getName());
+            IO.copy(source, destination);
+
+            String destinationWithoutExtension = destination.getAbsolutePath();
+			String destinationFilenameWithoutExtension = destination.getName();
+
+			if (destination.getName().contains(".")) {
+				destinationWithoutExtension = destinationWithoutExtension.substring(0, destinationWithoutExtension.lastIndexOf('.'));
+				destinationFilenameWithoutExtension = destinationFilenameWithoutExtension.substring(0, destinationFilenameWithoutExtension.lastIndexOf('.'));
+			}
+
+			if (destination.getName().toLowerCase().endsWith(".war")) {
+				checkWebapp(destinationFilenameWithoutExtension);
+			} else {
+				check();
+			}
+
+			final AppInfo info = findAppInfo(destination.getAbsolutePath(), destinationWithoutExtension);
+            if (info == null) {
+                throw new NullPointerException("appinfo not found");
+            }
+
+            final DeploymentExceptionManager dem = SystemInstance.get().getComponent(DeploymentExceptionManager.class);
+            if (dem.hasDeploymentFailed()) {
+                final Exception tre = dem.getLastException();
+                // we don't need this exception anymore
+                dem.clearLastException(info);
+                throw tre;
+            }
+
+            return info;
+		} catch (Exception e) {
+			throw new OpenEJBException(e);
+		}
+	}
+
+	private AppInfo findAppInfo(final String... paths) {
+		final Collection<AppInfo> deployedApps = getDeployedApps();
+        for (final AppInfo appInfo : deployedApps) {
+            for (final String path : paths) {
+                if (appInfo.path.equals(path)) {
+                    return appInfo;
+                }
+            }
+        }
+		return null;
+	}
+
+	private void check() {
+		final StandardServer server = TomcatHelper.getServer();
+		for (final Service service : server.findServices()) {
+			if (service.getContainer() instanceof Engine) {
+				final Engine engine = (Engine) service.getContainer();
+				for (final Container engineChild : engine.findChildren()) {
+					if (engineChild instanceof StandardHost) {
+						final StandardHost host = (StandardHost) engineChild;
+						webappBuilder.checkHost(host);
+					}
+				}
+            }
+		}
+	}
+
+	private void checkWebapp(final String webappName) {
+		try {
+			final ContextName cn = new ContextName(webappName, true);
+
+			final String name = "Catalina:type=Deployer,host=localhost";
+			final ObjectName oname = new ObjectName(name);
+
+			final String[] params = {cn.getName() };
+			final String[] signature = {"java.lang.String" };
+			mBeanServer.invoke(oname, "check", params, signature);
+		} catch (Exception e) {
+            //Ignore
+		}
+	}
+
+	@Override
+    public void undeploy(final String moduleId) throws UndeployException, NoSuchApplicationException {
+		try {
+			final AppInfo appInfo = findAppInfo(moduleId);
+			if (appInfo !=  null) {
+				webappBuilder.undeployWebApps(appInfo);
+			}
+			
+			assembler.destroyApplication(moduleId);
+
+			final File moduleFile = new File(moduleId);
+			
+			if (moduleFile.getName().contains(".")) {
+				// delete matching directory
+				final File dir = new File(moduleFile.getAbsolutePath().substring(0, moduleFile.getAbsolutePath().lastIndexOf('.')));
+				if (dir.exists() && dir.isDirectory()) {
+					delete(dir);
+				}
+			} else {
+				delete(new File(moduleFile + ".war"));
+				delete(new File(moduleFile + ".ear"));
+				delete(new File(moduleFile + ".rar"));
+			}
+			
+			delete(moduleFile);
+
+		} catch (Exception e) {
+			throw new UndeployException(e);
+		}
+	}
+
+    @Override
+    public void reload(final String s) {
+        throw new UnsupportedOperationException();
+    }
+
+    private void delete(final File f) {
+		if (f == null || (!f.exists())) {
+			return;
+		}
+		
+		if (f.isFile()) {
+			if(!f.delete()){
+                f.deleteOnExit();
+            }
+			return;
+		}
+		
+		if (f.isDirectory()) {
+			final File[] listFiles = f.listFiles();
+            if (listFiles != null) {
+                for (final File file : listFiles) {
+                    if (file.getName().equals(".") || file.getName().equals("..")) continue;
+                    delete(file);
+                }
+            }
+
+            if(!f.delete()){
+                f.deleteOnExit();
+            }
+		}
+	}
+
+}
diff --git a/src/main/java/catalina/facade/ExceptionManagerFacade.java b/src/main/java/catalina/facade/ExceptionManagerFacade.java
new file mode 100644
index 0000000..7bc4ac5
--- /dev/null
+++ b/src/main/java/catalina/facade/ExceptionManagerFacade.java
@@ -0,0 +1,25 @@
+/**
+ * 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 catalina.facade;
+
+import javax.ejb.Remote;
+
+@Remote
+public interface ExceptionManagerFacade {
+    Exception exception();
+}
diff --git a/src/main/java/catalina/facade/ExceptionManagerFacadeBean.java b/src/main/java/catalina/facade/ExceptionManagerFacadeBean.java
new file mode 100644
index 0000000..b328982
--- /dev/null
+++ b/src/main/java/catalina/facade/ExceptionManagerFacadeBean.java
@@ -0,0 +1,33 @@
+/**
+ * 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 catalina.facade;
+
+import org.apache.openejb.assembler.classic.DeploymentExceptionManager;
+import org.apache.openejb.loader.SystemInstance;
+
+import javax.ejb.Singleton;
+import javax.ejb.TransactionManagement;
+import javax.ejb.TransactionManagementType;
+
+@Singleton(name = "openejb/ExceptionManagerFacade")
+@TransactionManagement(TransactionManagementType.BEAN)
+public class ExceptionManagerFacadeBean implements ExceptionManagerFacade {
+    public Exception exception() {
+        return SystemInstance.get().getComponent(DeploymentExceptionManager.class).getLastException();
+    }
+}
diff --git a/src/main/java/org/apache/openejb/cts/DeploymentImpl.java b/src/main/java/org/apache/openejb/cts/DeploymentImpl.java
index ff97abe..0152ab1 100644
--- a/src/main/java/org/apache/openejb/cts/DeploymentImpl.java
+++ b/src/main/java/org/apache/openejb/cts/DeploymentImpl.java
@@ -24,9 +24,8 @@
 import com.sun.ts.lib.deliverable.PropertyNotSetException;
 import com.sun.ts.lib.porting.DeploymentInfo;
 import com.sun.ts.lib.porting.TSDeploymentException;
-import com.sun.ts.lib.porting.TSDeploymentInterface2;
 import org.apache.openejb.config.RemoteServer;
-import org.apache.openejb.testng.PropertiesBuilder;
+import org.apache.openejb.cts.deploy.TSDeploymentInterface2;
 
 import javax.enterprise.deploy.spi.DeploymentManager;
 import javax.enterprise.deploy.spi.Target;
diff --git a/src/main/java/org/apache/openejb/cts/deploy/DMProps.java b/src/main/java/org/apache/openejb/cts/deploy/DMProps.java
new file mode 100644
index 0000000..d78c576
--- /dev/null
+++ b/src/main/java/org/apache/openejb/cts/deploy/DMProps.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007, 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.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.apache.openejb.cts.deploy;
+
+import java.lang.String;
+import java.util.Properties;
+
+// Harness imports
+import com.sun.ts.lib.util.TestUtil;
+
+public class DMProps {
+
+  private String jarfile;
+
+  private String uri;
+
+  private String uname;
+
+  private String passwd;
+
+  public DMProps(String jarfile, String uri, String uname, String passwd) {
+    this.jarfile = jarfile;
+    this.uri = uri;
+    this.uname = uname;
+    this.passwd = passwd;
+  }
+
+  public boolean equals(DMProps dm2) {
+    return (this.jarfile.equals(dm2.jarfile) && this.uri.equals(dm2.uri)
+        && this.uname.equals(dm2.uname) && this.passwd.equals(dm2.passwd));
+  }
+
+  public void setJarFile(String jarfile) {
+    this.jarfile = jarfile;
+  }
+
+  public void setURI(String uri) {
+    this.uri = uri;
+  }
+
+  public void setUname(String uname) {
+    this.uname = uname;
+  }
+
+  public void setPasswd(String passwd) {
+    this.passwd = passwd;
+  }
+
+  public String getJarFile() {
+    return (jarfile);
+  }
+
+  public String getURI() {
+    return (uri);
+  }
+
+  public String getUname() {
+    return (uname);
+  }
+
+  public String getPasswd() {
+    return (passwd);
+  }
+
+}
diff --git a/src/main/java/org/apache/openejb/cts/deploy/DeployTestUtil.java b/src/main/java/org/apache/openejb/cts/deploy/DeployTestUtil.java
new file mode 100644
index 0000000..13ad65e
--- /dev/null
+++ b/src/main/java/org/apache/openejb/cts/deploy/DeployTestUtil.java
@@ -0,0 +1,1036 @@
+
+/*
+ * Copyright (c) 2007, 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.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.apache.openejb.cts.deploy;
+
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+import java.util.Iterator;
+import java.util.Hashtable;
+
+import java.io.*;
+import java.util.jar.Manifest;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+// Harness imports
+import com.sun.ts.lib.util.TestUtil;
+
+// J2EE Deployment imports
+import javax.enterprise.deploy.spi.*;
+import javax.enterprise.deploy.spi.status.*;
+import javax.enterprise.deploy.spi.exceptions.*;
+import javax.enterprise.deploy.model.*;
+import javax.enterprise.deploy.shared.*;
+import javax.enterprise.deploy.model.*;
+
+import java.io.*;
+import java.util.*;
+
+import javax.enterprise.deploy.shared.factories.*;
+import javax.enterprise.deploy.spi.*;
+import javax.enterprise.deploy.spi.exceptions.*;
+import javax.enterprise.deploy.spi.factories.*;
+
+public class DeployTestUtil {
+
+  public static final String DEPLOYMENT_MANIFEST_ENTRY_NAME = "J2EE-DeploymentFactory-Implementation-Class";
+
+  public static final String FILE_ARCHIVE = "FILE";
+
+  public static final String STREAM_ARCHIVE = "STREAM";
+
+  public static final String APPLICATION_ARCHIVE = "APPLICATION";
+
+  public static final String STAND_ALONE_ARCHIVE = "STAND_ALONE";
+
+  private DeploymentManager dm = null;
+
+  private DMProps dmp;
+
+  private DeploymentManager disconnectedDM;
+
+  /**
+   *
+   * Construct a DeployTestUtil object. Load the DeploymentFactories from the
+   * provided jarfile, and get a DeploymentManager instance.
+   *
+   */
+  public DeployTestUtil(DMProps dmprops) throws Exception {
+    dmp = dmprops;
+    loadDMFactories();
+  }
+
+  public DeploymentManager getDeploymentManager()
+      throws DeploymentManagerCreationException {
+    if (dm == null) {
+      DeploymentFactoryManager dfmanager = DeploymentFactoryManager
+          .getInstance();
+      dm = dfmanager.getDeploymentManager(dmp.getURI(), dmp.getUname(),
+          dmp.getPasswd());
+      TestUtil.logHarnessDebug(
+          "$$$$$$$$$$$$$$$[" + dmp.getUname() + ", " + dmp.getPasswd() + "]");
+      TestUtil.logHarness("amd Obtained FRESH DeploymentManager");
+    } else {
+      TestUtil.logHarness("amd Obtained CACHED DeploymentManager");
+    }
+    System.out.println(dm);
+    return dm;
+  }
+
+  public DeploymentManager getDisconnectedDeploymentManager()
+      throws DeploymentManagerCreationException {
+    if (disconnectedDM == null) {
+
+      TestUtil.logHarness("DeployTestUtil.getDeploymentManager called");
+      DeploymentFactoryManager dfmanager = DeploymentFactoryManager
+          .getInstance();
+      disconnectedDM = dfmanager.getDisconnectedDeploymentManager(dmp.getURI());
+    }
+    return (disconnectedDM);
+  }
+
+  public Vector getDeploymentFactoryClassNames() throws Exception {
+    File deployPlatformJarFile;
+
+    try {
+      deployPlatformJarFile = new File(dmp.getJarFile());
+    } catch (Exception e) {
+      throw new Exception(
+          "Could not contruct file object: " + dmp.getJarFile());
+    }
+
+    // Obtain DeploymentFactory names from manifest and load those entries
+    TestUtil.logHarness("loadDeploymentFactories loading factories from file:"
+        + deployPlatformJarFile.getName());
+
+    Manifest mf = new java.util.jar.JarFile(deployPlatformJarFile)
+        .getManifest();
+
+    // This should be rewritten to get multiple class names from the manifest
+    String dfClassNames = mf.getMainAttributes()
+        .getValue(DEPLOYMENT_MANIFEST_ENTRY_NAME);
+    if (dfClassNames == null) {
+      throw new Exception(
+          "Invalid Jar File: Jar file does not have entry for Deployment factories");
+    }
+
+    // Parse class names, assuming that class names are separated by space
+    java.util.StringTokenizer st = new java.util.StringTokenizer(dfClassNames,
+        " ");
+    Vector classNames = new Vector();
+    while (st.hasMoreTokens()) {
+      classNames.add(st.nextToken());
+    }
+
+    return (classNames);
+
+  }
+
+  private void loadDMFactories() throws Exception {
+    TestUtil.logHarness("DeployTestUtil.loadDMFactories called");
+    TestUtil.logHarness(
+        "DeployTestUtil.loadDMFactories using jarfile: " + dmp.getJarFile());
+    loadDeploymentFactories();
+  }
+
+  private void loadDeploymentFactories() throws Exception {
+
+    File deployPlatformJarFile;
+
+    try {
+      deployPlatformJarFile = new File(dmp.getJarFile());
+    } catch (Exception e) {
+      throw new Exception(
+          "Could not contruct file object: " + dmp.getJarFile());
+    }
+
+    // Obtain DeploymentFactory names from manifest and load those entries
+    TestUtil.logHarness("loadDeploymentFactories loading factories from file:"
+        + deployPlatformJarFile.getName());
+
+    Manifest mf = new java.util.jar.JarFile(deployPlatformJarFile)
+        .getManifest();
+
+    // This should be rewritten to get multiple class names from the manifest
+    TestUtil.logHarness(
+        "Looking for manifest entry: " + DEPLOYMENT_MANIFEST_ENTRY_NAME);
+    String dfClassNames = mf.getMainAttributes()
+        .getValue(DEPLOYMENT_MANIFEST_ENTRY_NAME);
+
+    if (dfClassNames == null) {
+      throw new Exception("Invalid Jar File: No manifest entry.");
+    }
+
+    // Parse class names, assuming that class names are separated by space
+    java.util.StringTokenizer st = new java.util.StringTokenizer(dfClassNames,
+        " ");
+    Vector classNames = new Vector();
+    while (st.hasMoreTokens())
+      classNames.add(st.nextToken());
+
+    // Load classes
+    try {
+      URL[] urls = new URL[] { deployPlatformJarFile.toURL() };
+      URLClassLoader urlClassLoader = new URLClassLoader(urls,
+          this.getClass().getClassLoader());
+
+      // Do i need to set the contect class loader ?
+      TestUtil.logHarness(
+          "loadDeploymentFactories about to load classes :" + dfClassNames);
+      Thread.currentThread().setContextClassLoader(urlClassLoader);
+
+      // Load all classes
+      for (int classNameIndex = 0; classNameIndex < classNames
+          .size(); classNameIndex++) {
+
+        Class factory = null;
+        DeploymentFactory df = null;
+
+        try {
+          factory = urlClassLoader
+              .loadClass((String) classNames.elementAt(classNameIndex));
+          df = (DeploymentFactory) factory.newInstance();
+        } catch (Exception e) {
+          e.printStackTrace();
+        }
+
+        if (df instanceof DeploymentFactory) {
+          DeploymentFactoryManager.getInstance()
+              .registerDeploymentFactory((DeploymentFactory) df);
+          TestUtil
+              .logMsg("Registered DeploymentFactory: " + df.getDisplayName());
+        } else {
+          throw new Exception("Does not implement DeploymentFactory");
+        }
+
+        // Class.forName((String)classNames.elementAt(classNameIndex),
+        // true, urlClassLoader);
+
+        // Register DeploymentFactory with DeploymentFactoryManager
+        // DeploymentFactory df = (DeploymentFactory)classNames.elementAt
+        // (classNameIndex);
+      }
+
+    } catch (Exception ex) {
+      ex.printStackTrace();
+      throw new Exception(
+          "Could not load DeploymentFactory class: " + ex.getMessage());
+    }
+
+  }
+
+  public void releaseDeploymentManager() {
+
+    if (dm != null) {
+      TestUtil.logHarness("amd Releasing DeploymentManager amd");
+      this.dm.release();
+    }
+    if (disconnectedDM != null) {
+      TestUtil.logHarness("amd Releasing DISCONNECTED DeploymentManager amd");
+      this.disconnectedDM.release();
+    }
+
+    TestUtil.logHarness(" amd Released DeploymentManager amd ");
+  }
+
+  public boolean checkIfModuleExists(TargetModuleID moduleToCheck,
+      TargetModuleID[] modulesList) {
+    boolean exists = false;
+    if (moduleToCheck == null) {
+      return exists;
+    }
+    int numMods = (modulesList == null) ? 0 : modulesList.length;
+    for (int modIndex = 0; modIndex < numMods; modIndex++) {
+      if (moduleToCheck.getModuleID()
+          .equals(modulesList[modIndex].getModuleID())) {
+        // Also check for same targets.
+        if (moduleToCheck.getTarget().getName()
+            .equals(modulesList[modIndex].getTarget().getName())) {
+          exists = true;
+          break;
+        }
+      }
+    }
+    return exists;
+  }
+
+  /*
+   * If the operation is successful then TargetModuleID is a valid module id.
+   * Else it will be null
+   **/
+  public TargetModuleID distributeModuleArchive(Target[] targets,
+      File moduleArchive, File deploymentPlan) throws Exception {
+    DeploymentManager dm = getDeploymentManager();
+    ProgressHandler progressHandler = new ProgressHandler();
+    ProgressObject progress = dm.distribute(targets, moduleArchive,
+        deploymentPlan);
+    progress.addProgressListener(progressHandler);
+    progressHandler.start();
+    // Wait for the progress handler to complete its job
+    progressHandler.join();
+    StateType completionState = progressHandler.getCompletionState();
+    if (completionState.getValue() != StateType.COMPLETED.getValue()) {
+      // The state must be either FAILED, or RELEASED
+      return null;
+    }
+    TargetModuleID[] resultModuleIDs = progress.getResultTargetModuleIDs();
+    if (resultModuleIDs.length < 1) {
+      // There should be atleast one target module id if progress is
+      // successfully complete
+      return null;
+    }
+    return resultModuleIDs[0];
+  }
+
+  /*
+   * If the operation is successful then TargetModuleID is a valid module id.
+   * Else it will be null
+   **/
+  public TargetModuleID distributeModuleStream(Target[] targets,
+      ModuleType moduleType, InputStream moduleArchive,
+      InputStream deploymentPlan, boolean oneDotFiveApi) throws Exception {
+    String apiType = (oneDotFiveApi == true) ? "1.5 API" : "deprecated API";
+    TestUtil.logMsg("Calling distribute(): Using " + apiType);
+    DeploymentManager dm = getDeploymentManager();
+    ProgressHandler progressHandler = new ProgressHandler();
+    ProgressObject progress = dm.distribute(targets, moduleArchive, deploymentPlan);
+    progress.addProgressListener(progressHandler);
+    progressHandler.start();
+    // Wait for the progress handler to complete its job
+    progressHandler.join();
+    StateType completionState = progressHandler.getCompletionState();
+    if (completionState.getValue() != StateType.COMPLETED.getValue()) {
+      // The state must be either FAILED, or RELEASED
+      return null;
+    }
+    TargetModuleID[] resultModuleIDs = progress.getResultTargetModuleIDs();
+    if (resultModuleIDs.length < 1) {
+      // There should be atleast one target module id if progress is
+      // successfully complete
+      return null;
+    }
+    return resultModuleIDs[0];
+  }
+
+  /*
+   * If the operation is successful then TargetModuleID is a valid module id.
+   * Else it will be null
+   **/
+  public TargetModuleID startModule(TargetModuleID moduleToStart)
+      throws Exception {
+    DeploymentManager dm = getDeploymentManager();
+    ProgressHandler progressHandler = new ProgressHandler();
+    ProgressObject progress = dm.start(new TargetModuleID[] { moduleToStart });
+    progress.addProgressListener(progressHandler);
+    progressHandler.start();
+    // Wait for the progress handler to complete its job
+    progressHandler.join();
+    StateType completionState = progressHandler.getCompletionState();
+    if (completionState.getValue() != StateType.COMPLETED.getValue()) {
+      // The state must be either FAILED, or RELEASED
+      return null;
+    }
+    TargetModuleID[] resultModuleIDs = progress.getResultTargetModuleIDs();
+    if (resultModuleIDs.length < 1) {
+      // There should be atleast one target module id if progress is
+      // successfully complete
+      return null;
+    }
+    return resultModuleIDs[0];
+  }
+
+  /*
+   * If the operation is successful then TargetModuleID is a valid module id.
+   * Else it will be null
+   **/
+  public TargetModuleID stopModule(TargetModuleID moduleToStop)
+      throws Exception {
+    DeploymentManager dm = getDeploymentManager();
+    ProgressHandler progressHandler = new ProgressHandler();
+    ProgressObject progress = dm.stop(new TargetModuleID[] { moduleToStop });
+    progress.addProgressListener(progressHandler);
+    progressHandler.start();
+    // Wait for the progress handler to complete its job
+    progressHandler.join();
+    StateType completionState = progressHandler.getCompletionState();
+    if (completionState.getValue() != StateType.COMPLETED.getValue()) {
+      // The state must be either FAILED, or RELEASED
+      return null;
+    }
+    TargetModuleID[] resultModuleIDs = progress.getResultTargetModuleIDs();
+    if (resultModuleIDs.length < 1) {
+      // There should be atleast one target module id if progress is
+      // successfully complete
+      return null;
+    }
+    return resultModuleIDs[0];
+  }
+
+  /*
+   * If the operation is successful then TargetModuleID is a valid module id.
+   * Else it will be null
+   **/
+  public TargetModuleID undeployModule(TargetModuleID moduleToUndeploy)
+      throws Exception {
+    DeploymentManager dm = getDeploymentManager();
+    ProgressHandler progressHandler = new ProgressHandler();
+    ProgressObject progress = dm
+        .undeploy(new TargetModuleID[] { moduleToUndeploy });
+    progress.addProgressListener(progressHandler);
+    progressHandler.start();
+    // Wait for the progress handler to complete its job
+    progressHandler.join();
+    StateType completionState = progressHandler.getCompletionState();
+    if (completionState.getValue() != StateType.COMPLETED.getValue()) {
+      // The state must be either FAILED, or RELEASED
+      return null;
+    }
+    TargetModuleID[] resultModuleIDs = progress.getResultTargetModuleIDs();
+    if (resultModuleIDs.length < 1) {
+      // There should be atleast one target module id if progress is
+      // successfully complete
+      return null;
+    }
+    return resultModuleIDs[0];
+  }
+
+  /*
+   * If the operation is successful then TargetModuleID is a valid module id.
+   * Else it will be null
+   **/
+  public TargetModuleID redeployModuleArchive(TargetModuleID[] targetModuleIds,
+      File moduleArchive, File deploymentPlan) throws Exception {
+    DeploymentManager dm = getDeploymentManager();
+    ProgressHandler progressHandler = new ProgressHandler();
+    ProgressObject progress = dm.redeploy(targetModuleIds, moduleArchive,
+        deploymentPlan);
+    progress.addProgressListener(progressHandler);
+    progressHandler.start();
+    // Wait for the progress handler to complete its job
+    progressHandler.join();
+    StateType completionState = progressHandler.getCompletionState();
+    if (completionState.getValue() != StateType.COMPLETED.getValue()) {
+      // The state must be either FAILED, or RELEASED
+      return null;
+    }
+    TargetModuleID[] resultModuleIDs = progress.getResultTargetModuleIDs();
+    if (resultModuleIDs.length < 1) {
+      // There should be atleast one target module id if progress is
+      // successfully complete
+      return null;
+    }
+    return resultModuleIDs[0];
+  }
+
+  /*
+   * If the operation is successful then TargetModuleID is a valid module id.
+   * Else it will be null
+   **/
+  public TargetModuleID redeployModuleStream(TargetModuleID[] targetModuleIds,
+      InputStream moduleArchive, InputStream deploymentPlan) throws Exception {
+    DeploymentManager dm = getDeploymentManager();
+    ProgressHandler progressHandler = new ProgressHandler();
+    ProgressObject progress = dm.redeploy(targetModuleIds, moduleArchive,
+        deploymentPlan);
+    progress.addProgressListener(progressHandler);
+    progressHandler.start();
+    // Wait for the progress handler to complete its job
+    progressHandler.join();
+    StateType completionState = progressHandler.getCompletionState();
+    if (completionState.getValue() != StateType.COMPLETED.getValue()) {
+      // The state must be either FAILED, or RELEASED
+      return null;
+    }
+    TargetModuleID[] resultModuleIDs = progress.getResultTargetModuleIDs();
+    if (resultModuleIDs.length < 1) {
+      // There should be atleast one target module id if progress is
+      // successfully complete
+      return null;
+    }
+    return resultModuleIDs[0];
+  }
+
+  public boolean testDistributeModule(ModuleType moduleType, File moduleArchive,
+      File deploymentPlan, String archiveType, boolean oneDotFiveApi)
+      throws Exception {
+    DeploymentManager dm = getDeploymentManager();
+    Target[] targets = dm.getTargets();
+    if (targets.length == 0)
+      return false;
+    Target targetToDeploy = targets[0];
+    TargetModuleID distributedModuleID = null;
+    TargetModuleID[] moduleIDsBeforeDistribute = dm
+        .getAvailableModules(moduleType, new Target[] { targetToDeploy });
+    if (archiveType.equals(FILE_ARCHIVE)) {
+      distributedModuleID = distributeModuleArchive(
+          new Target[] { targetToDeploy }, moduleArchive, deploymentPlan);
+    } else {
+      FileInputStream moduleStream = (moduleArchive == null) ? null
+          : new FileInputStream(moduleArchive);
+      FileInputStream planStream = (deploymentPlan == null) ? null
+          : new FileInputStream(deploymentPlan);
+      distributedModuleID = distributeModuleStream(
+          new Target[] { targetToDeploy }, moduleType, moduleStream, planStream,
+          oneDotFiveApi);
+    }
+    // If the distributedModuleID == null, the test is failed
+    if (distributedModuleID == null)
+      return false;
+    // Check if distriburtedModuleID has the same target as deployed target
+    if (!distributedModuleID.getTarget().getName()
+        .equals(targetToDeploy.getName()))
+      return false;
+    TargetModuleID[] moduleIDsAfterDistribute = dm
+        .getAvailableModules(moduleType, new Target[] { targetToDeploy });
+    boolean moduleExistsBeforeDistribute = checkIfModuleExists(
+        distributedModuleID, moduleIDsBeforeDistribute);
+    boolean moduleExistsAfterDistribute = checkIfModuleExists(
+        distributedModuleID, moduleIDsAfterDistribute);
+
+    // Clean up....
+    // undeploy the module
+    undeployModule(distributedModuleID);
+
+    if ((!moduleExistsBeforeDistribute) && moduleExistsAfterDistribute)
+      return true;
+    else
+      return false;
+  }
+
+  public boolean testStartModule(ModuleType moduleType, File moduleArchive,
+      File deploymentPlan, String archiveType) throws Exception {
+    DeploymentManager dm = getDeploymentManager();
+    Target[] targets = dm.getTargets();
+    if (targets.length == 0)
+      return false;
+    Target targetToDeploy = targets[0];
+    TargetModuleID distributedModuleID = null;
+    TargetModuleID[] moduleIDsBeforeDistribute = dm
+        .getAvailableModules(moduleType, new Target[] { targetToDeploy });
+    if (archiveType.equals(FILE_ARCHIVE)) {
+      distributedModuleID = distributeModuleArchive(
+          new Target[] { targetToDeploy }, moduleArchive, deploymentPlan);
+    } else {
+      distributedModuleID = distributeModuleStream(
+          new Target[] { targetToDeploy }, moduleType,
+          new FileInputStream(moduleArchive),
+          new FileInputStream(deploymentPlan), true);
+    }
+    // If the distributedModuleID == null, the test is failed
+    if (distributedModuleID == null)
+      return false;
+    // Check if distriburtedModuleID has the same target as deployed target
+    if (!distributedModuleID.getTarget().getName()
+        .equals(targetToDeploy.getName()))
+      return false;
+    TargetModuleID[] moduleIDsAfterDistribute = dm
+        .getAvailableModules(moduleType, new Target[] { targetToDeploy });
+    boolean moduleExistsBeforeDistribute = checkIfModuleExists(
+        distributedModuleID, moduleIDsBeforeDistribute);
+    boolean moduleExistsAfterDistribute = checkIfModuleExists(
+        distributedModuleID, moduleIDsAfterDistribute);
+    if (!((!moduleExistsBeforeDistribute) && moduleExistsAfterDistribute))
+      return false;
+
+    // start the module
+    TargetModuleID startedModuleID = null;
+    startedModuleID = startModule(distributedModuleID);
+    if (startedModuleID == null)
+      return false;
+    // Check that the startedModuleID is same as deployed module id
+    if (!startedModuleID.getModuleID()
+        .equals(distributedModuleID.getModuleID()))
+      return false;
+    TargetModuleID[] runningModules = dm.getRunningModules(moduleType,
+        new Target[] { targetToDeploy });
+    boolean result = false;
+    if (checkIfModuleExists(startedModuleID, runningModules))
+      result = true;
+    // Clean up....
+    // undeploy the module
+    stopModule(startedModuleID);
+    undeployModule(startedModuleID);
+
+    return result;
+
+  }
+
+  public boolean testStopModule(ModuleType moduleType, File moduleArchive,
+      File deploymentPlan, String archiveType) throws Exception {
+    DeploymentManager dm = getDeploymentManager();
+    Target[] targets = dm.getTargets();
+    if (targets.length == 0)
+      return false;
+    Target targetToDeploy = targets[0];
+    TargetModuleID distributedModuleID = null;
+    TargetModuleID[] moduleIDsBeforeDistribute = dm
+        .getAvailableModules(moduleType, new Target[] { targetToDeploy });
+    if (archiveType.equals(FILE_ARCHIVE)) {
+      distributedModuleID = distributeModuleArchive(
+          new Target[] { targetToDeploy }, moduleArchive, deploymentPlan);
+    } else {
+      distributedModuleID = distributeModuleStream(
+          new Target[] { targetToDeploy }, moduleType,
+          new FileInputStream(moduleArchive),
+          new FileInputStream(deploymentPlan), true);
+    }
+    // If the distributedModuleID == null, the test is failed
+    if (distributedModuleID == null)
+      return false;
+    // Check if distriburtedModuleID has the same target as deployed target
+    if (!distributedModuleID.getTarget().getName()
+        .equals(targetToDeploy.getName()))
+      return false;
+    TargetModuleID[] moduleIDsAfterDistribute = dm
+        .getAvailableModules(moduleType, new Target[] { targetToDeploy });
+    boolean moduleExistsBeforeDistribute = checkIfModuleExists(
+        distributedModuleID, moduleIDsBeforeDistribute);
+    boolean moduleExistsAfterDistribute = checkIfModuleExists(
+        distributedModuleID, moduleIDsAfterDistribute);
+    if (!((!moduleExistsBeforeDistribute) && moduleExistsAfterDistribute))
+      return false;
+
+    // start the module
+    TargetModuleID startedModuleID = null;
+    startedModuleID = startModule(distributedModuleID);
+    if (startedModuleID == null)
+      return false;
+    // Check that the startedModuleID is same as deployed module id
+    if (!startedModuleID.getModuleID()
+        .equals(distributedModuleID.getModuleID()))
+      return false;
+    TargetModuleID[] runningModules = dm.getRunningModules(moduleType,
+        new Target[] { targetToDeploy });
+    if (!checkIfModuleExists(startedModuleID, runningModules))
+      return false;
+
+    // stop the module
+    TargetModuleID stoppedModuleID = null;
+    stoppedModuleID = stopModule(startedModuleID);
+    if (stoppedModuleID == null)
+      return false;
+    // Check that the startedModuleID is same as redeployed module id
+    if (!startedModuleID.getModuleID().equals(stoppedModuleID.getModuleID()))
+      return false;
+    boolean modExistsInRunningMods = checkIfModuleExists(stoppedModuleID,
+        dm.getRunningModules(moduleType, new Target[] { targetToDeploy }));
+    boolean modExistsInNonRunningMods = checkIfModuleExists(stoppedModuleID,
+        dm.getNonRunningModules(moduleType, new Target[] { targetToDeploy }));
+
+    // Clean up....
+    // undeploy the module
+    undeployModule(stoppedModuleID);
+
+    if ((!modExistsInRunningMods) && modExistsInNonRunningMods)
+      return true;
+    else
+      return false;
+  }
+
+  public boolean testRedeployModule(ModuleType moduleType, File moduleArchive,
+      File deploymentPlan, String archiveType) throws Exception {
+    DeploymentManager dm = getDeploymentManager();
+    Target[] targets = dm.getTargets();
+    if (targets.length == 0)
+      return false;
+    Target targetToDeploy = targets[0];
+    TargetModuleID distributedModuleID = null;
+    TargetModuleID[] moduleIDsBeforeDistribute = dm
+        .getAvailableModules(moduleType, new Target[] { targetToDeploy });
+    if (archiveType.equals(FILE_ARCHIVE)) {
+      distributedModuleID = distributeModuleArchive(
+          new Target[] { targetToDeploy }, moduleArchive, deploymentPlan);
+    } else {
+      distributedModuleID = distributeModuleStream(
+          new Target[] { targetToDeploy }, moduleType,
+          new FileInputStream(moduleArchive),
+          new FileInputStream(deploymentPlan), true);
+    }
+    // If the distributedModuleID == null, the test is failed
+    if (distributedModuleID == null)
+      return false;
+    // Check if distriburtedModuleID has the same target as deployed target
+    if (!distributedModuleID.getTarget().getName()
+        .equals(targetToDeploy.getName()))
+      return false;
+    TargetModuleID[] moduleIDsAfterDistribute = dm
+        .getAvailableModules(moduleType, new Target[] { targetToDeploy });
+    boolean moduleExistsBeforeDistribute = checkIfModuleExists(
+        distributedModuleID, moduleIDsBeforeDistribute);
+    boolean moduleExistsAfterDistribute = checkIfModuleExists(
+        distributedModuleID, moduleIDsAfterDistribute);
+    if (!((!moduleExistsBeforeDistribute) && moduleExistsAfterDistribute))
+      return false;
+
+    // start the module
+    TargetModuleID startedModuleID = null;
+    startedModuleID = startModule(distributedModuleID);
+    if (startedModuleID == null)
+      return false;
+    // Check that the startedModuleID is same as deployed module id
+    if (!startedModuleID.getModuleID()
+        .equals(distributedModuleID.getModuleID()))
+      return false;
+    TargetModuleID[] runningModules = dm.getRunningModules(moduleType,
+        new Target[] { targetToDeploy });
+    if (!checkIfModuleExists(startedModuleID, runningModules))
+      return false;
+
+    // redeploy the module
+    TargetModuleID redeployedModuleID = null;
+    if (archiveType.equals(FILE_ARCHIVE)) {
+      redeployedModuleID = redeployModuleArchive(
+          new TargetModuleID[] { startedModuleID }, moduleArchive,
+          deploymentPlan);
+    } else {
+      redeployedModuleID = redeployModuleStream(
+          new TargetModuleID[] { startedModuleID },
+          new FileInputStream(moduleArchive),
+          new FileInputStream(deploymentPlan));
+    }
+    if (redeployedModuleID == null)
+      return false;
+    // Check that the startedModuleID is same as redeployed module id
+    if (!startedModuleID.getModuleID().equals(redeployedModuleID.getModuleID()))
+      return false;
+    TargetModuleID[] runningModulesAfterRedeploy = dm
+        .getRunningModules(moduleType, new Target[] { targetToDeploy });
+    boolean result = false;
+    if (checkIfModuleExists(redeployedModuleID, runningModulesAfterRedeploy))
+      result = true;
+
+    // Clean up....
+    // undeploy the module
+    stopModule(redeployedModuleID);
+    undeployModule(redeployedModuleID);
+
+    return result;
+  }
+
+  public boolean testUndeployModule(ModuleType moduleType, File moduleArchive,
+      File deploymentPlan, String archiveType) throws Exception {
+    DeploymentManager dm = getDeploymentManager();
+    Target[] targets = dm.getTargets();
+    if (targets.length == 0)
+      return false;
+    Target targetToDeploy = targets[0];
+    TargetModuleID distributedModuleID = null;
+    TargetModuleID[] moduleIDsBeforeDistribute = dm
+        .getAvailableModules(moduleType, new Target[] { targetToDeploy });
+    if (archiveType.equals(FILE_ARCHIVE)) {
+      distributedModuleID = distributeModuleArchive(
+          new Target[] { targetToDeploy }, moduleArchive, deploymentPlan);
+    } else {
+      distributedModuleID = distributeModuleStream(
+          new Target[] { targetToDeploy }, moduleType,
+          new FileInputStream(moduleArchive),
+          new FileInputStream(deploymentPlan), true);
+    }
+    // If the distributedModuleID == null, the test is failed
+    if (distributedModuleID == null)
+      return false;
+    // Check if distriburtedModuleID has the same target as deployed target
+    if (!distributedModuleID.getTarget().getName()
+        .equals(targetToDeploy.getName()))
+      return false;
+    TargetModuleID[] moduleIDsAfterDistribute = dm
+        .getAvailableModules(moduleType, new Target[] { targetToDeploy });
+    boolean moduleExistsBeforeDistribute = checkIfModuleExists(
+        distributedModuleID, moduleIDsBeforeDistribute);
+    boolean moduleExistsAfterDistribute = checkIfModuleExists(
+        distributedModuleID, moduleIDsAfterDistribute);
+    if (!((!moduleExistsBeforeDistribute) && moduleExistsAfterDistribute))
+      return false;
+
+    // start the module
+    TargetModuleID undeployedModuleID = null;
+    undeployedModuleID = undeployModule(distributedModuleID);
+    if (undeployedModuleID == null)
+      return false;
+    // Check that the startedModuleID is same as deployed module id
+    if (!undeployedModuleID.getModuleID()
+        .equals(distributedModuleID.getModuleID()))
+      return false;
+    if (checkIfModuleExists(undeployedModuleID,
+        dm.getAvailableModules(moduleType, new Target[] { targetToDeploy })))
+      return false;
+    else
+      return true;
+  }
+
+  // To test TargetModuleID
+  // Test TargetModuleID
+  public boolean testTargetModuleID(File moduleArchive, File deploymentPlan,
+      String archiveType) {
+    try {
+      DeploymentManager dm = getDeploymentManager();
+      Target[] targets = dm.getTargets();
+      if (targets.length == 0)
+        return false;
+      Target targetToDeploy = targets[0];
+      TargetModuleID distributedModuleID = null;
+      distributedModuleID = distributeModuleArchive(
+          new Target[] { targetToDeploy }, moduleArchive, deploymentPlan);
+      // If the distributedModuleID == null, the test is failed
+      if (distributedModuleID == null)
+        return false;
+      // Check if distriburtedModuleID has the same target as deployed target
+      if (!distributedModuleID.getTarget().getName()
+          .equals(targetToDeploy.getName()))
+        return false;
+
+      // Clean up....
+      // undeploy the module
+      undeployModule(distributedModuleID);
+
+      return true;
+    } catch (Exception ex) {
+      ex.printStackTrace();
+      return false;
+    }
+  }
+
+  //////
+  // Porting package 1.4 additions
+  //////
+
+  /*
+   * Why are we polling on the progress object's state to determine when the
+   * executed command is actually finished? First, Prakash mentioned that there
+   * is a case where it is possible for an executed command to finish before the
+   * user is even returned the progress object. In this case if we register a
+   * ProgressListener with the ProgressObject and handle events within the
+   * ProgressListener's handleProgressEvent() we may miss the event that told us
+   * the executed command had finished. Second, again according to Prakash, the
+   * spec does not specify how many events are generated when executing a
+   * command. For instance, if we call stop and pass 4 TargetModuleID objects,
+   * there is no place in the spec that tells us how many events we should
+   * expect. There could be a set of one or more events for each target or a
+   * single event for all the targets. Since the spec doesn't define this, we
+   * shouldn't assume.
+   *
+   * Having said that we decided to simply poll the progress object and ask it
+   * when it thinks it is finished. This will be denoted by a COMPLETED or
+   * FAILED state. If the state is FAILED we can use the
+   * getResultTargetModuleIds method to determine the failed targets. We can
+   * determine the failed targets by comparing the targets we issued the command
+   * for against the targets returned by getResultTargetModuleIds. The doc for
+   * getResultTargetModuleIds says it only returns the IDs of the targets that
+   * successfully completed the specified command. See the OperationStatus class
+   * for details on determining the failed targets.
+   */
+  private OperationStatus commandStatus(Target[] targets,
+      ProgressObject progress) {
+    OperationStatus status = null;
+    int sleepCount = 0;
+    int deployWaitMinutes = getDeployDelay();
+    final int MAX_SLEEP_COUNT = deployWaitMinutes * 60; // minutes to delay
+    while (!(progress.getDeploymentStatus().isCompleted()
+        || progress.getDeploymentStatus().isFailed())) {
+      try {
+        Thread.sleep(1 * 1000); // 1 second
+        if (++sleepCount >= MAX_SLEEP_COUNT) {
+          TestUtil.logErr("Error: DeployTestUtil.commandStatus() timed out"
+              + " waiting for operation to complete");
+          status = new OperationStatus(progress, targets, true);
+          break;
+        }
+      } catch (InterruptedException ie) {
+        break;
+      }
+    }
+    if (status == null) {
+      status = new OperationStatus(progress, targets);
+    }
+
+    return status;
+  }
+
+  private int getDeployDelay() {
+    int result = 5;
+    String delayStr = System.getProperty("DEPLOY_DELAY_IN_MINUTES", "5");
+    try {
+      result = Integer.parseInt(delayStr);
+    } catch (NumberFormatException nfe) {
+    }
+    TestUtil.logTrace(
+        "Maximum wait time for deployment is " + result + " minutes.");
+    return result;
+  }
+
+  private void writeFile(File aFile) {
+    FileInputStream in = null;
+    FileOutputStream out = null;
+    try {
+      in = new FileInputStream(aFile);
+      out = new FileOutputStream("/tmp/" + aFile.getName());
+      byte[] buf = new byte[2048];
+      int start = 0;
+      int i = 0;
+      while ((i = in.read(buf)) != -1) {
+        out.write(buf, 0, i);
+        start += i;
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    } finally {
+      try {
+        in.close();
+      } catch (Exception e) {
+      }
+      try {
+        out.close();
+      } catch (Exception e) {
+      }
+    }
+  }
+
+  public OperationStatus distributeModuleStreams(Target[] targets,
+      InputStream moduleArchive, InputStream deploymentPlan) throws Exception {
+    ProgressObject progress = null;
+    try {
+      progress = getDeploymentManager().distribute(targets, moduleArchive,
+          deploymentPlan);
+    } catch (Exception e) {
+      e.printStackTrace();
+      if (progress.isCancelSupported()) {
+        progress.cancel();
+      }
+      throw e;
+    }
+    OperationStatus result = commandStatus(targets, progress);
+    delay();
+    return result;
+  }
+
+  public OperationStatus distributeModuleFiles(Target[] targets,
+      File moduleArchive, File deploymentPlan) throws Exception {
+    ProgressObject progress = null;
+    try {
+      progress = getDeploymentManager().distribute(targets, moduleArchive,
+          deploymentPlan);
+    } catch (Exception e) {
+      e.printStackTrace();
+      if (progress.isCancelSupported()) {
+        progress.cancel();
+      }
+      throw e;
+    }
+    OperationStatus result = commandStatus(targets, progress);
+    delay();
+    return result;
+  }
+
+  public Target[] getTargets() throws Exception {
+    Target[] result = null;
+    result = getDeploymentManager().getTargets();
+    return result;
+  }
+
+  public OperationStatus stopModule(TargetModuleID[] modulesIDsToStop)
+      throws Exception {
+    ProgressObject progress = null;
+    try {
+      progress = getDeploymentManager().stop(modulesIDsToStop);
+    } catch (Exception e) {
+      e.printStackTrace();
+      // throw e;
+    }
+    return commandStatus(convertTargets(modulesIDsToStop), progress);
+  }
+
+  public OperationStatus startModule(TargetModuleID[] modulesIDsToStart)
+      throws Exception {
+    ProgressObject progress = null;
+    try {
+      progress = getDeploymentManager().start(modulesIDsToStart);
+    } catch (Exception e) {
+      e.printStackTrace();
+      // throw e;
+    }
+    return commandStatus(convertTargets(modulesIDsToStart), progress);
+  }
+
+  public OperationStatus undeployModule(TargetModuleID[] modulesIDsToUndeploy)
+      throws Exception {
+    ProgressObject progress = null;
+    try {
+      progress = getDeploymentManager().undeploy(modulesIDsToUndeploy);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+    OperationStatus result = commandStatus(convertTargets(modulesIDsToUndeploy),
+        progress);
+    delay();
+    return result;
+  }
+
+  private void delay() {
+    try {
+      int delayTime = Integer
+          .parseInt(System.getProperty("delay.after.deploy", "0"));
+      if (delayTime != 0) {
+        System.err.println("%%%%%%%%% SLEEPING FOR " + delayTime + " SECONDS");
+        Thread.sleep(delayTime * 1000);
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  private Target[] convertTargets(TargetModuleID[] targets) {
+    if (targets == null) {
+      return null;
+    }
+    Target[] result = new Target[targets.length];
+    for (int i = 0; i < targets.length; i++) {
+      result[i] = targets[i].getTarget();
+    }
+    return result;
+  }
+
+  //////
+  // Porting package 1.4 additions
+  //////
+
+}
+
+class ProgressHandler extends Thread implements ProgressListener {
+  volatile StateType finalState = null;
+
+  public void run() {
+    while (finalState == null) {
+      Thread.currentThread().yield();
+    }
+  }
+
+  public void handleProgressEvent(ProgressEvent event) {
+    DeploymentStatus ds = event.getDeploymentStatus();
+    System.out.println(ds.getMessage() + "\n");
+    if (ds.getState().getValue() != StateType.RUNNING.getValue()) {
+      finalState = ds.getState();
+    }
+  }
+
+  public StateType getCompletionState() {
+    return finalState;
+  }
+}
diff --git a/src/main/java/org/apache/openejb/cts/deploy/OperationStatus.java b/src/main/java/org/apache/openejb/cts/deploy/OperationStatus.java
new file mode 100644
index 0000000..efdb3b8
--- /dev/null
+++ b/src/main/java/org/apache/openejb/cts/deploy/OperationStatus.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2007, 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.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.apache.openejb.cts.deploy;
+
+import javax.enterprise.deploy.spi.Target;
+import javax.enterprise.deploy.spi.status.ProgressObject;
+import javax.enterprise.deploy.spi.TargetModuleID;
+import java.util.List;
+import java.util.ArrayList;
+import com.sun.ts.lib.util.TestUtil;
+
+public class OperationStatus {
+  private boolean failed;
+
+  private String progressMessage;
+
+  private Target[] failedTargets;
+
+  private TargetModuleID[] deployedTargetIDs;
+
+  private ProgressObject progress;
+
+  public OperationStatus(ProgressObject progress, Target[] failedTargets) {
+    this(progress, failedTargets, progress.getDeploymentStatus().isFailed());
+  }
+
+  public OperationStatus(ProgressObject progress, Target[] failedTargets,
+      boolean failed) {
+    this.progress = progress;
+    this.failed = failed;
+    this.progressMessage = progress.getDeploymentStatus().getMessage();
+    this.failedTargets = failedTargets;
+    this.deployedTargetIDs = filterNonRootTargetModuleIDs(
+        progress.getResultTargetModuleIDs());
+  }
+
+  public boolean isFailed() {
+    return failed;
+  }
+
+  public String getProgressMessage() {
+    return progressMessage;
+  }
+
+  public Target[] getFailedTargets() {
+    return findErrors();
+  }
+
+  public TargetModuleID[] getDeployedTargetIDs() {
+    return deployedTargetIDs;
+  }
+
+  public ProgressObject getProgressObject() {
+    return progress;
+  }
+
+  /*
+   * Filter out the non-root target module IDs from the specified list. The JSR
+   * 88 spec is ambiguous as to what the ProgressObject.getResultTargetModuleIDs
+   * method returns. The list of target module IDs may be root target module IDs
+   * (those corresponding to an application or standalone module) only or root
+   * plus non-root target module IDs (those corresponding to modules that are
+   * part of a larger application). Since the harness is only interested in
+   * stopping, starting and undeploying applications or standalone components we
+   * filter out the non-root target module IDs since we don't do anything with
+   * them anyway. We also need to filter the non-root target module IDs because
+   * the spec is ambiguous as to what will happen if we pass a list of target
+   * module IDs that contain non-root IDs to the start, stop and undeploy
+   * methods (in the JSR 88 API). The spec does not state if these methods
+   * should throw an error, ignore the non-root target module IDs or take some
+   * other action. Since this is implementation specific we can not assume
+   * anything except for the fact that the start, stop and undeploy methods
+   * should have no affect on non-root modules since they can NOT be started,
+   * stopped or undeployed according to the spec. See section 4.1 in the JSR 88
+   * spec for details.
+   */
+  private TargetModuleID[] filterNonRootTargetModuleIDs(TargetModuleID[] ids) {
+    List result = new ArrayList();
+    for (int i = 0; i < ids.length; i++) {
+      TargetModuleID id = ids[i];
+      if (id.getParentTargetModuleID() == null) {
+        result.add(id);
+      }
+    }
+    return (TargetModuleID[]) (result
+        .toArray(new TargetModuleID[result.size()]));
+  }
+
+  private boolean targetInList(Target target, TargetModuleID[] list) {
+    boolean result = false;
+    for (int i = 0; i < list.length; i++) {
+      Target t = list[i].getTarget();
+      if (t.getName().equals(target.getName())) {
+        result = true;
+        break;
+      }
+    }
+    return result;
+  }
+
+  private Target[] findErrors() {
+    List failed = new ArrayList();
+    for (int i = 0; i < failedTargets.length; i++) {
+      if (!targetInList(failedTargets[i], deployedTargetIDs)) {
+        failed.add(failedTargets[i]);
+      }
+    }
+    return (Target[]) failed.toArray(new Target[failed.size()]);
+  }
+
+  public String errMessage() {
+    StringBuffer buf = new StringBuffer("Failed targets: ");
+    int numFailures = (failedTargets == null) ? 0 : failedTargets.length;
+    for (int i = 0; i < numFailures; i++) {
+      buf.append(failedTargets[i].getName() + "  ");
+    }
+
+    buf.append(TestUtil.NEW_LINE + "DeploymentStatus...");
+    buf.append(TestUtil.NEW_LINE + "Message             = "
+        + progress.getDeploymentStatus().getMessage());
+    buf.append(TestUtil.NEW_LINE + "State               = "
+        + progress.getDeploymentStatus().getState());
+    buf.append(TestUtil.NEW_LINE + "Command             = "
+        + progress.getDeploymentStatus().getCommand());
+    buf.append(TestUtil.NEW_LINE + "Action              = "
+        + progress.getDeploymentStatus().getAction());
+    buf.append(TestUtil.NEW_LINE + "Additional info     = "
+        + progress.getDeploymentStatus().toString() + TestUtil.NEW_LINE);
+
+    return buf.toString();
+  }
+
+}
diff --git a/src/main/java/org/apache/openejb/cts/deploy/StandardDeployment14.java b/src/main/java/org/apache/openejb/cts/deploy/StandardDeployment14.java
new file mode 100644
index 0000000..8145bca
--- /dev/null
+++ b/src/main/java/org/apache/openejb/cts/deploy/StandardDeployment14.java
@@ -0,0 +1,869 @@
+/*
+ * Copyright (c) 2007, 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.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.apache.openejb.cts.deploy;
+
+import javax.enterprise.deploy.spi.*;
+import javax.enterprise.deploy.shared.*;
+
+import java.io.*;
+import java.util.*;
+import com.sun.ts.lib.implementation.sun.javaee.runtime.SunRIDeploymentInfo;
+import com.sun.ts.lib.porting.*;
+import com.sun.ts.lib.util.*;
+import com.sun.ts.lib.deliverable.*;
+import com.sun.ts.lib.harness.ExecutionMode;
+
+/**
+ *
+ * This class implements the TSDeploymentInterface. It does so by using the 88
+ * API's. As of J2EE 1.4, this class should be the standard implementation of
+ * TSDeploymentInterface. There will be no need of alternative implentations.
+ * All implementation specific code now exists in TSDeploymentInterface2.
+ *
+ * @author Kyle Grucci
+ * @author Anand Dhingra
+ *
+ */
+public class StandardDeployment14 implements TSDeploymentInterface {
+
+  protected static final String DEPLOYED_MODULES_FILE = "ts-deployed-modules";
+
+  protected static String TEMP_DIR;
+
+  protected PrintWriter log; // Log to harness
+
+  protected int iPortingSet = 1; // Porting set using this impl
+                                 // of TSDeploymentInterface
+
+  private String url = "deployer:???:???:999"; // URI for DM
+
+  private DeploymentManager depMgr; // for Deployment to manager 1
+
+  private DeployTestUtil dtu; // for Deployment to manager 1
+
+  private DMProps dmProps; // get these from Propmgr
+
+  protected TSDeploymentInterface2 dep2; // our impl of
+  // TSDeploymentInterface2
+
+  protected Hashtable htDeployedModules = // Map ear files to IDs so we
+      new Hashtable(); // can later undeploy
+
+  protected PropertyManagerInterface propMgr; // Properties from ts.jte
+
+  protected String sDepNumber = null; // Module ID
+
+  protected String deployStateFile;
+
+  /**
+   *
+   * Static initialization of this class
+   *
+   */
+  static {
+    TestUtil.initJavaTest();
+    TEMP_DIR = System.getProperty("java.io.tmpdir");
+    if (TEMP_DIR != null && TEMP_DIR.endsWith(File.separator)) {
+      TEMP_DIR = TEMP_DIR.substring(0, TEMP_DIR.length() - 1);
+    }
+  }
+
+  /**
+   *
+   * Initializes logging output, gets the Deliverable instance
+   *
+   * @param writer - PrintWriter for harness tracing
+   *
+   */
+  public void init(PrintWriter writer) {
+
+    this.log = writer;
+    TestUtil.logHarness("StandardDeployment14.init()");
+
+    iPortingSet = TSDeployment.iPortingSet;
+    TestUtil
+        .logHarness("StandardDeployment14:  Using porting set #" + iPortingSet);
+
+    try {
+      propMgr = DeliverableFactory.getDeliverableInstance()
+          .getPropertyManager();
+
+      try {
+        String portingString = String.valueOf(iPortingSet);
+        initDeployTestUtils(portingString);
+        deployStateFile = TEMP_DIR + File.separator + DEPLOYED_MODULES_FILE
+            + "_" + portingString + ".ser";
+      } catch (TSDeploymentException e) {
+        TestUtil.logHarness("Unable to initialize the deployment utilities.");
+      }
+      htDeployedModules = getDeployedModules();
+      dumpDeployedMods(htDeployedModules);
+
+      TestUtil.logHarnessDebug("Adding shutdown hook for state serialization");
+
+      // Handle shutdown gracefully.
+      Runtime.getRuntime().addShutdownHook(new Thread() {
+
+        // When the VM shuts down this method is invoked to undeploy
+        // all currently deployed applications. Note, this method is
+        // invoked when a user issues a ctrl-c or the VM shuts down
+        // normally. No matter which way the VM shuts down, this
+        // method will honor the harness execute mode specified by
+        // the user in the ts.jte file (harness.executeMode property).
+        public void run() {
+
+          int harnessExecMode = ExecutionMode.getExecutionMode(propMgr);
+
+          // immediately return if we are running in a mode
+          // where undeploy is not required.
+          if (harnessExecMode == ExecutionMode.DEPLOY
+              || harnessExecMode == ExecutionMode.DEPLOY_RUN) {
+            try {
+              TestUtil.logHarness("IN SHUTDOWN HOOK BEFORE WRITE");
+              dumpDeployedMods(htDeployedModules);
+              writeMap(htDeployedModules);
+            } catch (IOException ioe) {
+              ioe.printStackTrace();
+            }
+            return;
+          } else if (harnessExecMode == ExecutionMode.RUN) {
+            return;
+          }
+          TestUtil.logHarness(
+              "IN SHUTDOWNHOOK state file is : \"" + deployStateFile + "\"");
+          dumpDeployedMods(htDeployedModules);
+          Map deployedModules = (Map) htDeployedModules.clone();
+          if (deployedModules.size() != 0) {
+            TestUtil.logHarness("Shutdown requested during test run."
+                + "  Undeploying previously deployed applications...");
+
+            try {
+              initDeployTestUtils(sDepNumber);
+            } catch (TSDeploymentException e) {
+              TestUtil.logHarness("Unable to initialize the deployment"
+                  + " utilities.  Applications will not be undeployed.");
+            }
+
+            for (Iterator i = deployedModules.keySet().iterator(); i
+                .hasNext();) {
+
+              try {
+                undeploy((String) i.next());
+              } catch (TSDeploymentException tde) {
+                TestUtil.logHarness("Unexpected exception while"
+                    + " undeploying application during shutdown. " + "Cause: "
+                    + tde.getMessage());
+              }
+
+            }
+            // Release deployment manager in case we get killed
+            // We'll also do this with the deploy and undeploy methods
+            // since this will only be called if a shutdown is received
+            dtu.releaseDeploymentManager();
+            deleteDeployedModulesState(); // remove deployed module state
+          }
+        }
+      });
+      String portClass = "porting.ts.deploy2.class." + iPortingSet;
+      TestUtil.logHarness("Using " + portClass);
+      dep2 = TSDeployment2.getDeploymentInstance(log, portClass);
+    } catch (Exception e) {
+      e.printStackTrace();
+      TestUtil.logHarness(
+          "Creation of TSDeployment2 implementation instance failed."
+              + " Please check the values of 'porting.ts.deploy2.class.1' and"
+              + " 'porting.ts.deploy2.class.2'");
+    }
+  }
+
+  public String deploy(DeploymentInfo info) throws TSDeploymentException {
+    try {
+      String sArchive = info.getEarFile();
+      // we need to pass the deployinfo to the new porting package to get the
+      // plan. For now just use the runtime file
+      String[] sRunTimeFileArray = info.getRuntimeFiles();
+
+      TestUtil.logHarness("StandardDeployment14.deploy()");
+      sDepNumber = info.getProperty("deployment.props.number");
+      initDeployTestUtils(sDepNumber);
+
+      // start distribute here
+      TestUtil.logHarness("Starting to distribute:  " + sArchive);
+
+      File earfile = new File(sArchive);
+      Object plan = dep2.getDeploymentPlan(info);
+
+      TestUtil.logHarness("file: " + earfile.toString());
+
+      if (plan != null)
+        TestUtil.logHarness("plan: " + plan.toString());
+      else
+        TestUtil.logHarness("No deployment plan for this archive.");
+
+      Target[] targets = dep2.getTargetsToUse(dtu.getTargets(), info);
+      if (targets == null || targets.length == 0)
+        throw new TSDeploymentException("Empty Target List: ");
+
+      OperationStatus status;
+
+      if (plan instanceof InputStream) {
+        // distribute the module
+        status = dtu.distributeModuleStreams(targets,
+            new FileInputStream(earfile), (InputStream) plan);
+      } else if ((plan instanceof File) || (plan == null)) {
+        // distribute the module
+        status = dtu.distributeModuleFiles(targets, earfile, (File) plan);
+      } else {
+        throw new TSDeploymentException(
+            "Object returned from getDeploymentPlan must return either an InputStream or a File."
+                + "  May also be null in some cases like connectors.");
+      }
+
+      if (status.isFailed()) {
+        throw new TSDeploymentException(
+            "Distribute to one or more targets failed " + status.errMessage());
+      }
+
+      TestUtil.logHarness(
+          "$$$$$$$$$$ Deployment SUCCEEDED for \"" + earfile + "\"");
+
+      // Allow the licensee an opportunity to examine the returned
+      // ProgressObject and
+      // take any vendor specifc actions that may be necessary.
+      dep2.postDistribute(status.getProgressObject());
+
+      status = dtu.startModule(status.getDeployedTargetIDs());
+      if (status.isFailed()) {
+        throw new TSDeploymentException(
+            "Starting of module failed on one or more targets "
+                + status.errMessage());
+      }
+
+      // Allow the licensee an opportunity to examine the returned
+      // ProgressObject and
+      // take any vendor specifc actions that may be necessary.
+      dep2.postStart(status.getProgressObject());
+
+      // keep track of filename to TargetmoduleIDs mapping
+      htDeployedModules.put(getAppName(sArchive),
+          status.getDeployedTargetIDs());
+
+      // Check to see if we're in a test directory that contains
+      // embedded rars
+      if (sArchive.indexOf("connector" + File.separator + "deployment"
+          + File.separator + "ejb_Deployment.ear") != -1) {
+
+        Properties p = new Properties();
+        p.setProperty("rar_file", sArchive);
+        dep2.createConnectionFactory(status.getDeployedTargetIDs(), p);
+      }
+
+      if (sArchive.indexOf("xa" + File.separator + "ee" + File.separator + "tsr"
+          + File.separator + "ejb_Tsr.ear") != -1) {
+
+        Properties p = new Properties();
+        p.setProperty("rar_file", sArchive);
+        dep2.createConnectionFactory(status.getDeployedTargetIDs(), p);
+      }
+
+      // if we have a rar file embedded in the ear, then we need to create
+      // connection factories - needsome naming we can rely on - don't want
+      // to open every ear file to check
+      String javaeeLevel = propMgr.getProperty("javaee.level", "full");
+
+      if (javaeeLevel.contains("full") && !sArchive.endsWith(".rar")) {
+        return dep2.getClientClassPath(status.getDeployedTargetIDs(), info,
+            dtu.getDeploymentManager());
+      } else {
+        return "";
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw (TSDeploymentException) new TSDeploymentException(
+          "Deployment Failed.").initCause(e);
+    }
+  }
+
+  public void undeploy(String moduleId) throws TSDeploymentException {
+    ModuleType moduleType = getModuleType(moduleId);
+    TargetModuleID[] idsToUndeploy = (TargetModuleID[]) htDeployedModules
+        .get(getAppName(moduleId));
+
+    TestUtil.logHarnessDebug(
+        "$$$$$$$$$$$$$ idsToUndeploy.length = " + idsToUndeploy.length);
+    TestUtil.logHarnessDebug("$$$$$$$$$$$$$ Undeploying Module ID \""
+        + idsToUndeploy[0].getModuleID() + "\"");
+
+    if (idsToUndeploy == null) {
+      TestUtil.logHarness(
+          "idToUndeploy is null.  Assuming that the module is not currently deployed");
+      return;
+    } else {
+      TestUtil.logHarness("Undeploying module \"" + moduleId + "\"");
+    }
+
+    OperationStatus status = null;
+    try {
+      status = dtu.stopModule(idsToUndeploy);
+      if (status.isFailed()) {
+        // log a message but still try to undeploy all the modules
+        TestUtil.logHarness(
+            "Stop failed for one or more targets while undeploying module \""
+                + moduleId + "\"");
+      }
+
+      // Allow the licensee an opportunity to examine the returned
+      // ProgressObject and
+      // take any vendor specifc actions that may be necessary.
+      dep2.postStop(status.getProgressObject());
+
+      status = dtu.undeployModule(idsToUndeploy);
+      if (status.isFailed()) {
+        TestUtil.logHarness("Undeploy failed for one or more targets \""
+            + status.errMessage() + "\"");
+      }
+
+      // Allow the licensee an opportunity to examine the returned
+      // ProgressObject and
+      // take any vendor specifc actions that may be necessary.
+      dep2.postUndeploy(status.getProgressObject());
+
+      htDeployedModules.remove(getAppName(moduleId));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw new TSDeploymentException("Error while undeploying");
+    }
+    if (status.isFailed()) {
+      throw new TSDeploymentException(
+          "Undeploy failed for one or more targets \"" + status.errMessage()
+              + "\"");
+    }
+  }
+
+  public void undeploy(Properties p) throws TSDeploymentException {
+    String sArchive = p.getProperty("ear_file");
+    TestUtil.logHarness("StandardDeployment14.undeploy()");
+    initDeployTestUtils(p.getProperty("deployment.props.number"));
+
+    // Check to see if we're in a test directory that contains
+    // embedded rars
+    if (sArchive
+        .indexOf("connector" + File.separator + "deployment" + File.separator
+            + "ejb_Deployment.ear") != -1
+        || sArchive.indexOf("xa" + File.separator + "ee" + File.separator
+            + "tsr" + File.separator + "ejb_Tsr.ear") != -1) {
+      // we must have an embedded ra file in this ear
+      // we need to remove the connection factory
+      p.setProperty("rar_file", sArchive);
+      // call into new porting package to remove connection factories
+      TargetModuleID[] modulesToUndeploy = (TargetModuleID[]) (htDeployedModules
+          .get(getAppName(sArchive)));
+      if (modulesToUndeploy.length == 0) {
+        TestUtil
+            .logHarness("undeploy failed for application \"" + sArchive + "\"");
+        throw new TSDeploymentException(
+            "undeploy failed for application \"" + sArchive + "\"");
+      }
+      dep2.removeConnectionFactory(modulesToUndeploy, p);
+    }
+    this.undeploy(sArchive);
+  }
+
+  public boolean isDeployed(Properties p) throws TSDeploymentException {
+    TestUtil.logHarness("StandardDeployment14.isDeployed()");
+    String sArchive = p.getProperty("ear_file");
+    String sAppName = getAppName(sArchive);
+    // For now just assume that we started with clean servers
+    // and check our internal state hashtable
+    if (htDeployedModules == null) {
+      return false;
+    }
+
+    // resync the list of deployed modules with what the targets actually report
+    try {
+      normalizeMap(getTargets());
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+
+    TargetModuleID[] id = (TargetModuleID[]) htDeployedModules.get(sAppName);
+    if (id != null && id.length > 0) {
+      TestUtil.logHarnessDebug("StandardDeployment14.isDeployed():  "
+          + "After checking hashtable, id = " + sAppName);
+      return true;
+    } else {
+      TestUtil.logHarnessDebug("StandardDeployment14.isDeployed():  "
+          + "After checking hashtable, id = null");
+      return false;
+    }
+  }
+
+  public void deployConnector(Properties p) throws TSDeploymentException {
+    TestUtil.logHarness("StandardDeployment14.deployConnector()");
+    String sRarFileName = p.getProperty("rar_file");
+    DeploymentInfo info = null;
+    try {
+      info = new SunRIDeploymentInfo(sRarFileName, new String[] {});
+      info.setProperty("deployment.props.number",
+          p.getProperty("deployment.props.number"));
+      deploy(info); // adds deployed targets IDs to htDeployedModules
+      TargetModuleID[] targets = (TargetModuleID[]) (htDeployedModules
+          .get(getAppName(sRarFileName)));
+      dep2.createConnectionFactory(targets, p);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw new TSDeploymentException("Error while deploying Connector");
+    }
+
+    // call into new porting package to create connection factories
+    // If rar files now have runtime info, we will have to change the harness
+    // code
+    // to call deploy if we are using the StandardDeployment class. Our deploy
+    // method in here can check for rars and handle the connection factory
+    // logic.
+    // If old porting impls are used, then the harness wil still call these
+    // connector methods.
+  }
+
+  public void undeployConnector(Properties p) throws TSDeploymentException {
+    TestUtil.logHarness("StandardDeployment14.undeployConnector()");
+
+    if (isConnectorDeployed(p)) {
+      String rarFile = p.getProperty("rar_file");
+      // targets must have a non-empty list of TargetModuleIDs since
+      // isConnectorDeployed just checked it.
+      TargetModuleID[] targets = (TargetModuleID[]) (htDeployedModules
+          .get(getAppName(rarFile)));
+      dep2.removeConnectionFactory(targets, p);
+      p.setProperty("ear_file", rarFile);
+      undeploy(p);
+    } else {
+      TestUtil.logHarness(
+          "StandardDeployment14.undeployConnector() - " + "not undeploying.");
+    }
+  }
+
+  public boolean isConnectorDeployed(Properties p)
+      throws TSDeploymentException {
+    TestUtil.logHarness("StandardDeployment14.isConnectorDeployed()");
+    p.setProperty("ear_file", p.getProperty("rar_file"));
+    return isDeployed(p);
+  }
+
+  protected void initDeployTestUtils(String sPropNum)
+      throws TSDeploymentException {
+    try {
+      if (dtu != null) {
+        return;
+      }
+      String sJar = propMgr.getProperty("deployManagerJarFile." + sPropNum);
+      String sUri = propMgr.getProperty("deployManageruri." + sPropNum);
+      String sUname = propMgr.getProperty("deployManageruname." + sPropNum);
+      String sPassword = propMgr.getProperty("deployManagerpasswd." + sPropNum);
+
+      TestUtil.logHarnessDebug(
+          "StandardDeployment14.initDeployTestUtils() + sPropNum = "
+              + sPropNum);
+      TestUtil.logHarnessDebug("deployManagerJarFile:  " + sJar);
+      TestUtil.logHarnessDebug("deployManageruri:  " + sUri);
+      TestUtil.logHarnessDebug("deployManageruname:  " + sUname);
+      TestUtil.logHarnessDebug("deployManagerpasswd:  " + sPassword);
+
+      // Construct properties object for DM
+      dmProps = new DMProps(sJar, sUri, sUname, sPassword);
+
+      // Utility object for getting depMgr's
+      // dtu = DeployTestUtil.getDeployTestUtil(dmProps);
+      dtu = new DeployTestUtil(dmProps);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw new TSDeploymentException(
+          "Failed to get DeployTestUtil: " + e.getMessage());
+    }
+
+    // Construct the DM
+    // always initialize these in case props change in same VM of JavaTest
+    try {
+      depMgr = dtu.getDeploymentManager();
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      TestUtil.logHarness(
+          "Exception loading DeploymentFactoryManager factories: " + e);
+      throw new TSDeploymentException(
+          "Unable to get DeploymentManager: " + e.getMessage());
+    }
+  }
+
+  public String getAppClientArgs(Properties p) {
+    return dep2.getAppClientArgs(p);
+  }
+
+  public Hashtable getInteropJNDINames(DeploymentInfo[] infoArray) {
+    return dep2.getDependentValues(infoArray);
+  }
+
+  private static ModuleType getModuleType(String sArchive) {
+    String sExtension = sArchive.substring(sArchive.lastIndexOf(".") + 1);
+    ModuleType mt;
+
+    if (sExtension.equalsIgnoreCase("ear"))
+      mt = ModuleType.EAR;
+    else if (sExtension.equalsIgnoreCase("rar"))
+      mt = ModuleType.RAR;
+    else if (sExtension.equalsIgnoreCase("jar")) {
+      if (sArchive.indexOf("component") != -1)
+        mt = ModuleType.EJB;
+      else
+        mt = ModuleType.EJB; // Should this be CAR ?
+    } else if (sExtension.equalsIgnoreCase("war"))
+      mt = ModuleType.WAR;
+    else
+      mt = ModuleType.EAR;
+
+    return mt;
+  }
+
+  protected static String getAppName(String path) {
+    return path.substring(path.lastIndexOf(File.separator) + 1);
+  }
+
+  protected void dumpDeployedMods(Hashtable map) {
+    StringBuffer message = new StringBuffer("Deployed Modules: \n");
+    if (map == null || map.keySet() == null) {
+      TestUtil.logHarness("There are no deployed modules, returning");
+      return;
+    }
+    Iterator iter = map.keySet().iterator();
+    while (iter.hasNext()) {
+      String modName = (String) iter.next();
+      message.append("\t" + modName + "\n");
+    }
+    TestUtil.logHarness(message.toString());
+  }
+
+  protected boolean isValidTargetID(TargetModuleID targModID,
+      SerializableTargetID[] serTargModIDs) {
+    boolean result = false;
+    SerializableTargetID test = new SerializableTargetID(targModID);
+    for (int i = 0; i < serTargModIDs.length; i++) {
+      if (serTargModIDs[i].equals(test)) {
+        result = true;
+        break;
+      }
+    }
+    return result;
+  }
+
+  protected boolean isValidTargetID(TargetModuleID targModID,
+      TargetModuleID[] serTargModIDs) {
+    boolean result = false;
+    for (int i = 0; i < serTargModIDs.length; i++) {
+      if (serTargModIDs[i].equals(targModID)) {
+        result = true;
+        break;
+      }
+    }
+    return result;
+  }
+
+  protected TargetModuleID[] getRunningTargetModuleIDs(String sModuleName,
+      Target[] targets) throws Exception {
+    return depMgr.getRunningModules(getModuleType(sModuleName), targets);
+  }
+
+  /*
+   * This method is used to update our local hashtable (htDeployedModules) of
+   * deployed modules with the latest information from the targets that we've
+   * deployed them to.
+   */
+  protected void normalizeMap(Target[] targets) throws Exception {
+    List targModIDsList = null;
+
+    TestUtil.logHarnessDebug("Target[]");
+    for (int i = 0; i < targets.length; i++) {
+      TestUtil.logHarnessDebug("[" + targets[i].getDescription() + ", "
+          + targets[i].getName() + "]");
+    }
+
+    Hashtable result = new Hashtable();
+    Iterator iter = htDeployedModules.keySet().iterator();
+    while (iter.hasNext()) {
+      String modName = (String) iter.next();
+      TargetModuleID[] targModIDs = getRunningTargetModuleIDs(modName, targets);
+      if (targModIDs == null || targModIDs.length == 0) {
+        continue;
+      }
+      TestUtil.logHarnessDebug("****** Module name = \"" + modName + "\"");
+      TestUtil
+          .logHarnessDebug("****** targModIDs.length = " + targModIDs.length);
+      TestUtil.logHarnessDebug("TargetModuleID[]");
+      for (int i = 0; i < targModIDs.length; i++) {
+        TestUtil.logHarnessDebug("[" + targModIDs[i].getModuleID() + ", "
+            + targModIDs[i].getTarget().getDescription() + ", "
+            + targModIDs[i].getTarget().getName() + "]");
+      }
+
+      TargetModuleID[] savedIDs = (TargetModuleID[]) htDeployedModules
+          .get(modName);
+
+      TestUtil.logHarnessDebug("****** savedIDs.length = " + savedIDs.length);
+      TestUtil.logHarnessDebug("TargetModuleID[]");
+      for (int i = 0; i < savedIDs.length; i++) {
+        TestUtil.logHarnessDebug("[" + savedIDs[i].getModuleID() + "]");
+      }
+
+      targModIDsList = new ArrayList();
+      for (int i = 0; i < targModIDs.length; i++) {
+        if (isValidTargetID(targModIDs[i], savedIDs)) {
+          TestUtil.logHarnessDebug(
+              "&&&&&&&& Adding = " + targModIDs[i].getModuleID());
+          targModIDsList.add(targModIDs[i]);
+          TestUtil.logHarnessDebug(
+              "&&&&&&&& targModIDsList.size() is " + targModIDsList.size());
+          break;
+        }
+      }
+      if (targModIDsList.size() > 0) {
+        TargetModuleID[] validSavedIDs = (TargetModuleID[]) (targModIDsList
+            .toArray(new TargetModuleID[targModIDsList.size()]));
+        result.put(modName, validSavedIDs);
+      } else {
+        TestUtil.logHarnessDebug(
+            "$$$$$ We did not find any valid IDs :  " + modName);
+      }
+    }
+    TestUtil.logHarnessDebug("DUMP OF RESULT");
+    dumpDeployedMods(result);
+    TestUtil.logHarnessDebug("END DUMP OF RESULT END");
+    htDeployedModules = result;
+  }
+
+  // Read
+  protected Hashtable normalizeMap(Hashtable map, Target[] targets)
+      throws Exception {
+    List targModIDsList = null;
+
+    TestUtil.logHarnessDebug("Target[]");
+    for (int i = 0; i < targets.length; i++) {
+      TestUtil.logHarnessDebug("[" + targets[i].getDescription() + ", "
+          + targets[i].getName() + "]");
+    }
+
+    Hashtable result = new Hashtable();
+    Iterator iter = map.keySet().iterator();
+    while (iter.hasNext()) {
+      String modName = (String) iter.next();
+      TargetModuleID[] targModIDs = getRunningTargetModuleIDs(modName, targets);
+      if (targModIDs == null || targModIDs.length == 0) {
+        continue;
+      }
+      TestUtil.logHarnessDebug("****** Module name = \"" + modName + "\"");
+      TestUtil
+          .logHarnessDebug("****** targModIDs.length = " + targModIDs.length);
+      TestUtil.logHarnessDebug("TargetModuleID[]");
+      for (int i = 0; i < targModIDs.length; i++) {
+        TestUtil.logHarnessDebug("[" + targModIDs[i].getModuleID() + ", "
+            + targModIDs[i].getTarget().getDescription() + ", "
+            + targModIDs[i].getTarget().getName() + "]");
+      }
+
+      SerializableTargetID[] serIDs = (SerializableTargetID[]) map.get(modName);
+
+      TestUtil.logHarnessDebug("****** serIDs.length = " + serIDs.length);
+      TestUtil.logHarnessDebug("SerializableTargetModuleID[]");
+      for (int i = 0; i < serIDs.length; i++) {
+        TestUtil.logHarnessDebug("[" + serIDs[i].getModuleID() + "]");
+      }
+
+      targModIDsList = new ArrayList();
+      for (int i = 0; i < targModIDs.length; i++) {
+        if (isValidTargetID(targModIDs[i], serIDs)) {
+          TestUtil.logHarnessDebug(
+              "&&&&&&&& Adding = " + targModIDs[i].getModuleID());
+          targModIDsList.add(targModIDs[i]);
+          TestUtil.logHarnessDebug(
+              "&&&&&&&& targModIDsList.size() is " + targModIDsList.size());
+          break;
+        }
+      }
+      if (targModIDsList.size() > 0) {
+        TargetModuleID[] validSerIDs = (TargetModuleID[]) (targModIDsList
+            .toArray(new TargetModuleID[targModIDsList.size()]));
+        result.put(modName, validSerIDs);
+      }
+    }
+    TestUtil.logHarnessDebug("DUMP OF RESULT");
+    dumpDeployedMods(result);
+    TestUtil.logHarnessDebug("END DUMP OF RESULT END");
+    return result;
+  }
+
+  // Write
+  protected Hashtable normalizeMap(Hashtable map) {
+    Hashtable result = new Hashtable();
+    Iterator iter = map.keySet().iterator();
+    while (iter.hasNext()) {
+      String key = (String) iter.next();
+      TargetModuleID[] tmid = (TargetModuleID[]) map.get(key);
+      SerializableTargetID[] serIDs = new SerializableTargetID[tmid.length];
+      for (int i = 0; i < tmid.length; i++) {
+        serIDs[i] = new SerializableTargetID(tmid[i]);
+      }
+      result.put(key, serIDs);
+    }
+    return result;
+  }
+
+  protected void writeMap(Hashtable map) throws IOException {
+    deleteDeployedModulesState();
+    ObjectOutputStream oout = null;
+    Hashtable newMap = normalizeMap(map);
+    try {
+      oout = new ObjectOutputStream(new FileOutputStream(deployStateFile));
+      oout.writeObject(newMap);
+    } catch (IOException e) {
+      throw e;
+    } finally {
+      try {
+        oout.close();
+      } catch (Exception ee) {
+      }
+    }
+  }
+
+  protected Hashtable readMap() throws IOException {
+    Hashtable result = null;
+    File inFile = new File(deployStateFile);
+    if (inFile.isFile()) {
+      ObjectInputStream oin = null;
+      try {
+        oin = new ObjectInputStream(new FileInputStream(deployStateFile));
+        result = (Hashtable) (oin.readObject());
+      } catch (IOException e) {
+        throw e;
+      } catch (ClassNotFoundException cnfe) {
+        cnfe.printStackTrace();
+      } finally {
+        try {
+          oin.close();
+        } catch (Exception ee) {
+        }
+      }
+    }
+    return result;
+  }
+
+  protected Hashtable getDeployedModules() {
+    Hashtable result = null;
+    Hashtable serMap = null;
+    try {
+      serMap = readMap();
+    } catch (IOException e) {
+    }
+    if (serMap == null) {
+      result = new Hashtable();
+    } else {
+      try {
+        result = normalizeMap(serMap, getTargets());
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+    return result;
+  }
+
+  protected void deleteDeployedModulesState() {
+    try {
+      File removeMe = new File(
+          TEMP_DIR + File.separator + DEPLOYED_MODULES_FILE);
+      removeMe.delete();
+    } catch (Exception e) {
+    }
+  }
+
+  protected Target[] getTargets() {
+    // get the targets
+    return depMgr.getTargets();
+  }
+
+  protected static class SerializableTarget implements Serializable {
+    private String description;
+
+    private String name;
+
+    public SerializableTarget(Target target) {
+      this.description = target.getDescription();
+      this.name = target.getName();
+    }
+
+    public String getDescription() {
+      return description;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public boolean equals(Object obj) {
+      SerializableTarget that = null;
+      boolean result = false;
+      if (this instanceof SerializableTarget) {
+        that = (SerializableTarget) obj;
+        result = (description == null) ? that.getDescription() == null
+            : description.equals(that.getDescription());
+        result = result && ((name == null) ? that.getName() == null
+            : name.equals(that.getName()));
+      }
+      return result;
+    }
+  }
+
+  protected static class SerializableTargetID implements Serializable {
+    private SerializableTarget target;
+
+    private String moduleID;
+
+    public SerializableTargetID(TargetModuleID id) {
+      this.moduleID = id.getModuleID();
+      this.target = new SerializableTarget(id.getTarget());
+    }
+
+    public SerializableTarget getTarget() {
+      return target;
+    }
+
+    public String getModuleID() {
+      return moduleID;
+    }
+
+    public boolean equals(Object obj) {
+      boolean result = false;
+      SerializableTargetID that = null;
+      if (obj instanceof SerializableTargetID) {
+        that = (SerializableTargetID) obj;
+        result = (moduleID == null) ? that.getModuleID() == null
+            : moduleID.equals(that.getModuleID());
+        result = result && ((target == null) ? that.getTarget() == null
+            : target.equals(that.getTarget()));
+      }
+      return result;
+    }
+  }
+
+}
diff --git a/src/main/java/org/apache/openejb/cts/deploy/TSDeployment2.java b/src/main/java/org/apache/openejb/cts/deploy/TSDeployment2.java
new file mode 100644
index 0000000..7148b1d
--- /dev/null
+++ b/src/main/java/org/apache/openejb/cts/deploy/TSDeployment2.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package org.apache.openejb.cts.deploy;
+
+import java.io.*;
+import com.sun.ts.lib.deliverable.*;
+
+/**
+ * This is a factory class for creating instances of TSDeploymentInterface2. The
+ * implementation classes used are determined by the values of the porting
+ * package properties in TS_HOME/bin/ts.jte.
+ * 
+ * @author Kyle Grucci
+ */
+public class TSDeployment2 {
+  private static PropertyManagerInterface propMgr = null;
+
+  public static TSDeploymentInterface2 getDeploymentInstance(PrintWriter writer,
+      String sClassName) throws Exception {
+    return createInstance(sClassName, writer);
+  }
+
+  private static TSDeploymentInterface2 createInstance(String sClassName,
+      PrintWriter writer) throws Exception {
+    try {
+      propMgr = DeliverableFactory.getDeliverableInstance()
+          .getPropertyManager();
+
+      // create and initialize a new instance of the Deployment class
+      Class c = Class.forName(propMgr.getProperty(sClassName));
+      TSDeploymentInterface2 ctsDep1 = (TSDeploymentInterface2) c.newInstance();
+      ctsDep1.init(writer);
+      return ctsDep1;
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+}
diff --git a/src/main/java/org/apache/openejb/cts/deploy/TSDeploymentInterface2.java b/src/main/java/org/apache/openejb/cts/deploy/TSDeploymentInterface2.java
new file mode 100644
index 0000000..c901c77
--- /dev/null
+++ b/src/main/java/org/apache/openejb/cts/deploy/TSDeploymentInterface2.java
@@ -0,0 +1,38 @@
+package org.apache.openejb.cts.deploy;
+
+import com.sun.ts.lib.porting.DeploymentInfo;
+import com.sun.ts.lib.porting.TSDeploymentException;
+
+import java.io.PrintWriter;
+import java.util.Hashtable;
+import java.util.Properties;
+import javax.enterprise.deploy.spi.DeploymentManager;
+import javax.enterprise.deploy.spi.Target;
+import javax.enterprise.deploy.spi.TargetModuleID;
+import javax.enterprise.deploy.spi.status.ProgressObject;
+
+public interface TSDeploymentInterface2 {
+    void init(PrintWriter var1);
+
+    String getClientClassPath(TargetModuleID[] var1, DeploymentInfo var2, DeploymentManager var3) throws TSDeploymentException;
+
+    Object getDeploymentPlan(DeploymentInfo var1) throws TSDeploymentException;
+
+    void createConnectionFactory(TargetModuleID[] var1, Properties var2) throws TSDeploymentException;
+
+    void removeConnectionFactory(TargetModuleID[] var1, Properties var2) throws TSDeploymentException;
+
+    String getAppClientArgs(Properties var1);
+
+    Hashtable getDependentValues(DeploymentInfo[] var1);
+
+    Target[] getTargetsToUse(Target[] var1, DeploymentInfo var2);
+
+    void postDistribute(ProgressObject var1);
+
+    void postStart(ProgressObject var1);
+
+    void postStop(ProgressObject var1);
+
+    void postUndeploy(ProgressObject var1);
+}
