Merge pull request #23062 from smillidge/correct-cdi-api-fragment

Correct api fragment to reference the correct bundle
diff --git a/appserver/distributions/glassfish-common/pom.xml b/appserver/distributions/glassfish-common/pom.xml
index c8595e6..309ab57 100644
--- a/appserver/distributions/glassfish-common/pom.xml
+++ b/appserver/distributions/glassfish-common/pom.xml
@@ -17,17 +17,30 @@
 
 -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
+
     <parent>
         <groupId>org.glassfish.main.distributions</groupId>
         <artifactId>distributions</artifactId>
         <version>6.0.0-SNAPSHOT</version>
     </parent>
+
     <artifactId>glassfish-common</artifactId>
     <packaging>distribution-fragment</packaging>
+
     <name>GlassFish distribution Common module</name>
 
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.main.distributions</groupId>
+            <artifactId>nucleus-common</artifactId>
+            <version>${project.version}</version>
+            <type>zip</type>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
     <build>
         <resources>
             <resource>
@@ -70,14 +83,4 @@
             </plugin>
         </plugins>
     </build>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.glassfish.main.distributions</groupId>
-            <artifactId>nucleus-common</artifactId>
-            <version>${project.version}</version>
-            <type>zip</type>
-            <optional>true</optional>
-        </dependency>
-    </dependencies>
 </project>
diff --git a/appserver/distributions/glassfish-common/src/main/assembly/glassfish-common.xml b/appserver/distributions/glassfish-common/src/main/assembly/glassfish-common.xml
index 644c43b..2dbaaa8 100644
--- a/appserver/distributions/glassfish-common/src/main/assembly/glassfish-common.xml
+++ b/appserver/distributions/glassfish-common/src/main/assembly/glassfish-common.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2017, 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
@@ -17,15 +17,16 @@
 
 -->
 
-<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
 
     <id>stage-package</id>
+
     <formats>
         <format>dir</format>
     </formats>
 
     <includeBaseDirectory>false</includeBaseDirectory>
+
     <fileSets>
         <fileSet>
             <directory>${temp.dir}</directory>
diff --git a/appserver/distributions/glassfish-common/src/main/resources/bin/debug-asadmin b/appserver/distributions/glassfish-common/src/main/resources/bin/debug-asadmin
new file mode 100644
index 0000000..6af5318
--- /dev/null
+++ b/appserver/distributions/glassfish-common/src/main/resources/bin/debug-asadmin
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# Copyright (c) 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
+#
+
+# Always use JDK 1.6 or higher
+AS_INSTALL=`dirname "$0"`/../glassfish
+AS_INSTALL_LIB="$AS_INSTALL/lib"
+. "${AS_INSTALL}/config/asenv.conf"
+JAVA=java
+#Depends upon Java from ../config/asenv.conf
+if [ ${AS_JAVA} ]; then
+    JAVA=${AS_JAVA}/bin/java
+fi
+
+exec "$JAVA" -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=9008 -jar "$AS_INSTALL_LIB/client/appserver-cli.jar" "$@"
+
diff --git a/appserver/distributions/glassfish-common/src/main/resources/bin/debug-asadmin.bat b/appserver/distributions/glassfish-common/src/main/resources/bin/debug-asadmin.bat
new file mode 100755
index 0000000..965e548
--- /dev/null
+++ b/appserver/distributions/glassfish-common/src/main/resources/bin/debug-asadmin.bat
@@ -0,0 +1,34 @@
+@echo off

+REM

+REM  Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.

+REM

+REM  This program and the accompanying materials are made available under the

+REM  terms of the Eclipse Public License v. 2.0, which is available at

+REM  http://www.eclipse.org/legal/epl-2.0.

+REM

+REM  This Source Code may also be made available under the following Secondary

+REM  Licenses when the conditions for such availability set forth in the

+REM  Eclipse Public License v. 2.0 are satisfied: GNU General Public License,

+REM  version 2 with the GNU Classpath Exception, which is available at

+REM  https://www.gnu.org/software/classpath/license.html.

+REM

+REM  SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0

+REM

+

+

+REM  Always use JDK 1.6 or higher

+REM  Depends on Java from ..\glassfish\config\asenv.bat

+VERIFY OTHER 2>nul

+setlocal ENABLEEXTENSIONS

+if ERRORLEVEL 0 goto ok

+echo "Unable to enable extensions"

+exit /B 1

+:ok

+call "%~dp0..\glassfish\config\asenv.bat"

+if "%AS_JAVA%x" == "x" goto UsePath

+set JAVA="%AS_JAVA%\bin\java"

+goto run

+:UsePath

+set JAVA=java

+:run

+%JAVA% -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=9008 -jar "%~dp0..\glassfish\lib\client\appserver-cli.jar" %*

diff --git a/appserver/pom.xml b/appserver/pom.xml
index a4f8a5a..44830a4 100644
--- a/appserver/pom.xml
+++ b/appserver/pom.xml
@@ -134,8 +134,8 @@
 
         <!-- Jakarta Batch -->
         <jakarta.batch-api.version>2.0.0-M2</jakarta.batch-api.version>
-        <com.ibm.jbatch.container.version>2.0.0-M1</com.ibm.jbatch.container.version>
-        <com.ibm.jbatch.spi.version>2.0.0-M1</com.ibm.jbatch.spi.version>
+        <com.ibm.jbatch.container.version>2.0.0-M2</com.ibm.jbatch.container.version>
+        <com.ibm.jbatch.spi.version>2.0.0-M2</com.ibm.jbatch.spi.version>
 
         <!-- Jakarta Enterprise beans -->
         <jakarta.ejb-api.version>4.0.0-RC2</jakarta.ejb-api.version>
@@ -152,8 +152,8 @@
         <jsp-impl.version>3.0.0-RC1</jsp-impl.version>
 
         <!-- Used for Jakarta XML Web Services -->
-        <woodstox.version>5.1.0</woodstox.version>
-        <stax2-api.version>4.1</stax2-api.version>
+        <woodstox.version>5.3.0</woodstox.version>
+        <stax2-api.version>4.2.1</stax2-api.version>
 
         <!-- Jakarta Standard Tag Library -->
         <jstl-api.version>2.0.0-RC1</jstl-api.version>
@@ -556,7 +556,7 @@
             <dependency>
                 <groupId>commons-io</groupId>
                 <artifactId>commons-io</artifactId>
-                <version>2.6</version>
+                <version>2.7</version>
             </dependency>
             <dependency>
                 <groupId>com.sun.woodstock.dependlibs</groupId>
diff --git a/docs/reference-manual/src/main/jbake/content/asadmin.adoc b/docs/reference-manual/src/main/jbake/content/asadmin.adoc
index 91c5f3e..9b7db13 100644
--- a/docs/reference-manual/src/main/jbake/content/asadmin.adoc
+++ b/docs/reference-manual/src/main/jbake/content/asadmin.adoc
@@ -1,7 +1,7 @@
 type=page
 status=published
 title=asadmin
-next=capture-schema.html
+next=debug-asadmin.html
 prev=appclient.html
 ~~~~~~
 asadmin
diff --git a/docs/reference-manual/src/main/jbake/content/debug-asadmin.adoc b/docs/reference-manual/src/main/jbake/content/debug-asadmin.adoc
new file mode 100644
index 0000000..4103aaa
--- /dev/null
+++ b/docs/reference-manual/src/main/jbake/content/debug-asadmin.adoc
@@ -0,0 +1,54 @@
+type=page
+status=published
+title=debug-asadmin
+next=capture-schema.html
+prev=asadmin.html
+~~~~~~
+debug-asadmin
+=======
+
+The script content on this page is for navigation purposes only and does
+not alter the content in any way.
+
+[[debug-asadmin-1m]][[GSRFM00263]][[debug-asadmin]]
+
+debug-asadmin
+-------
+
+Variant of the `asadmin` utility for performing administrative tasks for Oracle \{product---name}. This variant
+is useful for debugging local admin commands the launching of \{product---name}. It suspends immediately 
+waiting for a debug connection to port 9008.
+
+[[sthref2364]]
+
+Synopsis
+
+[source,oac_no_warn]
+----
+debug-asadmin [--host host] 
+[--port port] 
+[--user admin-user] 
+[--passwordfile filename] 
+[--terse={true|false}] 
+[--secure={false|true}] 
+[--echo={true|false}] 
+[--interactive={true|false}] 
+[--detach={true|false}]
+[--help] 
+[subcommand [options] [operands]]
+----
+
+[[sthref2365]]
+
+Description
+
+Use the `debug-asadmin` utility to debug local admin commands and the launching of the Oracle
+GlassFish Server. See the `asadmin` command for full documentation.
+
+
+http://www.oracle.com/pls/topic/lookup?ctx=E18752&id=REFMAN5attributes-5[`attributes`(5)]
+
+'''''
+
+
+
diff --git a/docs/reference-manual/src/main/jbake/content/start-domain.adoc b/docs/reference-manual/src/main/jbake/content/start-domain.adoc
index b82a904..457715e 100644
--- a/docs/reference-manual/src/main/jbake/content/start-domain.adoc
+++ b/docs/reference-manual/src/main/jbake/content/start-domain.adoc
@@ -21,7 +21,7 @@
 [source,oac_no_warn]
 ----
 asadmin [asadmin-options] start-domain [--help] 
-[--debug={true|false}] [--domaindir domain-dir] 
+[--debug={true|false}] [--suspend={true|false}] [--domaindir domain-dir] 
 [--dry-run={true|false}] [--upgrade={true|false}] 
 [--verbose={true|false}] [--watchdog={true|false}] 
 [domain-name]
@@ -81,14 +81,29 @@
   Specifies whether the domain is started with
   http://java.sun.com/javase/technologies/core/toolsapis/jpda/[Java
   Platform Debugger Architecture (JPDA)]
-  (http://www.oracle.com/technetwork/java/javase/tech/jpda-141715.html)
-  debugging enabled. +
+  (https://docs.oracle.com/en/java/javase/11/docs/specs/jpda/conninv.html)
+  debugging enabled. With debugging enabled extra exceptions can be printed. +
   Possible values are as follows: +
   `true`;;
     The instance is started with JPDA debugging enabled and the port
     number for JPDA debugging is displayed.
   `false`;;
     The instance is started with JPDA debugging disabled (default).
+`--suspend`::
+`-s`::
+  Specifies whether the domain is started with
+  http://java.sun.com/javase/technologies/core/toolsapis/jpda/[Java
+  Platform Debugger Architecture (JPDA)]
+  (https://docs.oracle.com/en/java/javase/11/docs/specs/jpda/conninv.html)
+  debugging enabled and suspend the newly started VM before the main class loads. 
+  When a debugger connects, it can send a JDWP command to resume the suspended VM.
+  With debugging enabled extra exceptions can be printed.
+  Possible values are as follows: +
+  `true`;;
+    The instance is started with JPDA debugging enabled and a suspendPolicy of `SUSPEND_ALL`.
+    The port number for JPDA debugging is displayed.
+  `false`;;
+    The instance is started with JPDA debugging disabled (default).
 `--dry-run`::
 `-n`::
   Suppresses actual starting of the domain. Instead, `start-domain`
@@ -201,6 +216,6 @@
 link:stop-domain.html#stop-domain-1[`stop-domain`(1)]
 
 Java Platform Debugger Architecture (JPDA)
-(http://www.oracle.com/technetwork/java/javase/tech/jpda-141715.html)
+(https://docs.oracle.com/en/java/javase/11/docs/specs/jpda/conninv.html)
 
 
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/ArgumentManager.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/ArgumentManager.java
index 82803dd..ee7ff41 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/ArgumentManager.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/ArgumentManager.java
@@ -16,78 +16,74 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
- * API -- For now sticking with the draft1 API and behavior
- * This class will be handy for fixing error detection of bad input as below.
- * 
- * -name1 value1 -name2 value2 value3 value4 value5 -name3 -name4 -name5
- * --> "-name1":"value1",  "-name2":"value2", "default":"value5", "-name3":"-name4" 
- * 
+ * API -- For now sticking with the draft1 API and behavior This class will be handy for fixing error detection of bad
+ * input as below.
+ *
+ * -name1 value1 -name2 value2 value3 value4 value5 -name3 -name4 -name5 --> "-name1":"value1", "-name2":"value2",
+ * "default":"value5", "-name3":"-name4"
+ *
  * @author bnevins
  */
 
-public class ArgumentManager 
-{
-    public static Map<String,String> argsToMap(String[] sargs)
-    {
-        ArgumentManager mgr = new ArgumentManager(sargs);
-        return mgr.getArgs();
-    }
- 
-    public static Map<String,String> argsToMap(List<String>sargs)
-    {
-        ArgumentManager mgr = new ArgumentManager(sargs);
-        return mgr.getArgs();
-    }
-    
-    ///////////////////////////////////////////////////////////////////////////
-    //////   ALL PRIVATE BELOW      ///////////////////////////////////////////
-    ///////////////////////////////////////////////////////////////////////////
-    
-    private ArgumentManager(String[] sargs)
-    {
-        args = new ArrayList<String>();
-        
-        for(String s : sargs)
-            args.add(s);
+public class ArgumentManager {
+
+    private Map<String, String> map = new HashMap<>();
+    private List<String> args;
+
+    public static Map<String, String> argsToMap(String[] sargs) {
+        return new ArgumentManager(sargs).getArgs();
     }
 
-    private ArgumentManager(List<String> sargs)
-    {
-        args = sargs;
+    public static Map<String, String> argsToMap(List<String> sargs) {
+        return new ArgumentManager(sargs).getArgs();
     }
 
-    private Map<String, String> getArgs()
-    {
-        int len = args.size();
-        
+    ///////////////////////////////////////////////////////////////////////////
+    ////// ALL PRIVATE BELOW ///////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+
+    private ArgumentManager(String[] arguments) {
+        args = new ArrayList<>();
+
+        for (String argument : arguments) {
+            args.add(argument);
+        }
+    }
+
+    private ArgumentManager(List<String> arguments) {
+        args = arguments;
+    }
+
+    private Map<String, String> getArgs() {
+        int argumentsSize = args.size();
+
         // short-circuit out of here!
-        if(len <= 0)
+        if (argumentsSize <= 0) {
             return map;
-        
-        for(int i = 0; i < len; i++)
-        {
+        }
+
+        for (int i = 0; i < argumentsSize; i++) {
             String name = args.get(i);
-            
-            if(name.startsWith("-"))
-            {
+
+            if (name.startsWith("-")) {
                 // throw it away if there is no value left
-                if(i + 1 < len)
-                {
+                if (i + 1 < argumentsSize) {
                     map.put(name, args.get(++i));
                 }
-            }
-            else
-            {
+            } else {
                 // default --> last one wins!
                 map.put("default", args.get(i));
             }
         }
+        
         return map;
     }
 
-    Map<String,String>  map     = new HashMap<String,String>();
-    List<String>        args;
+
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFDomainLauncher.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFDomainLauncher.java
index bc199c8..edc3f71 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFDomainLauncher.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFDomainLauncher.java
@@ -16,62 +16,69 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import com.sun.enterprise.universal.io.SmartFile;
+import static com.sun.enterprise.universal.io.SmartFile.sanitize;
+import static com.sun.enterprise.util.SystemPropertyConstants.INSTALL_ROOT_PROPERTY;
+
 import java.io.File;
-import java.util.*;
-import static com.sun.enterprise.util.SystemPropertyConstants.*;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
- * GFDomainLauncher
- * This class is a package-private subclass of GFLauncher designed for
- * domain launching
+ * GFDomainLauncher This class is a package-private subclass of GFLauncher designed for domain launching
+ *
  * @author bnevins
  */
 class GFDomainLauncher extends GFLauncher {
 
+
+    /* sample profiler config
+     *
+           <java-config classpath-suffix="" debug-enabled="false" debug-options="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9009" env-classpath-ignored="true" java-home="${com.sun.aas.javaRoot}" javac-options="-g" rmic-options="-iiop -poa -alwaysgenerate -keepgenerated -g" system-classpath="">
+            <profiler classpath="c:/dev/elf/dist/elf.jar" enabled="false" name="MyProfiler" native-library-path="c:/bin">
+              <jvm-options>-Dprofiler3=foo3</jvm-options>
+              <jvm-options>-Dprofiler2=foo2</jvm-options>
+              <jvm-options>-Dprofiler1=foof</jvm-options>
+            </profiler>
+     */
+
+    private static final String MAIN_CLASS = "com.sun.enterprise.glassfish.bootstrap.ASMain";
+    private static final String BOOTSTRAP_JAR = "glassfish.jar";
+
     GFDomainLauncher(GFLauncherInfo info) {
         super(info);
     }
 
+    @Override
     void internalLaunch() throws GFLauncherException {
         try {
             launchInstance();
-        }
-        catch (GFLauncherException ex) {
+        } catch (GFLauncherException ex) {
             throw ex;
-        }
-        catch (Exception ex) {
+        } catch (Exception ex) {
             throw new GFLauncherException(ex);
         }
     }
 
+    @Override
     List<File> getMainClasspath() throws GFLauncherException {
-        List<File> list = new ArrayList<File>();
-        File dir = new File(getEnvProps().get(INSTALL_ROOT_PROPERTY),"modules");
+        List<File> list = new ArrayList<>();
+        File dir = new File(getEnvProps().get(INSTALL_ROOT_PROPERTY), "modules");
 
         File bootjar = new File(dir, BOOTSTRAP_JAR);
-        if (!bootjar.exists() && !isFakeLaunch())
+        if (!bootjar.exists() && !isFakeLaunch()) {
             throw new GFLauncherException("nobootjar", dir.getPath());
+        }
 
-        if(bootjar.exists())
-            list.add(SmartFile.sanitize(bootjar));
+        if (bootjar.exists()) {
+            list.add(sanitize(bootjar));
+        }
 
         return list;
     }
 
+    @Override
     String getMainClass() throws GFLauncherException {
         return MAIN_CLASS;
     }
-    private static final String MAIN_CLASS = "com.sun.enterprise.glassfish.bootstrap.ASMain";
-    private static final String BOOTSTRAP_JAR = "glassfish.jar";
-}
 
-/* sample profiler config
- * 
-       <java-config classpath-suffix="" debug-enabled="false" debug-options="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9009" env-classpath-ignored="true" java-home="${com.sun.aas.javaRoot}" javac-options="-g" rmic-options="-iiop -poa -alwaysgenerate -keepgenerated -g" system-classpath="">
-        <profiler classpath="c:/dev/elf/dist/elf.jar" enabled="false" name="MyProfiler" native-library-path="c:/bin">
-          <jvm-options>-Dprofiler3=foo3</jvm-options>
-          <jvm-options>-Dprofiler2=foo2</jvm-options>
-          <jvm-options>-Dprofiler1=foof</jvm-options>
-        </profiler>
- */
+}
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFEmbeddedLauncher.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFEmbeddedLauncher.java
index 8527018..e29fec1 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFEmbeddedLauncher.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFEmbeddedLauncher.java
@@ -16,19 +16,43 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import com.sun.enterprise.util.io.FileUtils;
 import java.io.File;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+
 import com.sun.enterprise.universal.io.SmartFile;
 import com.sun.enterprise.universal.xml.MiniXmlParser;
 import com.sun.enterprise.universal.xml.MiniXmlParserException;
 import com.sun.enterprise.util.HostAndPort;
+import com.sun.enterprise.util.io.FileUtils;
 
 /**
  *
  * @author Byron Nevins
  */
 class GFEmbeddedLauncher extends GFLauncher {
+
+    private boolean setup = false;
+    private File gfeJar, runServerJar;
+    private File installDir;
+    private File javaExe;
+    private File domainDir;
+    private String javaDbClassPath, logFilename;
+    private static final String GFE_RUNSERVER_JAR = "GFE_RUNSERVER_JAR";
+    private static final String GFE_RUNSERVER_CLASS = "GFE_RUNSERVER_CLASS";
+    private static final String GFE_JAR = "GFE_JAR";
+    private static final String INSTALL_HOME = "S1AS_HOME";
+    private static final String JAVA_HOME = "JAVA_HOME";
+    // private static final String DOMAIN_DIR = "GFE_DOMAIN";
+    private static final String GENERAL_MESSAGE = " *********  GENERAL MESSAGE ********\n"
+            + "You must setup four different environmental variables to run embedded" + " with asadmin.  They are\n" + "GFE_JAR - path to the embedded jar\n"
+            + "S1AS_HOME - path to installation directory.  This can be empty or not exist yet.\n"
+            + "JAVA_HOME - path to a JDK installation.  JRE installation is generally not good enough\n"
+            + "GFE_DEBUG_PORT - optional debugging port.  It will start suspended.\n" + "\n*********  SPECIFIC MESSAGE ********\n";
+
+    private String[] DERBY_FILES = { "derby.jar", "derbyclient.jar", };
+
+
     public GFEmbeddedLauncher(GFLauncherInfo info) {
         super(info);
 
@@ -38,8 +62,7 @@
     void internalLaunch() throws GFLauncherException {
         try {
             launchInstance();
-        }
-        catch (Exception ex) {
+        } catch (Exception ex) {
             throw new GFLauncherException(ex);
         }
     }
@@ -52,8 +75,9 @@
     @Override
     String getMainClass() throws GFLauncherException {
         String className = System.getenv(GFE_RUNSERVER_CLASS);
-        if (className == null)
+        if (className == null) {
             return "org.glassfish.tests.embedded.EmbeddedMain";
+        }
         return className;
     }
 
@@ -62,25 +86,23 @@
         // remember -- this is designed exclusively for SQE usage
         // don't do it mmore than once -- that would be silly!
 
-
-        if (setup)
+        if (setup) {
             return;
-        else
+        } else {
             setup = true;
+        }
 
         try {
             setupFromEnv();
-        }
-        catch (GFLauncherException gfle) {
-            String msg = "";
+        } catch (GFLauncherException gfle) {
             throw new GFLauncherException(GENERAL_MESSAGE + gfle.getMessage());
         }
 
         setCommandLine();
 
-        /* it is NOT an error for there to be no domain.xml (yet).
-         * so eat exceptions.  Also just set the default to 4848 if we don't find
-         * the port...
+        /*
+         * it is NOT an error for there to be no domain.xml (yet). so eat exceptions. Also just set the default to 4848 if we
+         * don't find the port...
          */
 
         GFLauncherInfo info = getInfo();
@@ -90,8 +112,9 @@
             String domainName = info.getDomainName();
             String instanceName = info.getInstanceName();
 
-            if (instanceName == null)
+            if (instanceName == null) {
                 instanceName = "server";
+            }
 
             File dom = new File(parent, domainName);
             File theConfigDir = new File(dom, "config");
@@ -105,8 +128,7 @@
             logFile = new File(logFile, "server.log");
             logFilename = logFile.getAbsolutePath();
 
-        }
-        catch (Exception e) {
+        } catch (Exception e) {
             // temp todo
             e.printStackTrace();
         }
@@ -114,23 +136,21 @@
         List<HostAndPort> adminAddresses = info.getAdminAddresses();
 
         if (adminAddresses == null || adminAddresses.isEmpty()) {
-            adminAddresses = new ArrayList<HostAndPort>();
+            adminAddresses = new ArrayList<>();
             adminAddresses.add(new HostAndPort("localhost", 4848, false));
             info.setAdminAddresses(adminAddresses);
         }
         GFLauncherLogger.addLogFileHandler(getLogFilename(), info);
 
-        //super.fixLogFilename();
+        // super.fixLogFilename();
 
-    /*
-    String domainName = parser.getDomainName();
-    if(GFLauncherUtils.ok(domainName)) {
-    info.setDomainName(domainName);
-    }
-     */
+        /*
+         * String domainName = parser.getDomainName(); if(GFLauncherUtils.ok(domainName)) { info.setDomainName(domainName); }
+         */
 
     }
 
+    @Override
     public String getLogFilename() throws GFLauncherException {
         return logFilename;
     }
@@ -138,8 +158,9 @@
     @Override
     void setClasspath() {
         String classPath = gfeJar.getPath() + File.pathSeparator + javaDbClassPath;
-        if (runServerJar != null)
+        if (runServerJar != null) {
             classPath = classPath + File.pathSeparator + runServerJar.getPath();
+        }
         setClasspath(classPath);
     }
 
@@ -168,8 +189,7 @@
 
         if (ok(debugPort)) {
             suspend = "y";
-        }
-        else {
+        } else {
             debugPort = "12345";
             suspend = "n";
         }
@@ -188,7 +208,7 @@
 
         cmdLine.add("-XX:+UnlockDiagnosticVMOptions");
         cmdLine.add("-XX:+LogVMOutput");
-        cmdLine.add("-XX:LogFile="      + jvmLogFile.getPath());
+        cmdLine.add("-XX:LogFile=" + jvmLogFile.getPath());
     }
 
     private void setupFromEnv() throws GFLauncherException {
@@ -206,71 +226,76 @@
         domainDir = getInfo().getDomainParentDir();
         domainDir = new File(domainDir, domainDirName);
 
-        if (!FileUtils.mkdirsMaybe(domainDir))
+        if (!FileUtils.mkdirsMaybe(domainDir)) {
             throw new GFLauncherException("Can not create directory: " + domainDir);
+        }
 
         domainDir = SmartFile.sanitize(domainDir);
     }
 
     private void setupJDK() throws GFLauncherException {
-        String err = "You must set the environmental variable JAVA_HOME to point " +
-                "at a valid JDK.  <jdk>/bin/javac[.exe] must exist.";
+        String err = "You must set the environmental variable JAVA_HOME to point " + "at a valid JDK.  <jdk>/bin/javac[.exe] must exist.";
 
         String jdkDirName = System.getenv(JAVA_HOME);
-        if (!ok(jdkDirName))
+        if (!ok(jdkDirName)) {
             throw new GFLauncherException(err);
+        }
 
         File jdkDir = new File(jdkDirName);
 
-        if (!jdkDir.isDirectory())
+        if (!jdkDir.isDirectory()) {
             throw new GFLauncherException(err);
+        }
 
-        if (File.separatorChar == '\\')
+        if (File.separatorChar == '\\') {
             javaExe = new File(jdkDir, "bin/java.exe");
-        else
+        } else {
             javaExe = new File(jdkDir, "bin/java");
+        }
 
-        if (!javaExe.isFile())
+        if (!javaExe.isFile()) {
             throw new GFLauncherException(err);
+        }
 
         javaExe = SmartFile.sanitize(javaExe);
     }
 
     private void setupInstallationDir() throws GFLauncherException {
-        String err = "You must set the environmental variable S1AS_HOME to point " +
-                "at a GlassFish installation or at an empty directory or at a " +
-                "location where an empty directory can be created.";
+        String err = "You must set the environmental variable S1AS_HOME to point " + "at a GlassFish installation or at an empty directory or at a "
+                + "location where an empty directory can be created.";
         String installDirName = System.getenv(INSTALL_HOME);
 
-        if (!ok(installDirName))
+        if (!ok(installDirName)) {
             throw new GFLauncherException(err);
+        }
 
         installDir = new File(installDirName);
 
-        if(!FileUtils.mkdirsMaybe(installDir))
+        if (!FileUtils.mkdirsMaybe(installDir)) {
             throw new GFLauncherException(err);
+        }
 
         installDir = SmartFile.sanitize(installDir);
     }
 
     private void setupEmbeddedJars() throws GFLauncherException {
-        String err = "You must set the environmental variable GFE_JAR to point " +
-                "at the Embedded jarfile.";
+        String err = "You must set the environmental variable GFE_JAR to point " + "at the Embedded jarfile.";
 
         String gfeJarName = System.getenv(GFE_JAR);
 
-        if (!ok(gfeJarName))
+        if (!ok(gfeJarName)) {
             throw new GFLauncherException(err);
+        }
 
         gfeJar = new File(gfeJarName);
 
-        if (!gfeJar.isFile() || gfeJar.length() < 1000000L)
+        if (!gfeJar.isFile() || gfeJar.length() < 1000000L) {
             throw new GFLauncherException(err);
+        }
 
         gfeJar = SmartFile.sanitize(gfeJar);
 
-         err = "You must set the environmental variable GFE_RUNSERVER_JAR to point " +
-                "at the server startup jar.";
+        err = "You must set the environmental variable GFE_RUNSERVER_JAR to point " + "at the server startup jar.";
 
         String runServerJarName = System.getenv(GFE_RUNSERVER_JAR);
 
@@ -280,8 +305,9 @@
             }
             runServerJar = new File(runServerJarName);
 
-            if (!runServerJar.isFile())
+            if (!runServerJar.isFile()) {
                 throw new GFLauncherException(err);
+            }
 
             runServerJar = SmartFile.sanitize(runServerJar);
         }
@@ -290,61 +316,38 @@
 
     private void setupJavaDB() throws GFLauncherException {
         // It normally will be in either:
-        //  * install-dir/javadb/lib
-        //  * install-dir/../javadb/lib
+        // * install-dir/javadb/lib
+        // * install-dir/../javadb/lib
 
         String relPath = "javadb/lib";
         File derbyLib = new File(installDir, relPath);
 
-        if(!derbyLib.isDirectory())
+        if (!derbyLib.isDirectory()) {
             derbyLib = new File(installDir.getParentFile(), relPath);
+        }
 
-        if(!derbyLib.isDirectory())
+        if (!derbyLib.isDirectory()) {
             throw new GFLauncherException("Could not find the JavaDB lib directory.");
+        }
 
-        // we have a valid directory.  Let's verify the right jars are there!
+        // we have a valid directory. Let's verify the right jars are there!
 
         javaDbClassPath = "";
-        boolean firstItem = true;
-        for(String fname : DERBY_FILES) {
+        for (String fname : DERBY_FILES) {
             File f = new File(derbyLib, fname);
 
             javaDbClassPath += File.pathSeparator;
             javaDbClassPath += f.getPath();
 
-            if(!f.exists())
+            if (!f.exists()) {
                 throw new GFLauncherException("Could not find the JavaDB jar: " + f);
+            }
         }
     }
 
     private boolean ok(String s) {
         return s != null && s.length() > 0;
     }
-    private boolean setup = false;
-    private File gfeJar, runServerJar;
-    private File installDir;
-    private File javaExe;
-    private File domainDir;
-    private String javaDbClassPath, logFilename;
-    private static final String GFE_RUNSERVER_JAR = "GFE_RUNSERVER_JAR";
-    private static final String GFE_RUNSERVER_CLASS = "GFE_RUNSERVER_CLASS";
-    private static final String GFE_JAR = "GFE_JAR";
-    private static final String INSTALL_HOME = "S1AS_HOME";
-    private static final String JAVA_HOME = "JAVA_HOME";
-    //private static final String DOMAIN_DIR       = "GFE_DOMAIN";
-    private static final String GENERAL_MESSAGE =
-            " *********  GENERAL MESSAGE ********\n" +
-            "You must setup four different environmental variables to run embedded" +
-            " with asadmin.  They are\n" +
-            "GFE_JAR - path to the embedded jar\n" +
-            "S1AS_HOME - path to installation directory.  This can be empty or not exist yet.\n" +
-            "JAVA_HOME - path to a JDK installation.  JRE installation is generally not good enough\n" +
-            "GFE_DEBUG_PORT - optional debugging port.  It will start suspended.\n" +
-            "\n*********  SPECIFIC MESSAGE ********\n";
 
-    private String[] DERBY_FILES =
-    {
-        "derby.jar",
-        "derbyclient.jar",
-    };
+
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFInstanceLauncher.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFInstanceLauncher.java
index ceacda4..cb55cdd 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFInstanceLauncher.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFInstanceLauncher.java
@@ -16,46 +16,51 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import com.sun.enterprise.universal.io.SmartFile;
-import java.io.*;
-import java.util.*;
-import static com.sun.enterprise.util.SystemPropertyConstants.*;
+import static com.sun.enterprise.util.SystemPropertyConstants.INSTALL_ROOT_PROPERTY;
 
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.sun.enterprise.universal.io.SmartFile;
 
 /**
  *
  * @author bnevins
  */
-class GFInstanceLauncher extends GFLauncher{
+class GFInstanceLauncher extends GFLauncher {
+
+    private static final String MAIN_CLASS = "com.sun.enterprise.glassfish.bootstrap.ASMain";
+    private static final String BOOTSTRAP_JAR = "glassfish.jar";
 
     GFInstanceLauncher(GFLauncherInfo info) {
         super(info);
     }
-    
+
     @Override
     void internalLaunch() throws GFLauncherException {
         try {
             launchInstance();
-        }
-        catch (GFLauncherException ex) {
+        } catch (GFLauncherException ex) {
             throw ex;
-        }
-        catch (Exception ex) {
+        } catch (Exception ex) {
             throw new GFLauncherException(ex);
         }
     }
 
     @Override
     List<File> getMainClasspath() throws GFLauncherException {
-        List<File> list = new ArrayList<File>();
-        File dir = new File(getEnvProps().get(INSTALL_ROOT_PROPERTY),"modules");
+        List<File> list = new ArrayList<>();
+        File dir = new File(getEnvProps().get(INSTALL_ROOT_PROPERTY), "modules");
 
         File bootjar = new File(dir, BOOTSTRAP_JAR);
-        if (!bootjar.exists() && !isFakeLaunch())
+        if (!bootjar.exists() && !isFakeLaunch()) {
             throw new GFLauncherException("nobootjar", dir.getPath());
+        }
 
-        if(bootjar.exists())
+        if (bootjar.exists()) {
             list.add(SmartFile.sanitize(bootjar));
+        }
 
         return list;
     }
@@ -64,7 +69,5 @@
     String getMainClass() throws GFLauncherException {
         return MAIN_CLASS;
     }
-    
-    private static final String MAIN_CLASS = "com.sun.enterprise.glassfish.bootstrap.ASMain";
-    private static final String BOOTSTRAP_JAR = "glassfish.jar";
+
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncher.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncher.java
index d5d9ae3..d023f9c 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncher.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -16,64 +16,200 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import java.io.*;
-import java.util.*;
-import java.util.logging.Level;
-import com.sun.enterprise.universal.collections.CollectionUtils;
+import static com.sun.enterprise.admin.launcher.GFLauncher.LaunchType.fake;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.DEFAULT_LOGFILE;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.FLASHLIGHT_AGENT_NAME;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.LIBMON_NAME;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.NEWLINE;
+import static com.sun.enterprise.admin.launcher.GFLauncherLogger.COMMAND_LINE;
+import static com.sun.enterprise.admin.launcher.GFLauncherLogger.addLogFileHandler;
+import static com.sun.enterprise.universal.collections.CollectionUtils.propertiesToStringMap;
+import static com.sun.enterprise.universal.glassfish.GFLauncherUtils.ok;
+import static com.sun.enterprise.universal.io.SmartFile.sanitize;
+import static com.sun.enterprise.universal.process.ProcessStreamDrainer.dispose;
+import static com.sun.enterprise.universal.process.ProcessStreamDrainer.redirect;
+import static com.sun.enterprise.universal.process.ProcessStreamDrainer.save;
+import static com.sun.enterprise.util.OS.isDarwin;
+import static com.sun.enterprise.util.SystemPropertyConstants.DEBUG_MODE_PROPERTY;
+import static com.sun.enterprise.util.SystemPropertyConstants.DROP_INTERRUPTED_COMMANDS;
+import static com.sun.enterprise.util.SystemPropertyConstants.INSTALL_ROOT_PROPERTY;
+import static com.sun.enterprise.util.SystemPropertyConstants.INSTANCE_ROOT_PROPERTY;
+import static com.sun.enterprise.util.SystemPropertyConstants.JAVA_ROOT_PROPERTY;
+import static com.sun.enterprise.util.io.FileUtils.copyFile;
+import static java.lang.Boolean.TRUE;
+import static java.util.Collections.emptyList;
+import static java.util.logging.Level.INFO;
+import static java.util.logging.Level.WARNING;
+import static java.util.stream.Collectors.toList;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import com.sun.enterprise.universal.glassfish.ASenvPropertyReader;
 import com.sun.enterprise.universal.glassfish.GFLauncherUtils;
 import com.sun.enterprise.universal.glassfish.TokenResolver;
 import com.sun.enterprise.universal.i18n.LocalStringsImpl;
-import com.sun.enterprise.universal.io.SmartFile;
 import com.sun.enterprise.universal.process.ProcessStreamDrainer;
+import com.sun.enterprise.universal.xml.MiniXmlParser;
 import com.sun.enterprise.universal.xml.MiniXmlParserException;
 import com.sun.enterprise.util.OS;
-import com.sun.enterprise.util.SystemPropertyConstants;
 import com.sun.enterprise.util.io.FileUtils;
-import com.sun.enterprise.universal.glassfish.ASenvPropertyReader;
-import com.sun.enterprise.universal.xml.MiniXmlParser;
-import static com.sun.enterprise.util.SystemPropertyConstants.*;
-import static com.sun.enterprise.admin.launcher.GFLauncherConstants.*;
 
 /**
- * This is the main Launcher class designed for external and internal usage.
- * Each of the 3 kinds of server -- domain, node-agent and instance -- need to
- * subclass this class.
+ * This is the main Launcher class designed for external and internal usage. 
+ * 
+ * <p>
+ * Each of the 3 kinds of server, domain, node-agent and instance, need to subclass this class.
  *
  * @author bnevins
  */
 public abstract class GFLauncher {
-    ///////////////////////////////////////////////////////////////////////////
-    //////     PUBLIC api area starts here             ////////////////////////
-    ///////////////////////////////////////////////////////////////////////////
+    
+    private final static LocalStringsImpl strings = new LocalStringsImpl(GFLauncher.class);
+    
     /**
-     *
-     * @return The info object that contains startup info
+     * Parameters provided by the caller of a launcher, either programmatically (for GF embedded) or as
+     * commandline parameters (GF DAS or Instance).
+     * 
      */
-    public final GFLauncherInfo getInfo() {
-        return info;
+    private GFLauncherInfo callerParameters;
+    
+    /**
+     * Properties from asenv.conf, such as <code>AS_DEF_DOMAINS_PATH="../domains"</code>
+     */
+    private Map<String, String> asenvProps;
+    
+    /** 
+     * The <code>java-config</code> attributes in domain.xml
+     */
+    private JavaConfig domainXMLjavaConfig;
+    
+    /** 
+     * the <code>debug-options</code> attribute from <code>java-config</code> in domain.xml
+     */
+    private List<String> domainXMLjavaConfigDebugOptions;
+    
+    /**
+     * The debug port (<code>address</code>) primarily extracted from <code>domainXMLjavaConfigDebugOptions</code>
+     */
+    private int debugPort = -1;
+    
+    /**
+     * The debug suspend (<code>suspend</code>) primarily extracted from <code>domainXMLjavaConfigDebugOptions</code>
+     */
+    private boolean debugSuspend;
+    
+    /**
+     * The combined <code>jvm-options</code> from <code>java-config</code>, <code>profiler</code> in domain.xml and extra ones
+     * added by this launcher
+     */
+    private JvmOptions domainXMLjvmOptions;
+    
+    /**
+     * Same data as domainXMLjvmOptions, but as list
+     */
+    private List<String> domainXMLJvmOptionsAsList = new ArrayList<>();
+    
+    /**
+     * The <code>profiler<code> from <code>java-config</code> in domain.xml
+     */
+    private Profiler domainXMLJavaConfigProfiler;
+    
+    /**
+     * The (combined) <code>system-property</code> elements in domain.xml
+     */
+    private Map<String, String> domainXMLSystemProperty;
+    
+    private String javaExe;
+    private String classpath;
+    private String adminFileRealmKeyFile;
+    private boolean secureAdminEnabled;
+    
+    /**
+     * The file name to log to using a <code>java.util.logging.FileHandler.FileHandler</code>
+     */
+    private String logFilename; // defaults to "logs/server.log"
+    
+    /**
+     * Tracks whether the fixLogFileName() method was called.
+     */
+    private boolean logFilenameWasFixed;
+    
+    /**
+     * Tracks whether the setup() had been called and/or should be called again.
+     */
+    private boolean setupCalledByClients; // handle with care
+    
+    // Tracks upgrading from V2 to V3. Since we're at V6 atm of wring, is this really needed?
+    private boolean needsAutoUpgrade;
+    private boolean needsManualUpgrade;
+    
+    private LaunchType mode = LaunchType.normal;
+    
+    
+    /**
+     * The full commandline string used to start GlassFish in process <code<>glassFishProcess</code>
+     */
+    private List<String> commandLine = new ArrayList<>();
+    
+    /**
+     * Time when GlassFish was launched
+     */
+    private long startTime;
+    
+    /**
+     * The process which is running GlassFish
+     */
+    private Process glassFishProcess;
+    private ProcessWhacker processWhacker;
+    private ProcessStreamDrainer processStreamDrainer;
+    
+    /**
+     * Exit value of the glassFishProcess, IFF we waited on the process
+     */
+    private int exitValue = -1;
+    
+
+    GFLauncher(GFLauncherInfo info) {
+        this.callerParameters = info;
     }
 
+    ///////////////////////////////////////////////////////////////////////////
+    ////// PUBLIC api area starts here ////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+   
+
     /**
-     * Launches the server. Any fatal error results in a GFLauncherException No
-     * unchecked Throwables of any kind will be thrown.
+     * Launches the server. Any fatal error results in a GFLauncherException No unchecked Throwables of any kind will be
+     * thrown.
      *
      * @throws com.sun.enterprise.admin.launcher.GFLauncherException
      */
     public final void launch() throws GFLauncherException {
         try {
             startTime = System.currentTimeMillis();
-            if (!setupCalledByClients)
+            if (!setupCalledByClients) {
                 setup();
+            }
+            // Typically invokes launchInstance()
             internalLaunch();
-        }
-        catch (GFLauncherException gfe) {
+        } catch (GFLauncherException gfe) {
             throw gfe;
-        }
-        catch (Throwable t) {
+        } catch (Throwable t) {
             // hk2 might throw a java.lang.Error
             throw new GFLauncherException(strings.get("unknownError", t.getMessage()), t);
-        }
-        finally {
+        } finally {
             GFLauncherLogger.removeLogFileHandler();
         }
     }
@@ -90,98 +226,100 @@
 
     public final void launchJVM(List<String> cmdsIn) throws GFLauncherException {
         try {
-            setup();    // we only use one thing -- the java executable
-            List<String> commands = new LinkedList<String>();
+            setup(); // we only use one thing -- the java executable
+            List<String> commands = new LinkedList<>();
             commands.add(javaExe);
 
             for (String cmd : cmdsIn) {
                 commands.add(cmd);
             }
 
-            ProcessBuilder pb = new ProcessBuilder(commands);
-            Process p = pb.start();
-            ProcessStreamDrainer.drain("launchJVM", p); // just to be safe
-        }
-        catch (GFLauncherException gfe) {
+            ProcessBuilder processBuilder = new ProcessBuilder(commands);
+            Process process = processBuilder.start();
+            ProcessStreamDrainer.drain("launchJVM", process); // just to be safe
+        } catch (GFLauncherException gfe) {
             throw gfe;
-        }
-        catch (Throwable t) {
+        } catch (Throwable t) {
             // hk2 might throw a java.lang.Error
             throw new GFLauncherException(strings.get("unknownError", t.getMessage()), t);
-        }
-        finally {
+        } finally {
             GFLauncherLogger.removeLogFileHandler();
         }
     }
 
     public void setup() throws GFLauncherException, MiniXmlParserException {
-        ASenvPropertyReader pr;
-        if (isFakeLaunch()) {
-            pr = new ASenvPropertyReader(info.getInstallDir());
-        }
-        else {
-            pr = new ASenvPropertyReader();
+        asenvProps = getAsEnvConfReader().getProps();
+        callerParameters.setup();
+        setupLogLevels();
+        
+        MiniXmlParser domainXML = new MiniXmlParser(getInfo().getConfigFile(), getInfo().getInstanceName());
+        
+        String domainName = domainXML.getDomainName();
+        if (ok(domainName)) {
+            callerParameters.setDomainName(domainName);
         }
 
-        asenvProps = pr.getProps();
-        info.setup();
-        setupLogLevels();
-        MiniXmlParser parser = new MiniXmlParser(getInfo().getConfigFile(), getInfo().getInstanceName());
-        String domainName = parser.getDomainName();
-        if (GFLauncherUtils.ok(domainName)) {
-            info.setDomainName(domainName);
-        }
-        info.setAdminAddresses(parser.getAdminAddresses());
-        javaConfig = new JavaConfig(parser.getJavaConfig());
-        setupProfilerAndJvmOptions(parser);
+        callerParameters.setAdminAddresses(domainXML.getAdminAddresses());
+        domainXMLjavaConfig = new JavaConfig(domainXML.getJavaConfig());
+        setupProfilerAndJvmOptions(domainXML);
         setupUpgradeSecurity();
 
-        Map<String, String> realmprops = parser.getAdminRealmProperties();
+        Map<String, String> realmprops = domainXML.getAdminRealmProperties();
         if (realmprops != null) {
             String classname = realmprops.get("classname");
             String keyfile = realmprops.get("file");
-            if ("com.sun.enterprise.security.auth.realm.file.FileRealm".equals(classname)
-                    && keyfile != null) {
+            if ("com.sun.enterprise.security.auth.realm.file.FileRealm".equals(classname) && keyfile != null) {
                 adminFileRealmKeyFile = keyfile;
             }
         }
 
-        secureAdminEnabled = parser.getSecureAdminEnabled();
+        secureAdminEnabled = domainXML.getSecureAdminEnabled();
 
         renameOsgiCache();
-        setupMonitoring(parser);
-        sysPropsFromXml = parser.getSystemProperties();
+        setupMonitoring(domainXML);
+        domainXMLSystemProperty = domainXML.getSystemProperties();
         asenvProps.put(INSTANCE_ROOT_PROPERTY, getInfo().getInstanceRootDir().getPath());
 
         // Set the config java-home value as the Java home for the environment,
         // unless it is empty or it is already refering to a substitution of
         // the environment variable.
-        String jhome = javaConfig.getJavaHome();
-        if (GFLauncherUtils.ok(jhome) && !jhome.trim().equals("${" + JAVA_ROOT_PROPERTY + "}")) {
-            asenvProps.put(JAVA_ROOT_PROPERTY, jhome);
+        String javaHome = domainXMLjavaConfig.getJavaHome();
+        if (ok(javaHome) && !javaHome.trim().equals("${" + JAVA_ROOT_PROPERTY + "}")) {
+            asenvProps.put(JAVA_ROOT_PROPERTY, javaHome);
         }
-        debugOptions = getDebug();
-        parseDebug();
-        parser.setupConfigDir(getInfo().getConfigDir(), getInfo().getInstallDir());
-        setLogFilename(parser);
+        
+        domainXMLjavaConfigDebugOptions = getDebugOptionsFromDomainXMLJavaConfig();
+        parseJavaConfigDebugOptions();
+        domainXML.setupConfigDir(getInfo().getConfigDir(), getInfo().getInstallDir());
+        
+        setLogFilename(domainXML);
         resolveAllTokens();
         fixLogFilename();
-        GFLauncherLogger.addLogFileHandler(logFilename, info);
+        addLogFileHandler(logFilename, callerParameters);
+        
         setJavaExecutable();
         setClasspath();
         setCommandLine();
         setJvmOptions();
         logCommandLine();
+
         // if no <network-config> element, we need to upgrade this domain
-        needsAutoUpgrade = !parser.hasNetworkConfig();
-        needsManualUpgrade = !parser.hasDefaultConfig();
+        needsAutoUpgrade = !domainXML.hasNetworkConfig();
+        needsManualUpgrade = !domainXML.hasDefaultConfig();
         setupCalledByClients = true;
     }
+    
+    /**
+     *
+     * @return The callerParameters object that contains startup callerParameters
+     */
+    public final GFLauncherInfo getInfo() {
+        return callerParameters;
+    }
 
     /**
-     * Returns the admin realm key file for the server, if the admin realm is a
-     * FileRealm. Otherwise return null. This value can be used to create a
-     * FileRealm for the server.
+     * Returns the admin realm key file for the server, if the admin realm is a FileRealm. Otherwise return null. This value
+     * can be used to create a FileRealm for the server.
      */
     public String getAdminRealmKeyFile() {
         return adminFileRealmKeyFile;
@@ -195,48 +333,44 @@
     }
 
     /**
-     * Returns the exit value of the process. This only makes sense when we ran
-     * in verbose mode and waited for the process to exit in the wait() method.
-     * Caveat Emptor!
+     * Returns the exit value of the glassFishProcess. This only makes sense when we ran in verbose mode and waited for the glassFishProcess
+     * to exit in the wait() method. Caveat Emptor!
      *
-     * @return the process' exit value if it completed and we waited. Otherwise
-     * it returns -1
+     * @return the glassFishProcess' exit value if it completed and we waited. Otherwise it returns -1
      */
     public final int getExitValue() {
         return exitValue;
     }
 
     /**
-     * You don't want to call this before calling launch because it would not
-     * make sense.
+     * You don't want to call this before calling launch because it would not make sense.
      *
-     * @return The Process object of the launched Server process. you will
-     * either get a valid Process object or an Exceptio will be thrown. You are
-     * guaranteed not to get a null.
-     * @throws GFLauncherException if the Process has not been created yet -
-     * call launch() before calling this method.
+     * @return The Process object of the launched Server glassFishProcess. you will either get a valid Process object or an Exceptio
+     * will be thrown. You are guaranteed not to get a null.
+     * @throws GFLauncherException if the Process has not been created yet - call launch() before calling this method.
      */
     public final Process getProcess() throws GFLauncherException {
-        if (process == null)
+        if (glassFishProcess == null) {
             throw new GFLauncherException("invalid_process");
+        }
 
-        return process;
+        return glassFishProcess;
     }
 
     /**
-     * A ProcessStreamDrainer is always attached to every Process created here.
-     * It is handy for getting the stdin and stdout as a nice String.
+     * A ProcessStreamDrainer is always attached to every Process created here. It is handy for getting the stdin and stdout
+     * as a nice String.
      *
-     * @return A valid ProcessStreamDrainer. You are guaranteed to never get a
-     * null.
-     * @throws GFLauncherException if the process has not launched yet
+     * @return A valid ProcessStreamDrainer. You are guaranteed to never get a null.
+     * @throws GFLauncherException if the glassFishProcess has not launched yet
      * @see com.sun.enterprise.universal.process.ProcessStreamDrainer
      */
     public final ProcessStreamDrainer getProcessStreamDrainer() throws GFLauncherException {
-        if (psd == null)
+        if (processStreamDrainer == null) {
             throw new GFLauncherException("invalid_psd");
+        }
 
-        return psd;
+        return processStreamDrainer;
     }
 
     /**
@@ -246,15 +380,15 @@
      * @throws GFLauncherException if you call this method too early
      */
     public String getLogFilename() throws GFLauncherException {
-        if (!logFilenameWasFixed)
+        if (!logFilenameWasFixed) {
             throw new GFLauncherException(strings.get("internalError") + " call to getLogFilename() before it has been initialized");
+        }
 
         return logFilename;
     }
 
     /**
-     * Return the port number of the debug port, or -1 if debugging is not
-     * enabled.
+     * Return the port number of the debug port, or -1 if debugging is not enabled.
      *
      * @return the debug port, or -1 if not debugging
      */
@@ -265,15 +399,14 @@
     /**
      * Return true if suspend=y AND debugging is on. otherwise return false.
      *
-     * @return the debug port, or -1 if not debugging
+     * @return true if suspending, or false if either not suspending or not debugging
      */
     public final boolean isDebugSuspend() {
         return debugPort >= 0 && debugSuspend;
     }
 
     /**
-     * Does this domain need to be automatically upgraded before it can be
-     * started?
+     * Does this domain need to be automatically upgraded before it can be started?
      *
      * @return true if the domain needs to be upgraded first
      */
@@ -292,88 +425,91 @@
 
     ///////////////////////////////////////////////////////////////////////////
     ///////////////////////////////////////////////////////////////////////////
-    //////     ALL private and package-private below   ////////////////////////
+    ////// ALL private and package-private below ////////////////////////
     ///////////////////////////////////////////////////////////////////////////
     ///////////////////////////////////////////////////////////////////////////
+
     abstract void internalLaunch() throws GFLauncherException;
 
-    private void parseDebug() {
-        // look for an option of this form:
-        // -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9009
-        // and extract the suspend and port values
-        for (String opt : debugOptions) {
-            if (!opt.startsWith("-Xrunjdwp:"))
-                continue;
-            String[] attrs = opt.substring(10).split(",");
-            for (String attr : attrs) {
-                if (attr.startsWith("address=")) {
-                    try {
-                        debugPort = Integer.parseInt(attr.substring(8));
-                    }
-                    catch (NumberFormatException ex) {
-                        debugPort = -1;
-                    }
-                }
-                if (attr.startsWith("suspend=")) {
-                    try {
-                        debugSuspend = attr.substring(8).toLowerCase(Locale.getDefault()).equals("y");
-                    }
-                    catch (Exception ex) {
-                        debugSuspend = false;
-                    }
-                }
+    void launchInstance() throws GFLauncherException, MiniXmlParserException {
+        if (isFakeLaunch()) {
+            return;
+        }
+
+        List<String> cmds = null;
+
+        // Use launchctl bsexec on MacOS versions before 10.10
+        // otherwise use regular startup.
+        // (No longer using StartupItemContext).
+        // See GLASSFISH-21343
+        if (isDarwin() && useLaunchCtl(System.getProperty("os.version")) && !getInfo().isVerboseOrWatchdog()) {
+
+            // On MacOS we need to start long running glassFishProcess with
+            // StartupItemContext. See IT 12942
+            cmds = new ArrayList<>();
+
+            // cmds.add("/usr/libexec/StartupItemContext");
+            // In MacOS 10.10 they removed StartupItemContext
+            // so call launchctl directly doing what StartupItemContext did
+            // See GLASSFISH-21113
+            cmds.add("launchctl");
+            cmds.add("bsexec");
+            cmds.add("/");
+            cmds.addAll(getCommandLine());
+        } else {
+            cmds = getCommandLine();
+        }
+
+        ProcessBuilder processBuilder = new ProcessBuilder(cmds);
+
+        // Change the directory if there is one specified, o/w stick with the
+        // default.
+        try {
+            processBuilder.directory(getInfo().getConfigDir());
+        } catch (Exception e) {
+        }
+
+        // Run the glassFishProcess and attach Stream Drainers
+        try {
+            closeStandardStreamsMaybe();
+
+            // Startup GlassFish
+            glassFishProcess = processBuilder.start();
+
+            String name = getInfo().getDomainName();
+
+            // verbose trumps watchdog.
+            if (getInfo().isVerbose()) {
+                processStreamDrainer = redirect(name, glassFishProcess);
+            } else if (getInfo().isWatchdog()) {
+                processStreamDrainer = dispose(name, glassFishProcess);
+            } else {
+                processStreamDrainer = save(name, glassFishProcess);
             }
+
+            writeSecurityTokens(glassFishProcess);
+        } catch (Exception e) {
+            throw new GFLauncherException("jvmfailure", e, e);
+        }
+
+        // If verbose, hang around until the domain stops
+        if (getInfo().isVerboseOrWatchdog()) {
+            wait(glassFishProcess);
         }
     }
 
-    private void setLogFilename(MiniXmlParser parser) throws GFLauncherException {
-        logFilename = parser.getLogFilename();
-
-        if (logFilename == null)
-            logFilename = DEFAULT_LOGFILE;
+    boolean isFakeLaunch() {
+        return mode == fake;
     }
 
-    private void fixLogFilename() throws GFLauncherException {
-        if (!GFLauncherUtils.ok(logFilename))
-            logFilename = DEFAULT_LOGFILE;
-
-        File f = new File(logFilename);
-
-        if (!f.isAbsolute()) {
-            // this is quite normal.  Logging Service will by default return
-            // a relative path!
-            f = new File(info.getInstanceRootDir(), logFilename);
-        }
-
-        // Get rid of garbage like "c:/gf/./././../gf"
-        f = SmartFile.sanitize(f);
-
-        // if the file doesn't exist -- make sure the parent dir exists
-        // this is common in unit tests AND the first time the instance is
-        // started....
-
-        if (!f.exists()) {
-            File parent = f.getParentFile();
-            if (!parent.isDirectory()) {
-                boolean wasCreated = parent.mkdirs();
-                if (!wasCreated) {
-                    f = null; // give up!!
-                }
-            }
-        }
-
-        if (f == null)
-            logFilename = null;
-        else
-            logFilename = f.getPath();
-
-        logFilenameWasFixed = true;
+    public final List<String> getCommandLine() {
+        return commandLine;
     }
 
-    // unit tests will want 'fake' so that the process is not really started.
+    // unit tests will want 'fake' so that the glassFishProcess is not really started.
     enum LaunchType {
         normal, debug, trace, fake
-    };
+    }
 
     void setMode(LaunchType mode) {
         this.mode = mode;
@@ -383,187 +519,244 @@
         return mode;
     }
 
-    boolean isFakeLaunch() {
-        return mode == LaunchType.fake;
+    final long getStartTime() {
+        return startTime;
     }
 
+
+
     abstract List<File> getMainClasspath() throws GFLauncherException;
 
     abstract String getMainClass() throws GFLauncherException;
 
-    GFLauncher(GFLauncherInfo info) {
-        this.info = info;
-    }
-
     final Map<String, String> getEnvProps() {
         return asenvProps;
     }
 
-    public final List<String> getCommandLine() {
-        return commandLine;
-    }
-
-    final long getStartTime() {
-        return startTime;
-    }
-
-    void launchInstance() throws GFLauncherException, MiniXmlParserException {
-        if (isFakeLaunch()) {
-            return;
-        }
-
-        List<String> cmds = null;
-	// Use launchctl bsexec on MacOS versions before 10.10
-	// otherwise use regular startup.
- 	// (No longer using StartupItemContext).
-	// See GLASSFISH-21343
-        if (OS.isDarwin() && useLaunchCtl(System.getProperty("os.version")) && 
-	    (!getInfo().isVerboseOrWatchdog())) {
-            // On MacOS we need to start long running process with
-            // StartupItemContext. See IT 12942
-            cmds = new ArrayList<String>();
-            //cmds.add("/usr/libexec/StartupItemContext");
-            // In MacOS 10.10 they removed StartupItemContext
-            // so call launchctl directly doing what StartupItemContext did
-            // See GLASSFISH-21113
-            cmds.add("launchctl");
-            cmds.add("bsexec");
-            cmds.add("/");
-            cmds.addAll(getCommandLine());
-        }
-        else {
-            cmds = getCommandLine();
-        }
-
-        ProcessBuilder pb = new ProcessBuilder(cmds);
-
-        //pb.directory(getInfo().getConfigDir());
-
-
-        // change the directory if there is one specified, o/w stick with the
-        // default.
-        try {
-            File newDir = getInfo().getConfigDir();
-            pb.directory(newDir);
-        }
-        catch (Exception e) {
-        }
-
-        //run the process and attach Stream Drainers
-        try {
-            closeStandardStreamsMaybe();
-            process = pb.start();
-            final String name = getInfo().getDomainName();
-
-            // verbose trumps watchdog.
-            if (getInfo().isVerbose()) {
-                psd = ProcessStreamDrainer.redirect(name, process);
-            }
-            else if (getInfo().isWatchdog()) {
-                psd = ProcessStreamDrainer.dispose(name, process);
-            }
-            else {
-                psd = ProcessStreamDrainer.save(name, process);
-            }
-            writeSecurityTokens(process);
-        }
-        catch (Exception e) {
-            throw new GFLauncherException("jvmfailure", e, e);
-        }
-
-        //if verbose, hang around until the domain stops
-        if (getInfo().isVerboseOrWatchdog())
-            wait(process);
-    }
-
     /**
      * Checks whether to use launchctl for start up by checking if mac os version < 10.10
      *
-     * @return  True if osversion < 10.10 
+     * @return True if osversion < 10.10
      */
     private static boolean useLaunchCtl(String osversion) {
 
         int major = 0;
         int minor = 0;
 
-	if (osversion == null || osversion.isEmpty())
-	    return false;
+        if (osversion == null || osversion.isEmpty()) {
+            return false;
+        }
 
         String[] split = osversion.split("[\\._\\-]+");
 
-	try {
-            if (split.length > 0  && split[0].length() > 0) {
+        try {
+            if (split.length > 0 && split[0].length() > 0) {
                 major = Integer.parseInt(split[0]);
             }
             if (split.length > 1 && split[1].length() > 0) {
                 minor = Integer.parseInt(split[1]);
             }
-	    return ((major <= 9) || (major <= 10 && minor < 10));
-	}
-	catch (NumberFormatException e) {
-	    // Assume version is 10.10 or later.
-	    return false;
-	}
-    }
 
-    private void writeSecurityTokens(Process sp) throws GFLauncherException, IOException {
-        handleDeadProcess();
-        OutputStream os = sp.getOutputStream();
-        OutputStreamWriter osw = null;
-        BufferedWriter bw = null;
-        try {
-            osw = new OutputStreamWriter(os);
-            bw = new BufferedWriter(osw);
-            for (String token : info.securityTokens) {
-                bw.write(token);
-                bw.newLine();
-                bw.flush();      //flushing once is ok too
-            }
+            return major <= 9 || major <= 10 && minor < 10;
+        } catch (NumberFormatException e) {
+            // Assume version is 10.10 or later.
+            return false;
         }
-        catch (IOException e) {
-            handleDeadProcess();
-            throw e;   //process is not dead, but got some other exception, rethrow it
+    }
+    
+    private ASenvPropertyReader getAsEnvConfReader() {
+        if (isFakeLaunch()) {
+            return new ASenvPropertyReader(callerParameters.getInstallDir());
         }
-        finally {
-            if (bw != null) {
-                bw.close();
+        
+        return new ASenvPropertyReader();
+    }
+    
+    private List<String> getDebugOptionsFromDomainXMLJavaConfig() {
+        if (callerParameters.isDebug() || callerParameters.isSuspend() || domainXMLjavaConfig.isDebugEnabled()) {
+            // Suspend setting from domain.xml can be overridden by caller
+            if (!callerParameters.isSuspend()) {
+                return domainXMLjavaConfig.getDebugOptions();
             }
-            if (osw != null) {
-                osw.close();
+            
+            return domainXMLjavaConfig.getDebugOptions()
+                                      .stream()
+                                      .filter(e -> e.startsWith("-agentlib:jdwp"))
+                                      .map(e -> e.replace("suspend=n", "suspend=y"))
+                                      .collect(toList());
+        }
+
+        return emptyList();
+    }
+    
+    /**
+     * 
+     * look for an option of this form:
+     * <code>-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9009</code>
+     * and extract the suspend and port values.
+     * 
+     */
+    private void parseJavaConfigDebugOptions() {
+        for (String option : domainXMLjavaConfigDebugOptions) {
+            if (!option.startsWith("-agentlib:jdwp")) {
+                continue;
             }
-            if (os != null) {
-                try {
-                    os.close();
+            
+            String[] attributes = option.substring(10).split(",");
+            for (String attribute : attributes) {
+                if (attribute.startsWith("address=")) {
+                    try {
+                        debugPort = Integer.parseInt(attribute.substring(8));
+                    } catch (NumberFormatException ex) {
+                        debugPort = -1;
+                    }
                 }
-                catch (IOException ioe) {
-                    // nothing to do
+                
+                if (attribute.startsWith("suspend=")) {
+                    try {
+                        debugSuspend = attribute.substring(8).toLowerCase(Locale.getDefault()).equals("y");
+                    } catch (Exception ex) {
+                        debugSuspend = false;
+                    }
                 }
             }
-            if (bw != null) {
-                handleDeadProcess();
+            
+            
+        }
+    }
+
+    private void setLogFilename(MiniXmlParser domainXML) throws GFLauncherException {
+        logFilename = domainXML.getLogFilename();
+
+        if (logFilename == null) {
+            logFilename = DEFAULT_LOGFILE;
+        }
+    }
+    
+    private void resolveAllTokens() {
+        // resolve jvm-options against:
+        // 1. itself
+        // 2. <system-property>'s from domain.xml
+        // 3. system properties -- essential there is, e.g. "${path.separator}" in domain.xml
+        // 4. asenvProps
+        // 5. env variables
+        // i.e. add in reverse order to get the precedence right
+
+        Map<String, String> all = new HashMap<>();
+
+        all.putAll(System.getenv());
+        all.putAll(asenvProps);
+        all.putAll(propertiesToStringMap(System.getProperties()));
+        all.putAll(domainXMLSystemProperty);
+        all.putAll(domainXMLjvmOptions.getCombinedMap());
+        all.putAll(domainXMLJavaConfigProfiler.getConfig());
+
+        TokenResolver resolver = new TokenResolver(all);
+        resolver.resolve(domainXMLjvmOptions.xProps);
+        resolver.resolve(domainXMLjvmOptions.xxProps);
+        resolver.resolve(domainXMLjvmOptions.plainProps);
+        resolver.resolve(domainXMLjvmOptions.sysProps);
+        resolver.resolve(domainXMLjavaConfig.getMap());
+        resolver.resolve(domainXMLJavaConfigProfiler.getConfig());
+        resolver.resolve(domainXMLjavaConfigDebugOptions);
+
+        logFilename = resolver.resolve(logFilename);
+        adminFileRealmKeyFile = resolver.resolve(adminFileRealmKeyFile);
+    }
+    
+    private void fixLogFilename() throws GFLauncherException {
+        if (!ok(logFilename)) {
+            logFilename = DEFAULT_LOGFILE;
+        }
+
+        File logFile = new File(logFilename);
+
+        if (!logFile.isAbsolute()) {
+            // this is quite normal. Logging Service will by default return a relative path!
+            logFile = new File(callerParameters.getInstanceRootDir(), logFilename);
+        }
+
+        // Get rid of garbage like "c:/gf/./././../gf"
+        logFile = sanitize(logFile);
+
+        // if the file doesn't exist -- make sure the parent dir exists
+        // this is common in unit tests AND the first time the instance is
+        // started....
+
+        if (!logFile.exists()) {
+            File parent = logFile.getParentFile();
+            if (!parent.isDirectory()) {
+                boolean wasCreated = parent.mkdirs();
+                if (!wasCreated) {
+                    logFile = null; // give up!!
+                }
             }
         }
+
+        if (logFile == null) {
+            logFilename = null;
+        } else {
+            logFilename = logFile.getPath();
+        }
+
+        logFilenameWasFixed = true;
+    }
+    
+    private void setJavaExecutable() throws GFLauncherException {
+        // first choice is from domain.xml
+        if (setJavaExecutableIfValid(domainXMLjavaConfig.getJavaHome())) {
+            return;
+        }
+
+        // second choice is from asenv
+        if (!setJavaExecutableIfValid(asenvProps.get(JAVA_ROOT_PROPERTY))) {
+            throw new GFLauncherException("nojvm");
+        }
+
     }
 
-    private void handleDeadProcess() throws GFLauncherException {
-        String trace = getDeadProcessTrace(process);
-        if (trace != null)
-            throw new GFLauncherException(trace);
-    }
+    boolean setJavaExecutableIfValid(String filename) {
+        if (!ok(filename)) {
+            return false;
+        }
 
-    private String getDeadProcessTrace(Process sp) throws GFLauncherException {
-        //returns null in case the process is NOT dead
-        try {
-            int ev = sp.exitValue();
-            ProcessStreamDrainer psd1 = getProcessStreamDrainer();
-            String output = psd1.getOutErrString();
-            String trace = strings.get("server_process_died", ev, output);
-            return trace;
+        File javaFile = new File(filename);
+
+        if (!javaFile.isDirectory()) {
+            return false;
         }
-        catch (IllegalThreadStateException e) {
-            //the process is still running and we are ok
-            return null;
+
+        if (GFLauncherUtils.isWindows()) {
+            javaFile = new File(javaFile, "bin/java.exe");
+        } else {
+            javaFile = new File(javaFile, "bin/java");
         }
+
+        if (javaFile.exists()) {
+            javaExe = sanitize(javaFile).getPath();
+            return true;
+        }
+
+        return false;
+    }
+    
+    void setClasspath() throws GFLauncherException {
+        List<File> mainCP = getMainClasspath(); // subclass provides this
+        List<File> envCP = domainXMLjavaConfig.getEnvClasspath();
+        List<File> sysCP = domainXMLjavaConfig.getSystemClasspath();
+        List<File> prefixCP = domainXMLjavaConfig.getPrefixClasspath();
+        List<File> suffixCP = domainXMLjavaConfig.getSuffixClasspath();
+        List<File> profilerCP = domainXMLJavaConfigProfiler.getClasspath();
+
+        // create a list of all the classpath pieces in the right order
+        List<File> all = new ArrayList<>();
+        all.addAll(prefixCP);
+        all.addAll(profilerCP);
+        all.addAll(mainCP);
+        all.addAll(sysCP);
+        all.addAll(envCP);
+        all.addAll(suffixCP);
+        setClasspath(GFLauncherUtils.fileListToPathString(all));
     }
 
     void setCommandLine() throws GFLauncherException {
@@ -572,53 +765,71 @@
         addIgnoreNull(cmdLine, javaExe);
         addIgnoreNull(cmdLine, "-cp");
         addIgnoreNull(cmdLine, getClasspath());
-        addIgnoreNull(cmdLine, debugOptions);
+        addIgnoreNull(cmdLine, domainXMLjavaConfigDebugOptions);
 
         String CLIStartTime = System.getProperty("WALL_CLOCK_START");
-
         if (CLIStartTime != null && CLIStartTime.length() > 0) {
             cmdLine.add("-DWALL_CLOCK_START=" + CLIStartTime);
         }
+        
+        if (debugPort >= 0) {
+            cmdLine.add("-D" + DEBUG_MODE_PROPERTY + "=" + TRUE);
+        }
 
-        if (jvmOptions != null)
-            addIgnoreNull(cmdLine, jvmOptions.toStringArray());
+        if (domainXMLjvmOptions != null) {
+            addIgnoreNull(cmdLine, domainXMLjvmOptions.toList());
+        }
 
-        GFLauncherNativeHelper nativeHelper = new GFLauncherNativeHelper(info, javaConfig, jvmOptions, profiler);
+        GFLauncherNativeHelper nativeHelper = new GFLauncherNativeHelper(callerParameters, domainXMLjavaConfig, domainXMLjvmOptions, domainXMLJavaConfigProfiler);
         addIgnoreNull(cmdLine, nativeHelper.getCommands());
         addIgnoreNull(cmdLine, getMainClass());
 
         try {
             addIgnoreNull(cmdLine, getInfo().getArgsAsList());
-        }
-        catch (GFLauncherException gfle) {
+        } catch (GFLauncherException gfle) {
             throw gfle;
-        }
-        catch (Exception e) {
-            //harmless
+        } catch (Exception e) {
+            // harmless
         }
     }
 
     void setJvmOptions() throws GFLauncherException {
-        List<String> jvmOpts = getJvmOptions();
-        jvmOpts.clear();
+        domainXMLJvmOptionsAsList.clear();
 
-        if (jvmOptions != null)
-            addIgnoreNull(jvmOpts, jvmOptions.toStringArray());
+        if (domainXMLjvmOptions != null) {
+            addIgnoreNull(domainXMLJvmOptionsAsList, domainXMLjvmOptions.toList());
+        }
 
     }
+    
+    void logCommandLine() {
+        StringBuilder sb = new StringBuilder();
+
+        if (!isFakeLaunch()) {
+            Iterable<String> cmdLine = getCommandLine();
+
+            for (String s : cmdLine) {
+                sb.append(NEWLINE);
+                sb.append(s);
+            }
+            GFLauncherLogger.info(COMMAND_LINE, sb.toString());
+        }
+    }
 
     public final List<String> getJvmOptions() {
-        return jvmOptionsList;
+        return domainXMLJvmOptionsAsList;
     }
 
     private void addIgnoreNull(List<String> list, String s) {
-        if (GFLauncherUtils.ok(s))
+        if (ok(s)) {
             list.add(s);
+        }
     }
 
     private void addIgnoreNull(List<String> list, Collection<String> ss) {
-        if (ss != null && !ss.isEmpty())
+        if (ss != null && !ss.isEmpty()) {
             list.addAll(ss);
+        }
     }
 
     private void wait(final Process p) throws GFLauncherException {
@@ -626,8 +837,7 @@
             setShutdownHook(p);
             p.waitFor();
             exitValue = p.exitValue();
-        }
-        catch (InterruptedException ex) {
+        } catch (InterruptedException ex) {
             throw new GFLauncherException("verboseInterruption", ex, ex);
         }
     }
@@ -647,146 +857,85 @@
 
         if (processWhacker == null) {
             Runtime runtime = Runtime.getRuntime();
-            final String msg = strings.get("serverStopped", info.getType());
+            final String msg = strings.get("serverStopped", callerParameters.getType());
             processWhacker = new ProcessWhacker(p, msg);
+
             runtime.addShutdownHook(new Thread(processWhacker));
-        }
-        else
+        } else {
             processWhacker.setProcess(p);
+        }
     }
 
-    private void resolveAllTokens() {
-        // resolve jvm-options against:
-        // 1. itself
-        // 2. <system-property>'s from domain.xml
-        // 3. system properties -- essential there is, e.g. "${path.separator}" in domain.xml
-        // 4. asenvProps
-        // 5. env variables
-        // i.e. add in reverse order to get the precedence right
+    private void setupProfilerAndJvmOptions(MiniXmlParser domainXML) throws MiniXmlParserException, GFLauncherException {
+        // Add JVM options from Profiler *last* so they override config's JVM options
+        domainXMLJavaConfigProfiler = new Profiler(domainXML.getProfilerConfig(), domainXML.getProfilerJvmOptions(), domainXML.getProfilerSystemProperties());
 
-        Map<String, String> all = new HashMap<String, String>();
-        Map<String, String> envProps = System.getenv();
-        Map<String, String> sysProps =
-                CollectionUtils.propertiesToStringMap(System.getProperties());
-
-        // TODO: Uncomment when admin password processing & aliasing is sorted out.
-
-        // Map<String, String> passwordAliases = new HashMap<String, String>();
-        // try {
-        //     String masterPassword = "changeit";
-        //     if (IdentityManager.getMasterPassword() != null)
-        //         masterPassword = IdentityManager.getMasterPassword();
-        //     PasswordAdapter pa = new PasswordAdapter(masterPassword.toCharArray());
-        //     Enumeration e = pa.getAliases();
-        //     if (e.hasMoreElements()) {
-        //         String alias = (String) e.nextElement();
-        //         passwordAliases.put(alias, pa.getPasswordForAlias(alias));
-        //     }
-        // } catch (Exception e) {
-        //     // TODO: ignore now. Defaults to not resolving password aliases
-        // }
-        // all.putAll(passwordAliases);
-
-        all.putAll(envProps);
-        all.putAll(asenvProps);
-        all.putAll(sysProps);
-        all.putAll(sysPropsFromXml);
-        all.putAll(jvmOptions.getCombinedMap());
-        all.putAll(profiler.getConfig());
-        TokenResolver resolver = new TokenResolver(all);
-        resolver.resolve(jvmOptions.xProps);
-        resolver.resolve(jvmOptions.xxProps);
-        resolver.resolve(jvmOptions.plainProps);
-        resolver.resolve(jvmOptions.sysProps);
-        resolver.resolve(javaConfig.getMap());
-        resolver.resolve(profiler.getConfig());
-        resolver.resolve(debugOptions);
-        //resolver.resolve(sysPropsFromXml);
-        logFilename = resolver.resolve(logFilename);
-        adminFileRealmKeyFile = resolver.resolve(adminFileRealmKeyFile);
-
-        // TODO ?? Resolve sysPropsFromXml ???
-    }
-
-    private void setJavaExecutable() throws GFLauncherException {
-        // first choice is from domain.xml
-        if (setJavaExecutableIfValid(javaConfig.getJavaHome()))
-            return;
-
-        // second choice is from asenv
-        if (!setJavaExecutableIfValid(asenvProps.get(JAVA_ROOT_PROPERTY)))
-            throw new GFLauncherException("nojvm");
-
-    }
-
-    void setClasspath() throws GFLauncherException {
-        List<File> mainCP = getMainClasspath(); // subclass provides this
-        List<File> envCP = javaConfig.getEnvClasspath();
-        List<File> sysCP = javaConfig.getSystemClasspath();
-        List<File> prefixCP = javaConfig.getPrefixClasspath();
-        List<File> suffixCP = javaConfig.getSuffixClasspath();
-        List<File> profilerCP = profiler.getClasspath();
-
-        // create a list of all the classpath pieces in the right order
-        List<File> all = new ArrayList<File>();
-        all.addAll(prefixCP);
-        all.addAll(profilerCP);
-        all.addAll(mainCP);
-        all.addAll(sysCP);
-        all.addAll(envCP);
-        all.addAll(suffixCP);
-        setClasspath(GFLauncherUtils.fileListToPathString(all));
-    }
-
-    boolean setJavaExecutableIfValid(String filename) {
-        if (!GFLauncherUtils.ok(filename)) {
-            return false;
-        }
-
-        File f = new File(filename);
-
-        if (!f.isDirectory()) {
-            return false;
-        }
-
-        if (GFLauncherUtils.isWindows()) {
-            f = new File(f, "bin/java.exe");
-        }
-        else {
-            f = new File(f, "bin/java");
-        }
-
-        if (f.exists()) {
-            javaExe = SmartFile.sanitize(f).getPath();
-            return true;
-        }
-        return false;
-    }
-
-    private List<String> getDebug() {
-        if (info.isDebug() || javaConfig.isDebugEnabled()) {
-            return javaConfig.getDebugOptions();
-        }
-        return Collections.emptyList();
-    }
-
-    private void setupProfilerAndJvmOptions(MiniXmlParser parser) throws MiniXmlParserException, GFLauncherException {
-        // add JVM options from Profiler *last* so they override config's
-        // JVM options
-
-        profiler = new Profiler(
-                parser.getProfilerConfig(),
-                parser.getProfilerJvmOptions(),
-                parser.getProfilerSystemProperties());
-
-        List<String> rawJvmOptions = parser.getJvmOptions();
+        List<String> rawJvmOptions = domainXML.getJvmOptions();
         rawJvmOptions.addAll(getSpecialSystemProperties());
-        if (profiler.isEnabled()) {
-            rawJvmOptions.addAll(profiler.getJvmOptions());
+        if (domainXMLJavaConfigProfiler.isEnabled()) {
+            rawJvmOptions.addAll(domainXMLJavaConfigProfiler.getJvmOptions());
         }
-        jvmOptions = new JvmOptions(rawJvmOptions);
-        if (info.isDropInterruptedCommands()) {
-            jvmOptions.sysProps.put(SystemPropertyConstants.DROP_INTERRUPTED_COMMANDS, Boolean.TRUE.toString());
+
+        domainXMLjvmOptions = new JvmOptions(rawJvmOptions);
+        if (callerParameters.isDropInterruptedCommands()) {
+            domainXMLjvmOptions.sysProps.put(DROP_INTERRUPTED_COMMANDS, TRUE.toString());
+        }
+    }
+    
+    private void writeSecurityTokens(Process sp) throws GFLauncherException, IOException {
+        handleDeadProcess();
+        OutputStream os = sp.getOutputStream();
+        OutputStreamWriter osw = null;
+        BufferedWriter bw = null;
+        try {
+            osw = new OutputStreamWriter(os);
+            bw = new BufferedWriter(osw);
+            for (String token : callerParameters.securityTokens) {
+                bw.write(token);
+                bw.newLine();
+                bw.flush(); // flushing once is ok too
+            }
+        } catch (IOException e) {
+            handleDeadProcess();
+            throw e; // glassFishProcess is not dead, but got some other exception, rethrow it
+        } finally {
+            if (bw != null) {
+                bw.close();
+            }
+            if (osw != null) {
+                osw.close();
+            }
+            if (os != null) {
+                try {
+                    os.close();
+                } catch (IOException ioe) {
+                    // nothing to do
+                }
+            }
+            if (bw != null) {
+                handleDeadProcess();
+            }
+        }
+    }
+
+    private void handleDeadProcess() throws GFLauncherException {
+        String trace = getDeadProcessTrace(glassFishProcess);
+        if (trace != null) {
+            throw new GFLauncherException(trace);
+        }
+    }
+
+    private String getDeadProcessTrace(Process sp) throws GFLauncherException {
+        // returns null in case the glassFishProcess is NOT dead
+        try {
+            int ev = sp.exitValue();
+            ProcessStreamDrainer psd1 = getProcessStreamDrainer();
+            String output = psd1.getOutErrString();
+            String trace = strings.get("server_process_died", ev, output);
+            return trace;
+        } catch (IllegalThreadStateException e) {
+            // the glassFishProcess is still running and we are ok
+            return null;
         }
     }
 
@@ -794,48 +943,39 @@
         // If this is an upgrade and the security manager is on,
         // copy the current server.policy file to the domain
         // before the upgrade.
-        if (info.isUpgrade()
-                && jvmOptions.sysProps.containsKey("java.security.manager")) {
+        if (callerParameters.isUpgrade() && domainXMLjvmOptions.sysProps.containsKey("java.security.manager")) {
 
             GFLauncherLogger.info(GFLauncherLogger.copy_server_policy);
 
-            File source = new File(new File(new File(info.installDir, "lib"),
-                    "templates"), "server.policy");
-            File target = new File(info.getConfigDir(), "server.policy");
+            File source = new File(new File(new File(callerParameters.installDir, "lib"), "templates"), "server.policy");
+            File target = new File(callerParameters.getConfigDir(), "server.policy");
 
             try {
-                FileUtils.copyFile(source, target);
-            }
-            catch (IOException ioe) {
+                copyFile(source, target);
+            } catch (IOException ioe) {
                 // the actual error is wrapped differently depending on
                 // whether the problem was with the source or target
                 Throwable cause = ioe.getCause() == null ? ioe : ioe.getCause();
-                throw new GFLauncherException(strings.get(
-                        "copy_server_policy_error", cause.getMessage()));
+                throw new GFLauncherException(strings.get("copy_server_policy_error", cause.getMessage()));
             }
         }
     }
 
     /**
-     * Because of some issues in GlassFish OSGi launcher, a server updated from
-     * version 3.0.x to 3.1 won't start if a OSGi cache directory populated with
-     * 3.0.x modules is used. So, as a work around, we rename the cache
-     * directory when upgrade path is used. See GLASSFISH-15772 for more
-     * details.
+     * Because of some issues in GlassFish OSGi launcher, a server updated from version 3.0.x to 3.1 won't start if a OSGi
+     * cache directory populated with 3.0.x modules is used. So, as a work around, we rename the cache directory when
+     * upgrade path is used. See GLASSFISH-15772 for more details.
      *
      * @throws GFLauncherException if it fails to rename the cache directory
      */
     private void renameOsgiCache() throws GFLauncherException {
-        if (info.isUpgrade()) {
-            File osgiCacheDir = new File(info.getDomainRootDir(),
-                    "osgi-cache");
-            File backupOsgiCacheDir = new File(info.getDomainRootDir(),
-                    "osgi-cache-" + System.currentTimeMillis());
+        if (callerParameters.isUpgrade()) {
+            File osgiCacheDir = new File(callerParameters.getDomainRootDir(), "osgi-cache");
+            File backupOsgiCacheDir = new File(callerParameters.getDomainRootDir(), "osgi-cache-" + System.currentTimeMillis());
             if (osgiCacheDir.exists() && !backupOsgiCacheDir.exists()) {
                 if (!FileUtils.renameFile(osgiCacheDir, backupOsgiCacheDir)) {
                     throw new GFLauncherException(strings.get("rename_osgi_cache_failed", osgiCacheDir, backupOsgiCacheDir));
-                }
-                else {
+                } else {
                     GFLauncherLogger.fine("rename_osgi_cache_succeeded", osgiCacheDir, backupOsgiCacheDir);
                 }
             }
@@ -846,26 +986,28 @@
         // As usual we have to be very careful.
 
         // If it is NOT enabled -- we are out of here!!!
-        if (parser.isMonitoringEnabled() == false)
+        if (parser.isMonitoringEnabled() == false) {
             return;
+        }
 
         // if the user has a hard-coded "-javaagent" jvm-option that uses OUR jar
         // then we do NOT want to add our own.
-        Set<String> plainKeys = jvmOptions.plainProps.keySet();
+        Set<String> plainKeys = domainXMLjvmOptions.plainProps.keySet();
         for (String key : plainKeys) {
             if (key.startsWith("javaagent:")) {
-                // complications -- of course!!  They may have mix&match forward and back slashes
+                // complications -- of course!! They may have mix&match forward and back slashes
                 key = key.replace('\\', '/');
                 if (key.indexOf(FLASHLIGHT_AGENT_NAME) >= 0)
+                 {
                     return; // Done!!!!
+                }
             }
         }
 
         // It is not already specified AND monitoring is enabled.
         try {
-            jvmOptions.plainProps.put(getMonitoringAgentJvmOptionString(), null);
-        }
-        catch (GFLauncherException gfe) {
+            domainXMLjvmOptions.plainProps.put(getMonitoringAgentJvmOptionString(), null);
+        } catch (GFLauncherException gfe) {
             // This has been defined as a non-fatal error.
             // Silently ignore it -- but do NOT add it as an option
         }
@@ -875,10 +1017,9 @@
         File libMonDir = new File(getInfo().getInstallDir(), LIBMON_NAME);
         File flashlightJarFile = new File(libMonDir, FLASHLIGHT_AGENT_NAME);
 
-        if (flashlightJarFile.isFile())
+        if (flashlightJarFile.isFile()) {
             return "javaagent:" + getCleanPath(flashlightJarFile);
-        // No agent jar...
-        else {
+        } else {
             String msg = strings.get("no_flashlight_agent", flashlightJarFile);
             GFLauncherLogger.warning(GFLauncherLogger.NO_FLASHLIGHT_AGENT, flashlightJarFile);
             throw new GFLauncherException(msg);
@@ -886,28 +1027,15 @@
     }
 
     private static String getCleanPath(File f) {
-        return SmartFile.sanitize(f).getPath().replace('\\', '/');
+        return sanitize(f).getPath().replace('\\', '/');
     }
 
     private List<String> getSpecialSystemProperties() throws GFLauncherException {
-        Map<String, String> props = new HashMap<String, String>();
+        Map<String, String> props = new HashMap<>();
         props.put(INSTALL_ROOT_PROPERTY, getInfo().getInstallDir().getAbsolutePath());
         props.put(INSTANCE_ROOT_PROPERTY, getInfo().getInstanceRootDir().getAbsolutePath());
-        return (this.propsToJvmOptions(props));
-    }
-
-    void logCommandLine() {
-        StringBuilder sb = new StringBuilder();
-
-        if (!isFakeLaunch()) {
-            Iterable<String> cmdLine = getCommandLine();
-
-            for (String s : cmdLine) {
-                sb.append(NEWLINE);
-                sb.append(s);
-            }
-            GFLauncherLogger.info(GFLauncherLogger.COMMAND_LINE, sb.toString());
-        }
+        
+        return propsToJvmOptions(props);
     }
 
     String getClasspath() {
@@ -919,7 +1047,7 @@
     }
 
     private List<String> propsToJvmOptions(Map<String, String> map) {
-        List<String> ss = new ArrayList<String>();
+        List<String> ss = new ArrayList<>();
         Set<Map.Entry<String, String>> entries = map.entrySet();
 
         for (Map.Entry<String, String> entry : entries) {
@@ -938,84 +1066,62 @@
     }
 
     private void setupLogLevels() {
-        if (info.isVerbose())
-            GFLauncherLogger.setConsoleLevel(Level.INFO);
-        else
-            GFLauncherLogger.setConsoleLevel(Level.WARNING);
+        if (callerParameters.isVerbose()) {
+            GFLauncherLogger.setConsoleLevel(INFO);
+        } else {
+            GFLauncherLogger.setConsoleLevel(WARNING);
+        }
     }
 
     private void closeStandardStreamsMaybe() {
         // see issue 12832
         // Windows bug/feature -->
-        // Say process A (ssh) creates Process B (asadmin start-instance )
+        // Say glassFishProcess A (ssh) creates Process B (asadmin start-instance )
         // which then fires up Process C (the instance).
-        // Process B exits but Process A does NOT.  Process A is waiting for
+        // Process B exits but Process A does NOT. Process A is waiting for
         // Process C to exit.
         // The solution is to close down the standard streams BEFORE creating
-        // Process C.  Then Process A becomes convinced that the process it created
+        // Process C. Then Process A becomes convinced that the glassFishProcess it created
         // has finished.
         // If there is a console that means the user is sitting at the terminal
         // directly and we don't have to worry about it.
-        // Note that the issue is inside SSH -- not inside GF code per se.  I.e.
+        // Note that the issue is inside SSH -- not inside GF code per se. I.e.
         // Process B absolutely positively does exit whether or not this code runs...
         // don't run this unless we have to because our "..." messages disappear.
 
-        if (System.console() == null && OS.isWindows() && !(info.isVerboseOrWatchdog())) {
+        if (System.console() == null && OS.isWindows() && !callerParameters.isVerboseOrWatchdog()) {
             String sname;
 
-            if (info.isDomain())
-                sname = info.getDomainName();
-            else
-                sname = info.getInstanceName();
+            if (callerParameters.isDomain()) {
+                sname = callerParameters.getDomainName();
+            } else {
+                sname = callerParameters.getInstanceName();
+            }
 
             System.out.println(strings.get("ssh", sname));
             try {
                 System.in.close();
-            }
-            catch (Exception e) { // ignore
+            } catch (Exception e) { // ignore
             }
             try {
                 System.err.close();
-            }
-            catch (Exception e) { // ignore
+            } catch (Exception e) { // ignore
             }
             try {
                 System.out.close();
-            }
-            catch (Exception e) { // ignore
+            } catch (Exception e) { // ignore
             }
         }
     }
-    private List<String> commandLine = new ArrayList<String>();
-    private List<String> jvmOptionsList = new ArrayList<String>();
-    private GFLauncherInfo info;
-    private Map<String, String> asenvProps;
-    private JavaConfig javaConfig;
-    private JvmOptions jvmOptions;
-    private Profiler profiler;
-    private Map<String, String> sysPropsFromXml;
-    private String javaExe;
-    private String classpath;
-    private String adminFileRealmKeyFile;
-    private boolean secureAdminEnabled;
-    private List<String> debugOptions;
-    private long startTime;
-    private String logFilename;
-    private LaunchType mode = LaunchType.normal;
-    private final static LocalStringsImpl strings = new LocalStringsImpl(GFLauncher.class);
-    private boolean setupCalledByClients = false; //handle with care
-    private int exitValue = -1;
-    private ProcessWhacker processWhacker;
-    private Process process;
-    private ProcessStreamDrainer psd;
-    private boolean logFilenameWasFixed = false;
-    private boolean needsAutoUpgrade = false;
-    private boolean needsManualUpgrade = false;
-    private int debugPort = -1;
-    private boolean debugSuspend = false;
+
+
 
     ///////////////////////////////////////////////////////////////////////////
     private static class ProcessWhacker implements Runnable {
+
+        private String message;
+        private Process process;
+
         ProcessWhacker(Process p, String msg) {
             message = msg;
             process = p;
@@ -1032,7 +1138,7 @@
             System.out.println(message);
             process.destroy();
         }
-        private String message;
-        private Process process;
+
+
     }
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherConstants.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherConstants.java
index 536de50..8861163 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherConstants.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherConstants.java
@@ -23,18 +23,18 @@
  * @author bnevins
  */
 class GFLauncherConstants {
-    static final String JAVA_NATIVE_SYSPROP_NAME    = "java.library.path";
-    static final String NEWLINE                     = System.getProperty("line.separator");
-    static final String LIBDIR                      = "lib";
-    static final String PS                          = java.io.File.pathSeparator;
-    static final String SPARC                       = "sparc";
-    static final String SPARCV9                     = "sparcv9";
-    static final String X86                         = "x86";
-    static final String AMD64                       = "amd64";
-    static final String NATIVE_LIB_PREFIX           = "native-library-path-prefix";
-    static final String NATIVE_LIB_SUFFIX           = "native-library-path-suffix";
-    static final String LIBMON_NAME                 = "lib/monitor";
-    static final String FLASHLIGHT_AGENT_NAME       = "flashlight-agent.jar";
-    static final String DEFAULT_LOGFILE             = "logs/server.log";
-    static final boolean OS_SUPPORTS_BTRACE         = !OS.isAix();
+    static final String JAVA_NATIVE_SYSPROP_NAME = "java.library.path";
+    static final String NEWLINE = System.getProperty("line.separator");
+    static final String LIBDIR = "lib";
+    static final String PS = java.io.File.pathSeparator;
+    static final String SPARC = "sparc";
+    static final String SPARCV9 = "sparcv9";
+    static final String X86 = "x86";
+    static final String AMD64 = "amd64";
+    static final String NATIVE_LIB_PREFIX = "native-library-path-prefix";
+    static final String NATIVE_LIB_SUFFIX = "native-library-path-suffix";
+    static final String LIBMON_NAME = "lib/monitor";
+    static final String FLASHLIGHT_AGENT_NAME = "flashlight-agent.jar";
+    static final String DEFAULT_LOGFILE = "logs/server.log";
+    static final boolean OS_SUPPORTS_BTRACE = !OS.isAix();
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherException.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherException.java
index 8c9f6f9..a61a6c2 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherException.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherException.java
@@ -19,65 +19,61 @@
 import com.sun.enterprise.universal.i18n.LocalStringsImpl;
 
 /**
- * The one and only type of Exception that will be thrown out of this package.
- * I18N is wired in.  If a String message is found in the resource bundle, it will
- * use that String.  If not, it will use the String itself.
+ * The one and only type of Exception that will be thrown out of this package. I18N is wired in. If a String message is
+ * found in the resource bundle, it will use that String. If not, it will use the String itself.
+ *
  * @author bnevins
  */
 public class GFLauncherException extends Exception {
 
+    private static final long serialVersionUID = 2048446361062717571L;
+    private final static LocalStringsImpl strings = new LocalStringsImpl(GFLauncherException.class);
+
     /**
-     * 
-     * @param msg The message is either pointing at a I18N key in the resource 
-     * bundle or will be treated as a plain string.
+     *
+     * @param msg The message is either pointing at a I18N key in the resource bundle or will be treated as a plain string.
      */
-    public GFLauncherException(String msg)
-    {
+    public GFLauncherException(String msg) {
         super(strings.get(msg));
     }
 
     /**
-     * 
-     * @param msg The message is either pointing at a I18N key in the resource 
-     * bundle or will be treated as a plain string that will get formatted with
-     * objs.
+     *
+     * @param msg The message is either pointing at a I18N key in the resource bundle or will be treated as a plain string
+     * that will get formatted with objs.
      * @param objs Objects used for formatting the message.
      */
-    public GFLauncherException(String msg, Object... objs)
-    {
+    public GFLauncherException(String msg, Object... objs) {
         super(strings.get(msg, objs));
     }
 
     /**
-     * 
-     * @param msg The message is either pointing at a I18N key in the resource 
-     * bundle or will be treated as a plain string.
+     *
+     * @param msg The message is either pointing at a I18N key in the resource bundle or will be treated as a plain string.
      * @param t The causing Throwable.
      */
-    public GFLauncherException(String msg, Throwable t)
-    {
+    public GFLauncherException(String msg, Throwable t) {
         super(strings.get(msg), t);
     }
 
     /**
-     * 
-     * @param msg The message is either pointing at a I18N key in the resource 
-     * bundle or will be treated as a plain string that will get formatted with
-     * objs.
+     *
+     * @param msg The message is either pointing at a I18N key in the resource bundle or will be treated as a plain string
+     * that will get formatted with objs.
      * @param t The causing Throwable.
      * @param objs Objects used for formatting the message.
      */
-    public GFLauncherException(String msg, Throwable t, Object... objs)
-    {
+    public GFLauncherException(String msg, Throwable t, Object... objs) {
         super(strings.get(msg, objs), t);
     }
+
     /**
-     * 
+     *
      * @param t The causing Throwable.
      */
-    public GFLauncherException(Throwable t)
-    {
+    public GFLauncherException(Throwable t) {
         super(t);
     }
-    private final static LocalStringsImpl strings = new LocalStringsImpl(GFLauncherException.class);
+
+
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherFactory.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherFactory.java
index 42bb9d4..2d75400 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherFactory.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherFactory.java
@@ -16,6 +16,10 @@
 
 package com.sun.enterprise.admin.launcher;
 
+import static org.glassfish.api.admin.RuntimeType.DAS;
+import static org.glassfish.api.admin.RuntimeType.EMBEDDED;
+import static org.glassfish.api.admin.RuntimeType.INSTANCE;
+
 import org.glassfish.api.admin.RuntimeType;
 
 /**
@@ -25,29 +29,22 @@
 public class GFLauncherFactory {
 
     /**
-     * 
+     *
      * @param type The type of server to launch.
-     * @return A launcher instance that can be used for launching the specified 
-     * server type.
-     * @throws com.sun.enterprise.admin.launcher.GFLauncherException 
+     * @return A launcher instance that can be used for launching the specified server type.
+     * @throws com.sun.enterprise.admin.launcher.GFLauncherException
      */
-    public static GFLauncher getInstance(RuntimeType type) throws GFLauncherException
-    {
-        switch(type)
-        {
-            case DAS:
-                return new GFDomainLauncher(
-                        new GFLauncherInfo(RuntimeType.DAS));
-            case EMBEDDED:
-                return new GFEmbeddedLauncher(
-                        new GFLauncherInfo(RuntimeType.EMBEDDED));
+    public static GFLauncher getInstance(RuntimeType type) throws GFLauncherException {
+        switch (type) {
+        case DAS:
+            return new GFDomainLauncher(new GFLauncherInfo(DAS));
+        case EMBEDDED:
+            return new GFEmbeddedLauncher(new GFLauncherInfo(EMBEDDED));
+        case INSTANCE:
+            return new GFInstanceLauncher(new GFLauncherInfo(INSTANCE));
 
-            case INSTANCE:
-                return new GFInstanceLauncher(
-                        new GFLauncherInfo(RuntimeType.INSTANCE));
-
-            default:
-                throw new GFLauncherException("Only domain, instance and embedded launching are currently supported.");
+        default:
+            throw new GFLauncherException("Only domain, instance and embedded launching are currently supported.");
         }
     }
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherInfo.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherInfo.java
index 1aac9cd..91d6fb8 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherInfo.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -16,31 +16,96 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import java.io.*;
-import java.util.*;
-import com.sun.enterprise.universal.glassfish.GFLauncherUtils;
-import com.sun.enterprise.universal.io.SmartFile;
-import com.sun.enterprise.util.HostAndPort;
+import static com.sun.enterprise.admin.launcher.ArgumentManager.argsToMap;
+import static com.sun.enterprise.universal.glassfish.GFLauncherUtils.ok;
+import static com.sun.enterprise.universal.glassfish.GFLauncherUtils.safeExists;
+import static com.sun.enterprise.universal.glassfish.GFLauncherUtils.safeIsDirectory;
+import static com.sun.enterprise.universal.io.SmartFile.sanitize;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.glassfish.api.admin.RuntimeType;
 
+import com.sun.enterprise.universal.glassfish.GFLauncherUtils;
+import com.sun.enterprise.util.HostAndPort;
+
 /**
  * @author Byron Nevins
  */
 public class GFLauncherInfo {
+    
+    // BUG TODO get the def. domains dir from asenv 3/14/2008. Will this ever be done? 24/05/2020 
+    private final static String DEFAULT_DOMAIN_PARENT_DIR = "domains";
+    private final static String CONFIG_DIR = "config";
+    private final static String CONFIG_FILENAME = "domain.xml";
 
+    // Set by contructor
+    private RuntimeType type;
+    
+    /**
+     * Incoming arguments from caller
+     */
+    private List<String> argsRaw = new ArrayList<>();
+    
+    /**
+     * Intermediate map form of arguments from caller
+     */
+    private Map<String, String> argsMap;
+    
+    // Start set by arguments, final form of arguments from caller
+    
+    private boolean debug; // --debug argument, e.g. ./asadmin start-domain --debug
+    private boolean suspend; // --suspend
+    private boolean verbose; // --verbose argument e.g. ./asadmin start-domain --verbose
+    private boolean watchdog;
+    private boolean upgrade;
+    
+    private File domainParentDir;
+    private File instanceRootDir;
+    private File domainRootDir;
+    
+    private String domainName;
+    private String instanceName;
+
+    // End set by arguments
+   
+    private File configDir; // default [domainRootDir]/config
+    private File configFile; // default [configDir]/domain.xml
+    
+    File installDir; // default is [installDir]/modules/common-utils.jar/../..
+    
+    private boolean valid;
+    
+    private boolean dropInterruptedCommands; // "org.glassfish.job-manager.drop-interrupted-commands" system property
+    private List<HostAndPort> adminAddresses; // admin host and port, e.g. localhost:4848
+    private RespawnInfo respawnInfo;
+    
+    // password tokens -- could be multiple -- launcher should *just* write them onto stdin of server
+    final List<String> securityTokens = new ArrayList<>(); // note: it's package private
+
+    
+    GFLauncherInfo(RuntimeType type) {
+        this.type = type;
+    }
+    
     /**
      * Add the string arguments in the order given.
+     *
      * @param args The string arguments
      */
     public void addArgs(String... args) {
-        for (String s : args) {
-            argsRaw.add(s);
+        for (String argument : args) {
+            argsRaw.add(argument);
         }
     }
 
     /**
-     * Set the (optional) domain name.  This can also be sent in as a String arg
-     * like so: "-domainname" "theName"
+     * Set the (optional) domain name. This can also be sent in as a String arg like so: "-domainname" "theName"
+     *
      * @param domainName
      */
     public void setDomainName(String domainName) {
@@ -48,9 +113,9 @@
     }
 
     /**
-     * Set the (optional) domain parent directory.  
-     * This can also be sent in as a String arg
-     * like so: "-domaindir" "parentDirPath"
+     * Set the (optional) domain parent directory. This can also be sent in as a String arg like so: "-domaindir"
+     * "parentDirPath"
+     *
      * @param domainParentName The parent directory of the domain
      */
     public void setDomainParentDir(String domainParentName) {
@@ -59,16 +124,17 @@
 
     /**
      * Starts the server in verbose mode
-     * @param b 
+     *
+     * @param b
      */
     public void setVerbose(boolean b) {
         verbose = b;
     }
 
     /**
-     * Starts the server in watchdog mode.  This is only useful if verbose is false.
-     * It does the same thing as verbose -- except without the dumping of output
-     * to standard out and err streams.
+     * Starts the server in watchdog mode. This is only useful if verbose is false. It does the same thing as verbose --
+     * except without the dumping of output to standard out and err streams.
+     *
      * @param b
      * @since 3.2
      */
@@ -78,14 +144,41 @@
 
     /**
      * Starts the server in debug mode
-     * @param b 
+     *
+     * @param b
      */
     public void setDebug(boolean b) {
         debug = b;
     }
+    
+    /**
+    *
+    * @return true if debug mode is on.
+    */
+   public boolean isDebug() {
+       return debug;
+   }
+    
+    /**
+     * Starts the server in suspended debug mode
+     * 
+     * @param suspend
+     */
+    public void setSuspend(boolean suspend) {
+        this.suspend = suspend;
+    }
+    
+    /**
+    *
+    * @return true if suspend debug mode is on.
+    */
+    public boolean isSuspend() {
+        return suspend;
+    }
 
-     /**
+    /**
      * Starts the server in upgrade mode
+     *
      * @param b
      */
     public void setUpgrade(boolean b) {
@@ -132,13 +225,7 @@
         return watchdog;
     }
 
-    /**
-     * 
-     * @return true if debug mode is on.
-     */
-    public boolean isDebug() {
-        return debug;
-    }
+    
 
     /**
      *
@@ -149,7 +236,7 @@
     }
 
     /**
-     * 
+     *
      * @return The domain name
      */
     public String getDomainName() {
@@ -171,31 +258,33 @@
     public List<HostAndPort> getAdminAddresses() {
         return adminAddresses;
     }
+
     public RuntimeType getType() {
         return type;
     }
 
     public File getConfigDir() {
-        return SmartFile.sanitize(configDir);
+        return sanitize(configDir);
     }
 
     void setConfigDir(File f) {
-        configDir = SmartFile.sanitize(f);
+        configDir = sanitize(f);
     }
-    
+
     public File getInstanceRootDir() throws GFLauncherException {
         if (!valid) {
             throw new GFLauncherException("internalError", "Call to getInstanceRootDir() on an invalid GFLauncherInfo object.");
         }
-        if(instanceRootDir != null) {
+
+        if (instanceRootDir != null) {
             return instanceRootDir;
         }
-        else if(isDomain()) {
+
+        if (isDomain()) {
             return domainRootDir;
         }
-        else {
-            throw new GFLauncherException("internalError", "Call to getInstanceRootDir() on an invalid GFLauncherInfo object.");
-        }
+
+        throw new GFLauncherException("internalError", "Call to getInstanceRootDir() on an invalid GFLauncherInfo object.");
     }
 
     File getDomainParentDir() {
@@ -207,11 +296,11 @@
     }
 
     /**
-     *  TEMPORARY.  The guts of HK2 and V3 bootstrapping wants String[]
-     * -- this will be changed soon, but it is messy to change it right now.
-     * so temporarily we will humor HK2 by sending in String[]
+     * TEMPORARY. The guts of HK2 and V3 bootstrapping wants String[] -- this will be changed soon, but it is messy to
+     * change it right now. so temporarily we will humor HK2 by sending in String[]
+     *
      * @return an array of String arguments
-     * @throws com.sun.enterprise.admin.launcher.GFLauncherException 
+     * @throws com.sun.enterprise.admin.launcher.GFLauncherException
      */
     public String[] getArgsAsStringArray() throws GFLauncherException {
         List<String> list = getArgsAsList();
@@ -220,20 +309,19 @@
     }
 
     public List<String> getArgsAsList() throws GFLauncherException {
-        Iterator<Map.Entry<String, String>> map = getArgs().entrySet().iterator();
-        List<String> argList = new ArrayList<String>();
-        while (map.hasNext()) {
-            Map.Entry<String, String> entry = map.next();
+        List<String> argList = new ArrayList<>();
+        for (Map.Entry<String, String> entry : getArgs().entrySet()) {
             argList.add(entry.getKey());
             argList.add(entry.getValue());
         }
+
         return argList;
     }
 
     /**
-     * 
+     *
      * @return a Map<String,String> of processed and packaged args
-     * @throws com.sun.enterprise.admin.launcher.GFLauncherException 
+     * @throws com.sun.enterprise.admin.launcher.GFLauncherException
      */
     public Map<String, String> getArgs() throws GFLauncherException {
         // args processed and packaged for AppServer
@@ -242,28 +330,28 @@
             throw new GFLauncherException("internalError", "Call to getArgs() on an invalid GFLauncherInfo object.");
         }
 
-        Map<String, String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<>();
 
         map.put("-type", type.toString());
-        
-        if(isDomain()) {
-            map.put("-domaindir", SmartFile.sanitize(domainRootDir.getPath()));
+
+        if (isDomain()) {
+            map.put("-domaindir", sanitize(domainRootDir.getPath()));
             map.put("-domainname", domainName);
-        }
-        else if(isInstance()) {
-            map.put("-instancedir", SmartFile.sanitize(instanceRootDir.getPath()));
+        } else if (isInstance()) {
+            map.put("-instancedir", sanitize(instanceRootDir.getPath()));
         }
 
-        // no need for watchdog here.  It is a client-side phenomenon only!
+        // no need for watchdog here. It is a client-side phenomenon only!
         map.put("-verbose", Boolean.toString(verbose));
         map.put("-debug", Boolean.toString(debug));
         map.put("-instancename", instanceName);
         map.put("-upgrade", Boolean.toString(upgrade));
-        map.put("-read-stdin", "true"); //always make the server read the stdin for master password, at least.
+        map.put("-read-stdin", "true"); // always make the server read the stdin for master password, at least.
 
-        if(respawnInfo != null) {
+        if (respawnInfo != null) {
             respawnInfo.put(map);
         }
+
         return map;
     }
 
@@ -271,39 +359,31 @@
         respawnInfo = new RespawnInfo(classname, classpath, args);
     }
 
-    /** Adds the given name value pair as a security token. This is what will be put on the
-     *  launched process's stdin to securely pass it on. The value is accepted as a String and it may be insecure.
-     *  A string formed by concatenating name, '=' and value is written to the stdin as a single
-     *  line delimited by newline character. To get
-     *  the value of the token, the server should parse the line knowing this. None of the parameters may be null.
+    /**
+     * Adds the given name value pair as a security token. This is what will be put on the launched process's stdin to
+     * securely pass it on. The value is accepted as a String and it may be insecure. A string formed by concatenating name,
+     * '=' and value is written to the stdin as a single line delimited by newline character. To get the value of the token,
+     * the server should parse the line knowing this. None of the parameters may be null.
      *
-     * @param name  String representing name of the token
+     * @param name String representing name of the token
      * @param value String representing the value (should we call it a password?)
      * @throws NullPointerException if any of the parameters are null
      */
     public void addSecurityToken(String name, String value) {
-        if (name == null || value == null)
+        if (name == null || value == null) {
             throw new NullPointerException();
+        }
+        
         securityTokens.add(name + "=" + value);
     }
-    
-    GFLauncherInfo(RuntimeType type) {
-        this.type = type;
-    }
-
 
     void setAdminAddresses(List<HostAndPort> adminAddresses) {
         this.adminAddresses = adminAddresses;
     }
-    void setup() throws GFLauncherException {
-        setupFromArgs();
-        finalSetup();
-    }
 
     /**
-     * IMPORTANT:  These 2 methods are designed for use only by Unit Tests so we are
-     * not dependent on an installation.  Normally we figure out installDir from
-     * wher we are running from. 
+     * IMPORTANT: These 2 methods are designed for use only by Unit Tests so we are not dependent on an installation.
+     * Normally we figure out installDir from where we are running from.
      */
     void setInstallDir(File f) {
         installDir = f;
@@ -312,101 +392,86 @@
     File getInstallDir() {
         return installDir;
     }
-            
-    private void setupFromArgs() {
-        argsMap = ArgumentManager.argsToMap(argsRaw);
 
-        File f = null;
-        String s = null;
-        ThreeStateBoolean tsb = null;
+    void setup() throws GFLauncherException {
+        setupFromArgs();
+        finalSetup();
+    }
+    
+    private void setupFromArgs() {
+        argsMap = argsToMap(argsRaw);
+
+        File fileArgument = null;
+        String stringArgument = null;
 
         // pick out file props
-        // annoying -- cli uses "domaindir" to represent the parent of the 
-        // domain root dir.  I'm sticking with the same syntax for now...
-        if ((f = getFile("domaindir")) != null) {
-            domainParentDir = f;
+        // annoying -- cli uses "domaindir" to represent the parent of the
+        // domain root dir. I'm sticking with the same syntax for now...
+        if ((fileArgument = getFile("domaindir")) != null) {
+            domainParentDir = fileArgument;
         }
 
-        if ((f = getFile("instanceRootDir")) != null) {
-            instanceRootDir = f;
+        if ((fileArgument = getFile("instanceRootDir")) != null) {
+            instanceRootDir = fileArgument;
         }
 
-        if ((f = getFile("domainroot")) != null) {
-            domainRootDir = f;
+        if ((fileArgument = getFile("domainroot")) != null) {
+            domainRootDir = fileArgument;
         }
 
         // Now do the same thing with known Strings
-        if ((s = getString("domain")) != null) {
-            domainName = s;
+        if ((stringArgument = getString("domain")) != null) {
+            domainName = stringArgument;
         }
 
         // the Arg processor may have set the name "default" to the domain name
         // just like in asadmin
-        if (!GFLauncherUtils.ok(domainName) && (s = getString("default")) != null) {
-            domainName = s;
+        if (!ok(domainName) && (stringArgument = getString("default")) != null) {
+            domainName = stringArgument;
         }
 
-        if ((s = getString("instancename")) != null) {
-            instanceName = s;
+        if ((stringArgument = getString("instancename")) != null) {
+            instanceName = stringArgument;
         }
 
-        // finally, do the booleans
-        // getting ugly.  Findbugs does not like using regular Boolean object
+        // Finally, do the booleans
+        //
+        // Getting ugly. Findbugs does not like using regular Boolean object
         // a three-state boolean
-        // we do NOT want to disturb the existing values of these variables if the
+        // We do NOT want to disturb the existing values of these variables if the
         // user has not explicitly overridden them.
-
-        tsb = getBoolean("debug");
-
-        if(tsb.isTrue())
-            debug = true;
-        else if(tsb.isFalse())
-            debug = false;
-
-        tsb = getBoolean("verbose");
-        if(tsb.isTrue())
-            verbose = true;
-        else if(tsb.isFalse())
-            verbose = false;
-
-        tsb = getBoolean("watchdog");
-        if(tsb.isTrue())
-            watchdog = true;
-        else if(tsb.isFalse())
-            watchdog = false;
-
-        tsb = getBoolean("upgrade");
-        if(tsb.isTrue())
-            upgrade = true;
-        else if(tsb.isFalse())
-            upgrade = false;
+        debug = getBoolean("debug", debug);
+        verbose = getBoolean("verbose", verbose);
+        watchdog = getBoolean("watchdog", watchdog);
+        upgrade = getBoolean("upgrade", upgrade);
     }
 
     private void finalSetup() throws GFLauncherException {
-        if(installDir == null)
+        if (installDir == null) {
             installDir = GFLauncherUtils.getInstallDir();
+        }
 
-        if (!GFLauncherUtils.safeIsDirectory(installDir)) {
+        if (!safeIsDirectory(installDir)) {
             throw new GFLauncherException("noInstallDir", installDir);
         }
 
         // check user-supplied args
         if (domainParentDir != null) {
             // if the arg was given -- then it MUST point to a real dir
-            if (!GFLauncherUtils.safeIsDirectory(domainParentDir)) {
+            if (!safeIsDirectory(domainParentDir)) {
                 throw new GFLauncherException("noDomainParentDir", domainParentDir);
             }
         }
 
         setupServerDirs();
 
-        if (!GFLauncherUtils.safeIsDirectory(configDir)) {
+        if (!safeIsDirectory(configDir)) {
             throw new GFLauncherException("noConfigDir", configDir);
         }
 
         configFile = new File(configDir, CONFIG_FILENAME);
 
-        if (!GFLauncherUtils.safeExists(configFile)) {
+        if (!safeExists(configFile)) {
             throw new GFLauncherException("noConfigFile", configFile);
         }
 
@@ -419,10 +484,11 @@
     }
 
     private void setupServerDirs() throws GFLauncherException {
-        if(isDomain())
+        if (isDomain()) {
             setupDomainDirs();
-        else if(isInstance())
+        } else if (isInstance()) {
             setupInstanceDirs();
+        }
     }
 
     private void setupDomainDirs() throws GFLauncherException {
@@ -433,12 +499,12 @@
             return;
         }
 
-        // if they set domainParentDir -- use it.  o/w use the default dir
+        // if they set domainParentDir -- use it. o/w use the default dir
         if (domainParentDir == null) {
             domainParentDir = new File(installDir, DEFAULT_DOMAIN_PARENT_DIR);
         }
 
-        // if they specified domain name -- use it.  o/w use the one and only dir
+        // if they specified domain name -- use it. o/w use the one and only dir
         // in the domain parent dir
 
         if (domainName == null) {
@@ -447,12 +513,13 @@
 
         domainRootDir = new File(domainParentDir, domainName);
 
-        if (!GFLauncherUtils.safeIsDirectory(domainRootDir)) {
+        if (!safeIsDirectory(domainRootDir)) {
             throw new GFLauncherException("noDomainRootDir", domainRootDir);
         }
 
         configDir = new File(domainRootDir, CONFIG_DIR);
     }
+
     private void setupInstanceDirs() throws GFLauncherException {
         if (instanceRootDir == null) {
             throw new GFLauncherException("Missing instanceRootDir");
@@ -466,12 +533,7 @@
     private String getTheOneAndOnlyDomain() throws GFLauncherException {
         // look for subdirs in the parent dir -- there must be one and only one
 
-        File[] files = domainParentDir.listFiles(new FileFilter() {
-
-            public boolean accept(File f) {
-                return GFLauncherUtils.safeIsDirectory(f);
-            }
-        });
+        File[] files = domainParentDir.listFiles(f -> safeIsDirectory(f));
 
         if (files == null || files.length == 0) {
             throw new GFLauncherException("noDomainDirs", domainParentDir);
@@ -483,24 +545,40 @@
 
         return files[0].getName();
     }
+    
+    private File getFile(String key) {
+        String value = getString(key);
+
+        if (value == null) {
+            return null;
+        }
+        
+        return new File(value);
+    }
+    
+    private boolean getBoolean(String key, boolean def) {
+        ThreeStateBoolean booleanArgument = getBoolean(key);
+        
+        if (booleanArgument.isTrue()) {
+            return true;
+        }
+        
+        if (booleanArgument.isFalse()) {
+            return false;
+        }
+        
+        return def;
+    }
 
     private ThreeStateBoolean getBoolean(String key) {
         // 3 return values -- true, false, null
-        String s = getValueIgnoreCommandDelimiter(key);
+        String value = getValueIgnoreCommandDelimiter(key);
 
-        if (s != null) // guaranteed true or false
-            return new ThreeStateBoolean(Boolean.valueOf(s));
-        else
-            return new ThreeStateBoolean(null);
-    }
-
-    private File getFile(String key) {
-        String s = getString(key);
-
-        if (s == null)
-            return null;
-        else
-            return new File(s);
+        if (value != null) {
+            return new ThreeStateBoolean(Boolean.valueOf(value));
+        }
+        
+        return new ThreeStateBoolean(null);
     }
 
     private String getString(String key) {
@@ -509,70 +587,49 @@
 
     private String getValueIgnoreCommandDelimiter(String key) {
         // it can be confusing trying to remember -- is it "--option"?
-        // or "-option" or "option".  So look for any such match.
+        // or "-option" or "option". So look for any such match.
 
         if (argsMap.containsKey(key)) {
             return argsMap.get(key);
         }
+        
         key = "-" + key;
         if (argsMap.containsKey(key)) {
             return argsMap.get(key);
         }
+        
         key = "-" + key;
         if (argsMap.containsKey(key)) {
             return argsMap.get(key);
         }
+
         return null;
     }
 
-    private RuntimeType type;
-    private boolean verbose = false;
-    private boolean watchdog = false;
-    private boolean debug = false;
-    private boolean upgrade = false;
-    File installDir;
-    private File domainParentDir;
-    private File domainRootDir;
-    private File instanceRootDir;
-    //private File nodeAgentDir;
-    //private File nodeAgentsDir;
-    private File configDir;
-    private File configFile; // domain.xml
-    private String domainName;
-    private String instanceName;
-    private boolean dropInterruptedCommands = false;
-    private boolean valid = false;
-    private Map<String, String> argsMap;
-    private ArrayList<String> argsRaw = new ArrayList<String>();
-    private List<HostAndPort> adminAddresses;
-    private RespawnInfo respawnInfo;
-    // BUG TODO get the def. domains dir from asenv 3/14/2008
-    private final static String DEFAULT_DOMAIN_PARENT_DIR = "domains";
-    private final static String CONFIG_DIR = "config";
-    private final static String CONFIG_FILENAME = "domain.xml";
-    //password tokens -- could be multiple -- launcher should *just* write them onto stdin of server
-    final List<String> securityTokens = new ArrayList<String>(); // note: it's package private
-
     boolean isVerboseOrWatchdog() {
         return verbose || watchdog;
     }
 
     final private static class ThreeStateBoolean {
+        
+        final Boolean b;
 
         ThreeStateBoolean(Boolean b) {
             this.b = b;
         }
+
         boolean isNull() {
             return b == null;
         }
+
         boolean isTrue() {
             return !isNull() && b.booleanValue();
         }
+
         boolean isFalse() {
             return !isNull() && !b.booleanValue();
         }
         
-        Boolean b;
     }
 
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherLogger.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherLogger.java
index 5d0e93f..004f65d 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherLogger.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherLogger.java
@@ -16,14 +16,24 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import com.sun.enterprise.server.logging.ODLLogFormatter;
-import com.sun.enterprise.universal.i18n.LocalStringsImpl;
+import static java.util.logging.Level.FINE;
+import static java.util.logging.Level.INFO;
+import static java.util.logging.Level.SEVERE;
+import static java.util.logging.Level.WARNING;
 
 import java.io.IOException;
-import java.util.logging.*;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.FileHandler;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 import org.glassfish.logging.annotation.LogMessageInfo;
-import org.glassfish.logging.annotation.LoggerInfo;
 import org.glassfish.logging.annotation.LogMessagesResourceBundle;
+import org.glassfish.logging.annotation.LoggerInfo;
+
+import com.sun.enterprise.server.logging.ODLLogFormatter;
+import com.sun.enterprise.universal.i18n.LocalStringsImpl;
 
 /**
  * A POL (plain old logger).
@@ -31,39 +41,86 @@
  * @author bnevins
  */
 public class GFLauncherLogger {
+
+    // The resourceBundle name to be used for the module's log messages
+    @LogMessagesResourceBundle
+    public static final String SHARED_LOGMESSAGE_RESOURCE = "com.sun.enterprise.admin.launcher.LogMessages";
+
+    @LoggerInfo(subsystem = "Launcher", description = "Launcher Logger", publish = true)
+    public static final String LOGGER_NAME = "javax.enterprise.launcher";
+
+    private final static Logger logger;
+    private final static LocalStringsImpl strings = new LocalStringsImpl(GFLauncherLogger.class);
+    private static FileHandler logfileHandler;
+
+    static {
+        /*
+         * Create a Logger just for the launcher that only uses the Handlers we set up. This makes sure that when we change the
+         * log level for the Handler, we don't interfere with subsequent use of the Logger by asadmin.
+         */
+        logger = Logger.getLogger(LOGGER_NAME, SHARED_LOGMESSAGE_RESOURCE);
+        logger.setLevel(INFO);
+        logger.setUseParentHandlers(false);
+        logger.addHandler(new ConsoleHandler());
+    }
+
+    @LogMessageInfo(
+        message = "Single and double quote characters are not allowed in the CLASSPATH environmental variable.  "
+                  + "They were stripped out for you.\nBefore: {0}\nAfter: {1}",
+        comment = "CLASSPATH is illegal.",
+        cause = "see message", action = "see message", level = "SEVERE")
+    public static final String NO_QUOTES_ALLOWED = "NCLS-GFLAUNCHER-00001";
+
+    @LogMessageInfo(message = "Error Launching: {0}", comment = "Launcher Error", cause = "see message", action = "fix the CLASSPATH", level = "SEVERE")
+    public static final String LAUNCH_FAILURE = "NCLS-GFLAUNCHER-00002";
+
+    @LogMessageInfo(message = "Could not locate the flashlight agent here: {0}", comment = "catastrophic error", cause = "see message", action = "Find the agent file.", level = "SEVERE")
+    public static final String NO_FLASHLIGHT_AGENT = "NCLS-GFLAUNCHER-00003";
+
+    @LogMessageInfo(message = "Will copy glassfish/lib/templates/server.policy file to domain before upgrading.", comment = "Upgrade Information", level = "INFO")
+
+    public static final String copy_server_policy = "NCLS-GFLAUNCHER-00004";
+
+    @LogMessageInfo(message = "JVM invocation command line:{0}", comment = "Routine Information", cause = "NA", action = "NA", level = "INFO")
+    public static final String COMMAND_LINE = "NCLS-GFLAUNCHER-00005";
+
+    private GFLauncherLogger() {
+    }
+
     // use LocalStrings for < INFO level...
 
     public static void warning(String msg, Object... objs) {
-        logger.log(Level.WARNING, msg, objs);
+        logger.log(WARNING, msg, objs);
     }
 
     public static void info(String msg, Object... objs) {
-        logger.log(Level.INFO, msg, objs);
+        logger.log(INFO, msg, objs);
     }
 
     public static void severe(String msg, Object... objs) {
-        logger.log(Level.SEVERE, msg, objs);
+        logger.log(SEVERE, msg, objs);
     }
 
     public static void fine(String msg, Object... objs) {
-        if(logger.isLoggable(Level.FINE))
+        if (logger.isLoggable(FINE)) {
             logger.fine(strings.get(msg, objs));
+        }
     }
 
-    /////////////////////////  non-public below  //////////////////////////////
+    ///////////////////////// non-public below //////////////////////////////
+
     static synchronized void setConsoleLevel(Level level) {
-        for (Handler h : logger.getHandlers()) {
-            if (ConsoleHandler.class.isAssignableFrom(h.getClass())) {
-                h.setLevel(level);
+        for (Handler handler : logger.getHandlers()) {
+            if (ConsoleHandler.class.isAssignableFrom(handler.getClass())) {
+                handler.setLevel(level);
             }
         }
     }
 
     /**
-     * IMPORTANT! The server's logfile is added to the *local* logger. But it is
-     * never removed. The files are kept open by the logger. One really bad
-     * result is that Windows will not be able to delete that server after
-     * stopping it. Solution: remove the file handler when done.
+     * IMPORTANT! The server's logfile is added to the *local* logger. But it is never removed. The files are kept open by
+     * the logger. One really bad result is that Windows will not be able to delete that server after stopping it. Solution:
+     * remove the file handler when done.
      *
      * @param logFile The logfile
      * @throws GFLauncherException if the info object has not been setup
@@ -75,10 +132,9 @@
             }
             logfileHandler = new FileHandler(logFile, true);
             logfileHandler.setFormatter(new ODLLogFormatter());
-            logfileHandler.setLevel(Level.INFO);
+            logfileHandler.setLevel(INFO);
             logger.addHandler(logfileHandler);
-        }
-        catch (IOException e) {
+        } catch (IOException e) {
             // should be seen in verbose and watchdog modes for debugging
             e.printStackTrace();
         }
@@ -93,73 +149,5 @@
         }
     }
 
-    private GFLauncherLogger() {
-    }
-    // The resourceBundle name to be used for the module's log messages
-    @LogMessagesResourceBundle
-    public static final String SHARED_LOGMESSAGE_RESOURCE = "com.sun.enterprise.admin.launcher.LogMessages";
-    @LoggerInfo(subsystem = "Launcher", description = "Launcher Logger", publish = true)
-    public static final String LOGGER_NAME = "javax.enterprise.launcher";
-    private final static Logger logger;
-    private final static LocalStringsImpl strings = new LocalStringsImpl(GFLauncherLogger.class);
-    private static FileHandler logfileHandler;
 
-    static {
-        /*
-         * Create a Logger just for the launcher that only uses
-         * the Handlers we set up.  This makes sure that when
-         * we change the log level for the Handler, we don't
-         * interfere with subsequent use of the Logger by
-         * asadmin.
-         */
-        logger = Logger.getLogger(LOGGER_NAME, SHARED_LOGMESSAGE_RESOURCE);
-        logger.setLevel(Level.INFO);
-        logger.setUseParentHandlers(false);
-        logger.addHandler(new ConsoleHandler());
-    }
-
-    @LogMessageInfo(
-            message =
-    "Single and double quote characters are not allowed in the CLASSPATH environmental variable.  "
-    + "They were stripped out for you.\nBefore: {0}\nAfter: {1}",
-    comment = "CLASSPATH is illegal.",
-       cause = "see message",
-    action = "see message",
-
-    level = "SEVERE")
-    public static final String NO_QUOTES_ALLOWED = "NCLS-GFLAUNCHER-00001";
-    @LogMessageInfo(
-            message =
-    "Error Launching: {0}",
-    comment = "Launcher Error",
-    cause = "see message",
-    action = "fix the CLASSPATH",
-    level = "SEVERE")
-    public static final String LAUNCH_FAILURE = "NCLS-GFLAUNCHER-00002";
-
-    @LogMessageInfo(
-            message =
-    "Could not locate the flashlight agent here: {0}",
-    comment = "catastrophic error",
-   cause = "see message",
-    action = "Find the agent file.",
-    level = "SEVERE")
-    public static final String NO_FLASHLIGHT_AGENT = "NCLS-GFLAUNCHER-00003";
-
-    @LogMessageInfo(
-            message =
-    "Will copy glassfish/lib/templates/server.policy file to domain before upgrading.",
-    comment = "Upgrade Information",
-    level = "INFO")
-
-    public static final String copy_server_policy = "NCLS-GFLAUNCHER-00004";
-
-    @LogMessageInfo(
-            message =
-    "JVM invocation command line:{0}",
-    comment = "Routine Information",
-   cause = "NA",
-    action = "NA",
-    level = "INFO")
-    public static final String COMMAND_LINE = "NCLS-GFLAUNCHER-00005";
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherMain.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherMain.java
index 69416f1..0036c00 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherMain.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherMain.java
@@ -16,9 +16,8 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.glassfish.api.admin.RuntimeType;
+import static com.sun.enterprise.admin.launcher.GFLauncherLogger.LAUNCH_FAILURE;
+import static org.glassfish.api.admin.RuntimeType.DAS;
 
 /**
  *
@@ -27,18 +26,16 @@
 public class GFLauncherMain {
 
     /**
-     * JAVADOC IS PENDING FINAL API OF THE ARGS
+     *
      * @param args
      */
-    public static void main(String[] args)
-    {
+    public static void main(String[] args) {
         try {
-            GFLauncher launcher = GFLauncherFactory.getInstance(RuntimeType.DAS);
+            GFLauncher launcher = GFLauncherFactory.getInstance(DAS);
             launcher.getInfo().addArgs(args);
             launcher.launch();
-        }
-        catch (GFLauncherException ex) {
-            GFLauncherLogger.severe(GFLauncherLogger.LAUNCH_FAILURE, ex);
+        } catch (GFLauncherException ex) {
+            GFLauncherLogger.severe(LAUNCH_FAILURE, ex);
         }
     }
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherNativeHelper.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherNativeHelper.java
index 2f446a0..00155e2 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherNativeHelper.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/GFLauncherNativeHelper.java
@@ -16,40 +16,59 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import com.sun.enterprise.universal.glassfish.GFLauncherUtils;
-import com.sun.enterprise.universal.io.SmartFile;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.AMD64;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.JAVA_NATIVE_SYSPROP_NAME;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.LIBDIR;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.PS;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.SPARC;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.SPARCV9;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.X86;
+import static com.sun.enterprise.universal.io.SmartFile.sanitize;
+
 import java.io.File;
-import java.util.*;
-import static com.sun.enterprise.admin.launcher.GFLauncherConstants.*;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.sun.enterprise.universal.glassfish.GFLauncherUtils;
 
 /**
- * The platform-specific code is ugly.  That's why it is concentrated here.
+ * The platform-specific code is ugly. That's why it is concentrated here.
+ *
  * @author bnevins
  */
 class GFLauncherNativeHelper {
+
+    private final GFLauncherInfo info;
+    private final JvmOptions jvmOptions;
+    private final Profiler profiler;
+    private final File installDir;
+    private final File libDir;
+    private final JavaConfig javaConfig;
+
+
     GFLauncherNativeHelper(GFLauncherInfo info_, JavaConfig javaConfig_, JvmOptions jvmOptions_, Profiler profiler_) {
         info = info_;
         javaConfig = javaConfig_;
         jvmOptions = jvmOptions_;
         profiler = profiler_;
 
-        if(info == null || jvmOptions == null || profiler == null)
-            throw new NullPointerException(
-           "Null argument(s) to GFLauncherNativeHelper.GFLauncherNativeHelper");
+        if (info == null || jvmOptions == null || profiler == null) {
+            throw new NullPointerException("Null argument(s) to GFLauncherNativeHelper.GFLauncherNativeHelper");
+        }
 
-        installDir = SmartFile.sanitize(info.getInstallDir());
+        installDir = sanitize(info.getInstallDir());
         libDir = new File(installDir, LIBDIR);
     }
 
     List<String> getCommands() {
-        List<String> list = new ArrayList<String>();
+        List<String> list = new ArrayList<>();
 
-        String stockNativePathsString   = getStockNativePathString();
-        String prefixFileString         = getPrefixString();
-        String suffixFileString         = getSuffixString();
-        String profilerFileString       = getProfilerString();
-        String libFileString            = libDir.getPath();
-        String lib64FileString          = getLib64String();
+        String stockNativePathsString = getStockNativePathString();
+        String prefixFileString = getPrefixString();
+        String suffixFileString = getSuffixString();
+        String profilerFileString = getProfilerString();
+        String libFileString = libDir.getPath();
+        String lib64FileString = getLib64String();
 
         // bnevins: Very simple to change the order right here in the future!
         // don't worry about extra PS's --> no problem-o
@@ -76,8 +95,9 @@
         // return the path that is setup by the JVM
         String s = System.getProperty(JAVA_NATIVE_SYSPROP_NAME);
 
-        if(!GFLauncherUtils.ok(s))
+        if (!GFLauncherUtils.ok(s)) {
             s = "";
+        }
 
         return s;
     }
@@ -92,35 +112,33 @@
 
     private String getProfilerString() {
         // if not enabled -- fagetaboutit
-        if(!profiler.isEnabled())
+        if (!profiler.isEnabled()) {
             return "";
+        }
 
         List<File> ff = profiler.getNativePath();
         return GFLauncherUtils.fileListToPathString(ff);
     }
 
     private String getLib64String() {
-        // <i-r>/lib/sparcv9  has 64-bit SPARC natives
-        // <i-r>/lib/amd64    has 64-bit x86 natives
+        // <i-r>/lib/sparcv9 has 64-bit SPARC natives
+        // <i-r>/lib/amd64 has 64-bit x86 natives
 
         String osArch = System.getProperty("os.arch");
         File f64 = null;
 
-        if(osArch.equals(SPARC))
+        if (osArch.equals(SPARC)) {
             f64 = new File(libDir, SPARCV9);
-        else if(osArch.equals(X86))
+        } else if (osArch.equals(X86)) {
             f64 = new File(libDir, AMD64);
+        }
 
-        if(f64 != null && f64.isDirectory())
+        if (f64 != null && f64.isDirectory()) {
             return f64.getPath();
-        
+        }
+
         return "";
     }
 
-    private final GFLauncherInfo    info;
-    private final JvmOptions        jvmOptions;
-    private final Profiler          profiler;
-    private final File              installDir;
-    private final File              libDir;
-    private final JavaConfig        javaConfig;
+
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/JavaConfig.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/JavaConfig.java
index 2b1a838..86d66b1 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/JavaConfig.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/JavaConfig.java
@@ -16,10 +16,18 @@
 
 package com.sun.enterprise.admin.launcher;
 
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.NATIVE_LIB_PREFIX;
+import static com.sun.enterprise.admin.launcher.GFLauncherConstants.NATIVE_LIB_SUFFIX;
+import static com.sun.enterprise.universal.glassfish.GFLauncherUtils.ok;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
 import com.sun.enterprise.universal.glassfish.GFLauncherUtils;
-import static com.sun.enterprise.admin.launcher.GFLauncherConstants.*;
-import java.io.*;
-import java.util.*;
 
 /**
  *
@@ -40,53 +48,51 @@
     }
 
     List<File> getEnvClasspath() {
-        if(useEnvClasspath()) {
+        if (useEnvClasspath()) {
             String s = System.getenv("CLASSPATH");
             s = stripQuotes(s);
             return GFLauncherUtils.stringToFiles(s);
-        }
-        else {
-            return new ArrayList<File>();
+        } else {
+            return new ArrayList<>();
         }
     }
 
     List<File> getPrefixClasspath() {
         String cp = map.get("classpath-prefix");
 
-        if(GFLauncherUtils.ok(cp)) {
+        if (ok(cp)) {
             return GFLauncherUtils.stringToFiles(cp);
-        }
-        else {
-            return new ArrayList<File>();
+        } else {
+            return new ArrayList<>();
         }
     }
 
     String getNativeLibraryPrefix() {
         String s = map.get(NATIVE_LIB_PREFIX);
 
-        if(!GFLauncherUtils.ok(s))
+        if (!ok(s)) {
             s = "";
+        }
 
         return s;
     }
 
-
     List<File> getSuffixClasspath() {
         String cp = map.get("classpath-suffix");
 
-        if(GFLauncherUtils.ok(cp)) {
+        if (ok(cp)) {
             return GFLauncherUtils.stringToFiles(cp);
-        }
-        else {
-            return new ArrayList<File>();
+        } else {
+            return new ArrayList<>();
         }
     }
 
     String getNativeLibrarySuffix() {
         String s = map.get(NATIVE_LIB_SUFFIX);
 
-        if(!GFLauncherUtils.ok(s))
+        if (!ok(s)) {
             s = "";
+        }
 
         return s;
     }
@@ -94,11 +100,10 @@
     List<File> getSystemClasspath() {
         String cp = map.get("system-classpath");
 
-        if(GFLauncherUtils.ok(cp)) {
+        if (ok(cp)) {
             return GFLauncherUtils.stringToFiles(cp);
-        }
-        else {
-            return new ArrayList<File>();
+        } else {
+            return new ArrayList<>();
         }
     }
 
@@ -107,25 +112,26 @@
         // Since our final command line is a List<String>, we can't have 2
         // options in one String -- the JVM will ignore the second option...
         // sample "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9999"
-        List<String> empty = Collections.emptyList();
-        String s = map.get("debug-options");
+        
+        String debugOptions = map.get("debug-options");
 
-        if(!GFLauncherUtils.ok(s)) {
-            return empty;
+        if (!ok(debugOptions)) {
+            return emptyList();
         }
-        String[] ss = s.split(" ");
+        
+        String[] debugOptionsArray = debugOptions.split(" ");
 
-        if(ss.length <= 0) {
-            return empty;
+        if (debugOptionsArray.length <= 0) {
+            return emptyList();
         }
-        return Arrays.asList(ss);
+        
+        return asList(debugOptionsArray);
     }
 
     boolean isDebugEnabled() {
         return Boolean.parseBoolean(map.get("debug-enabled"));
     }
 
-
     private boolean useEnvClasspath() {
         String s = map.get("env-classpath-ignored");
 
@@ -134,8 +140,9 @@
         // If there is no value -- return false
         // else use the opposite of whatever the value is
 
-        if(s == null || s.length() <= 0)
+        if (s == null || s.length() <= 0) {
             return false;
+        }
 
         return !Boolean.parseBoolean(s);
     }
@@ -150,8 +157,9 @@
         // and for there to be an embedded quote character especially since we give
         // a SEVERE error message everytime.
 
-        if(!hasQuotes(s))
+        if (!hasQuotes(s)) {
             return s;
+        }
 
         String s2 = stripChar(s, "'");
         s2 = stripChar(s2, "\"");
@@ -161,11 +169,13 @@
     }
 
     private boolean hasQuotes(String s) {
-        if(s == null)
+        if (s == null) {
             return false;
+        }
 
-        if(s.indexOf('\'') >= 0)
+        if (s.indexOf('\'') >= 0) {
             return true;
+        }
 
         return s.indexOf('"') >= 0;
     }
@@ -175,14 +185,16 @@
 
         StringBuilder sb = new StringBuilder();
 
-        for(String s2 : ss)
+        for (String s2 : ss) {
             sb.append(s2);
+        }
 
         return sb.toString();
     }
 
     private Map<String, String> map;
 }
+
 /*
  * Sample java-config from a V2 domain.xml
  *  <java-config
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/JvmOptions.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/JvmOptions.java
index d4babdb..4d5ec70 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/JvmOptions.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/JvmOptions.java
@@ -16,24 +16,33 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import java.util.*;
+import static com.sun.enterprise.util.StringUtils.ok;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import com.sun.enterprise.util.OS;
 import com.sun.enterprise.util.StringUtils;
 
-import static com.sun.enterprise.util.StringUtils.ok;
-
 /**
  *
  * @author bnevins
  */
 class JvmOptions {
 
+    Map<String, String> sysProps = new HashMap<>();
+    Map<String, String> xxProps = new HashMap<>();
+    Map<String, String> xProps = new HashMap<>();
+    Map<String, String> plainProps = new HashMap<>();
+    int osgiPort = -1;
+
     JvmOptions(List<String> options) throws GFLauncherException {
         // We get them from domain.xml as a list of Strings
-        // -Dx=y   -Dxx  -XXfoo -XXgoo=zzz -client  -server
+        // -Dx=y -Dxx -XXfoo -XXgoo=zzz -client -server
         // Issue 4434 -- we might get a jvm-option like this:
         // <jvm-options>"-xxxxxx"</jvm-options> notice the literal double-quotes
 
@@ -42,88 +51,77 @@
 
             if (s.startsWith("-D")) {
                 addSysProp(s);
-            }
-            else if (s.startsWith("-XX")) {
+            } else if (s.startsWith("-XX")) {
                 addXxProp(s);
-            }
-            else if (s.startsWith("-X")) {
+            } else if (s.startsWith("-X")) {
                 addXProp(s);
-            }
-            else if (s.startsWith("-")) {
+            } else if (s.startsWith("-")) {
                 addPlainProp(s);
-            }
-            else // TODO i18n
-            {
+            } else {
                 throw new GFLauncherException("UnknownJvmOptionFormat", s);
             }
         }
+
         filter(); // get rid of forbidden stuff
         setOsgiPort();
     }
 
     @Override
     public String toString() {
-        List<String> ss = toStringArray();
+        List<String> options = toList();
         StringBuilder sb = new StringBuilder();
-        for (String s : ss) {
-            sb.append(s).append('\n');
+        for (String option : options) {
+            sb.append(option).append('\n');
         }
+
         return sb.toString();
     }
 
-    List<String> toStringArray() {
-        List<String> ss = new ArrayList<String>();
-        Iterator<Map.Entry<String, String>> entryIterator = xxProps.entrySet().iterator();
-        while (entryIterator.hasNext()) {
-            Map.Entry<String, String> entry = entryIterator.next();
+    List<String> toList() {
+        List<String> options = new ArrayList<>();
+        
+        for (Map.Entry<String, String> entry : xxProps.entrySet()) {
             String value = entry.getValue();
             if (value != null) {
-                ss.add("-XX" + entry.getKey() + "=" + value);
-            }
-            else {
-                ss.add("-XX" + entry.getKey());
+                options.add("-XX" + entry.getKey() + "=" + value);
+            } else {
+                options.add("-XX" + entry.getKey());
             }
         }
-        entryIterator = xProps.entrySet().iterator();
-        while (entryIterator.hasNext()) {
-            Map.Entry<String, String> entry = entryIterator.next();
+        
+        for (Map.Entry<String, String> entry : xProps.entrySet()) {
             String value = entry.getValue();
             if (value != null) {
-                ss.add("-X" + entry.getKey() + "=" + value);
-            }
-            else {
-                ss.add("-X" + entry.getKey());
+                options.add("-X" + entry.getKey() + "=" + value);
+            } else {
+                options.add("-X" + entry.getKey());
             }
         }
 
-        entryIterator = plainProps.entrySet().iterator();
-        while (entryIterator.hasNext()) {
-            Map.Entry<String, String> entry = entryIterator.next();
+        for (Map.Entry<String, String> entry : plainProps.entrySet()) {
             String value = entry.getValue();
             if (value != null) {
-                ss.add("-" + entry.getKey() + "=" + value);
-            }
-            else {
-                ss.add("-" + entry.getKey());
+                options.add("-" + entry.getKey() + "=" + value);
+            } else {
+                options.add("-" + entry.getKey());
             }
         }
-        entryIterator = sysProps.entrySet().iterator();
-        while (entryIterator.hasNext()) {
-            Map.Entry<String, String> entry = entryIterator.next();
+        
+        for (Map.Entry<String, String> entry : sysProps.entrySet()) {
             String value = entry.getValue();
             if (value != null) {
-                ss.add("-D" + entry.getKey() + "=" + value);
-            }
-            else {
-                ss.add("-D" + entry.getKey());
+                options.add("-D" + entry.getKey() + "=" + value);
+            } else {
+                options.add("-D" + entry.getKey());
             }
         }
-        return postProcessOrdering(ss);
+        
+        return postProcessOrdering(options);
     }
 
     Map<String, String> getCombinedMap() {
         // used for resolving tokens
-        Map<String, String> all = new HashMap<String, String>(plainProps);
+        Map<String, String> all = new HashMap<>(plainProps);
         all.putAll(xProps);
         all.putAll(xxProps);
         all.putAll(sysProps);
@@ -172,34 +170,34 @@
         xxProps.remove(":LogFile");
     }
 
-
     private List<String> postProcessOrdering(List<String> unsorted) {
         /*
-         * (1) JVM has one known order dependency. If these 3 are here, then
-         * unlock MUST appear first in the list -XX:+UnlockDiagnosticVMOptions
-         * -XX:+LogVMOutput -XX:LogFile=D:/as/domains/domain1/logs/jvm.log
+         * (1) JVM has one known order dependency. If these 3 are here, then unlock MUST appear first in the list
+         * -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=D:/as/domains/domain1/logs/jvm.log
          *
-         * June 2012 http://java.net/jira/browse/GLASSFISH-18777 JFR needs
-         * UnlockCommercialFeatures -- it is also order-dependent. New algorithm
-         * -- put -XX:+Unlock* first
+         * June 2012 http://java.net/jira/browse/GLASSFISH-18777 JFR needs UnlockCommercialFeatures -- it is also
+         * order-dependent. New algorithm -- put -XX:+Unlock* first
          *
-         * (2) TODO Get the name of the instance early. We no longer send in the
-         * instanceRoot as an arg so -- ????
+         * (2) TODO Get the name of the instance early. We no longer send in the instanceRoot as an arg so -- ????
          */
 
-        // go through the list hunting for the magic string.  If such a string is
-        // found then move it to the top.  In June 2012 I changed this to a less
+        // go through the list hunting for the magic string. If such a string is
+        // found then move it to the top. In June 2012 I changed this to a less
         // efficient but much more robust and simple algorithm...
 
-        List<String> sorted = new ArrayList<String>(unsorted.size());
+        List<String> sorted = new ArrayList<>(unsorted.size());
 
-        for (String s : unsorted)
-            if (hasMagic(s))
+        for (String s : unsorted) {
+            if (hasMagic(s)) {
                 sorted.add(s);
+            }
+        }
 
-        for (String s : unsorted)
-            if (!hasMagic(s))
+        for (String s : unsorted) {
+            if (!hasMagic(s)) {
                 sorted.add(s);
+            }
+        }
 
         return sorted;
     }
@@ -210,15 +208,13 @@
     }
 
     /**
-     * Filters out unwanted properties and filters in interested properties that
-     * may need to be present by default in certain environments (OS, vm.vendor)
+     * Filters out unwanted properties and filters in interested properties that may need to be present by default in
+     * certain environments (OS, vm.vendor)
      *
-     * bnevins September 2009 There may be System Properties from V2 that cause
-     * havoc. E.g. the MBean Server sys prop from V2 will be removed by upgrade
-     * code in the server but the server will blow up before it starts with a
-     * CNFE! We need to remove it carefully. I.e. the user may want to set up
-     * their own MBean Server Factory so we just check to see if the value is
-     * identical to the V2 class...
+     * bnevins September 2009 There may be System Properties from V2 that cause havoc. E.g. the MBean Server sys prop from
+     * V2 will be removed by upgrade code in the server but the server will blow up before it starts with a CNFE! We need to
+     * remove it carefully. I.e. the user may want to set up their own MBean Server Factory so we just check to see if the
+     * value is identical to the V2 class...
      *
      */
     private void filter() {
@@ -235,8 +231,9 @@
 
         String val = sysProps.get(key);
 
-        if (val != null && val.startsWith(forbiddenStart) && val.endsWith(forbiddenEnd))
+        if (val != null && val.startsWith(forbiddenStart) && val.endsWith(forbiddenEnd)) {
             sysProps.remove(key);
+        }
 
         if (OS.isDarwin() && System.getProperty("java.vm.vendor").equals("Apple Inc.")) {
             // on Mac OS, unless the property is specified in the domain.xml, we add
@@ -259,21 +256,16 @@
         String s = sysProps.get("osgi.shell.telnet.port");
 
         // not configured
-        if (!ok(s))
+        if (!ok(s)) {
             return;
+        }
 
         try {
             osgiPort = Integer.parseInt(s);
-        }
-        catch (Exception e) {
+        } catch (Exception e) {
             // already handled -- it is already set to -1
         }
     }
-    Map<String, String> sysProps = new HashMap<String, String>();
-    Map<String, String> xxProps = new HashMap<String, String>();
-    Map<String, String> xProps = new HashMap<String, String>();
-    Map<String, String> plainProps = new HashMap<String, String>();
-    int osgiPort = -1;
 
     private static class NameValue {
 
@@ -282,14 +274,14 @@
 
             if (index < 0) {
                 name = s;
-            }
-            else {
+            } else {
                 name = s.substring(0, index);
                 if (index + 1 < s.length()) {
                     value = s.substring(index + 1);
                 }
             }
         }
+
         private String name;
         private String value;
     }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/Profiler.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/Profiler.java
index 1facfcc..c592afb 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/Profiler.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/Profiler.java
@@ -16,19 +16,28 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import com.sun.enterprise.universal.glassfish.GFLauncherUtils;
-import java.io.*;
-import java.util.*;
+import static com.sun.enterprise.universal.glassfish.GFLauncherUtils.ok;
+import static com.sun.enterprise.universal.glassfish.GFLauncherUtils.stringToFiles;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptyMap;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
- * This class wraps the profiler element in java-config
- * Note that the V2 dtd says that there can be generic property elements in the
- * profiler element.  I don't know why anyone would use them -- but if they do I 
- * turn it into a "-D" System Property
+ * This class wraps the profiler element in java-config Note that the V2 dtd says that there can be generic property
+ * elements in the profiler element. I don't know why anyone would use them -- but if they do I turn it into a "-D"
+ * System Property
+ *
  * @author Byron Nevins
  */
 public class Profiler {
+
     Map<String, String> config;
+    private boolean enabled;
     List<String> jvmOptions;
 
     Profiler(Map<String, String> config, List<String> jvmOptions, Map<String, String> sysProps) {
@@ -40,46 +49,44 @@
 
     List<String> getJvmOptions() {
         if (!enabled) {
-            return Collections.emptyList();
+            return emptyList();
         }
         return jvmOptions;
     }
 
     Map<String, String> getConfig() {
         if (!enabled) {
-            return Collections.emptyMap();
+            return emptyMap();
         }
         return config;
     }
 
     List<File> getClasspath() {
         if (!enabled) {
-            return Collections.emptyList();
+            return emptyList();
         }
 
         String cp = config.get("classpath");
 
-        if (GFLauncherUtils.ok(cp)) {
-            return GFLauncherUtils.stringToFiles(cp);
+        if (ok(cp)) {
+            return stringToFiles(cp);
         }
-        else {
-            return Collections.emptyList();
-        }
+        
+        return emptyList();
     }
 
     List<File> getNativePath() {
         if (!enabled) {
-            return Collections.emptyList();
+            return emptyList();
         }
 
         String cp = config.get("native-library-path");
 
-        if (GFLauncherUtils.ok(cp)) {
-            return GFLauncherUtils.stringToFiles(cp);
+        if (ok(cp)) {
+            return stringToFiles(cp);
         }
-        else {
-            return Collections.emptyList();
-        }
+            
+        return emptyList();
     }
 
     boolean isEnabled() {
@@ -87,19 +94,21 @@
     }
 
     private List<String> getPropertiesAsJvmOptions(Map<String, String> props) {
-        List<String> list = new ArrayList<String>();
+        List<String> list = new ArrayList<>();
         Set<Map.Entry<String, String>> entries = props.entrySet();
 
         for (Map.Entry<String, String> entry : entries) {
             String name = entry.getKey();
             String value = entry.getValue();
 
-            if (value != null)
+            if (value != null) {
                 list.add("-D" + name + "=" + value);
-            else
+            } else {
                 list.add("-D" + name);
+            }
         }
+
         return list;
     }
-    private boolean enabled;
+
 }
diff --git a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/RespawnInfo.java b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/RespawnInfo.java
index c88d7a3..0e54b6d 100644
--- a/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/RespawnInfo.java
+++ b/nucleus/admin/launcher/src/main/java/com/sun/enterprise/admin/launcher/RespawnInfo.java
@@ -16,19 +16,28 @@
 
 package com.sun.enterprise.admin.launcher;
 
-import java.util.*;
+import java.util.Map;
 
 /**
  *
  * @author bnevins
  */
 class RespawnInfo {
+
+    private String classname;
+    private String classpath;
+    private String[] args;
+
+    private static final String PREFIX = "-asadmin-";
+    private static final String SEPARATOR = ",,,";
+
     RespawnInfo(String cn, String cp, String[] a) {
         classname = cn;
         classpath = cp;
 
-        if(a == null)
+        if (a == null) {
             a = new String[0];
+        }
 
         args = a;
     }
@@ -41,26 +50,30 @@
     }
 
     private void validate() throws GFLauncherException {
-        if(!ok(classname))
+        if (!ok(classname)) {
             throw new GFLauncherException("respawninfo.empty", "classname");
-        if(!ok(classpath))
+        }
+        if (!ok(classpath))
+         {
             throw new GFLauncherException("respawninfo.empty", "classpath");
         // args are idiot-proof
+        }
     }
 
     private void putArgs(Map<String, String> map) throws GFLauncherException {
         int numArgs = args.length;
         StringBuilder argLine = new StringBuilder();
 
-        for(int i = 0; i < numArgs; i++) {
+        for (int i = 0; i < numArgs; i++) {
             String arg = args[i];
 
-            if(i != 0)
+            if (i != 0) {
                 argLine.append(SEPARATOR);
+            }
 
-            if(arg.indexOf(SEPARATOR) >= 0) {
-                // this should not happen.  Only the ultra-paranoid programmer would
-                // bother checking for it.  I guess that's me!
+            if (arg.indexOf(SEPARATOR) >= 0) {
+                // this should not happen. Only the ultra-paranoid programmer would
+                // bother checking for it. I guess that's me!
                 throw new GFLauncherException("respawninfo.illegalToken", arg, SEPARATOR);
             }
             argLine.append(args[i]);
@@ -68,15 +81,9 @@
 
         map.put(PREFIX + "args", argLine.toString());
     }
-    
+
     private boolean ok(String s) {
         return s != null && s.length() > 0;
     }
 
-    private String      classname;
-    private String      classpath;
-    private String[]    args;
-
-    private static final String PREFIX = "-asadmin-";
-    private static final String SEPARATOR = ",,,";
 }
diff --git a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/StartDomainCommand.java b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/StartDomainCommand.java
index 68e6015..ac90b96 100644
--- a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/StartDomainCommand.java
+++ b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/StartDomainCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -16,17 +16,27 @@
 
 package com.sun.enterprise.admin.servermgmt.cli;
 
-import com.sun.enterprise.admin.cli.CLIConstants;
-import java.io.*;
-import java.util.*;
-import java.util.logging.*;
+import static com.sun.enterprise.admin.cli.CLIConstants.RESTART_DEBUG_OFF;
+import static com.sun.enterprise.admin.cli.CLIConstants.RESTART_DEBUG_ON;
+import static com.sun.enterprise.admin.cli.CLIConstants.RESTART_NORMAL;
+import static com.sun.enterprise.admin.cli.CLIConstants.WALL_CLOCK_START_PROP;
+import static java.util.logging.Level.FINER;
+import static org.glassfish.api.admin.RuntimeType.DAS;
 
-import jakarta.inject.Inject;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
 
-import org.jvnet.hk2.annotations.*;
 import org.glassfish.api.Param;
-import org.glassfish.api.admin.*;
+import org.glassfish.api.admin.CommandException;
+import org.glassfish.api.admin.CommandValidationException;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.api.admin.ServerEnvironment;
 import org.glassfish.hk2.api.PerLookup;
+import org.glassfish.security.common.FileRealmHelper;
+import org.jvnet.hk2.annotations.Service;
 
 import com.sun.enterprise.admin.cli.Environment;
 import com.sun.enterprise.admin.launcher.GFLauncher;
@@ -37,7 +47,8 @@
 import com.sun.enterprise.universal.i18n.LocalStringsImpl;
 import com.sun.enterprise.universal.process.ProcessStreamDrainer;
 import com.sun.enterprise.universal.xml.MiniXmlParserException;
-import org.glassfish.security.common.FileRealmHelper;
+
+import jakarta.inject.Inject;
 
 /**
  * The start-domain command.
@@ -49,46 +60,60 @@
 @PerLookup
 public class StartDomainCommand extends LocalDomainCommand implements StartServerCommand {
 
-    private GFLauncherInfo info;
-    private GFLauncher launcher;
+    private static final LocalStringsImpl strings = new LocalStringsImpl(StartDomainCommand.class);
+
     @Param(optional = true, shortName = "v", defaultValue = "false")
     private boolean verbose;
+
     @Param(optional = true, defaultValue = "false")
     private boolean upgrade;
+
     @Param(optional = true, shortName = "w", defaultValue = "false")
     private boolean watchdog;
+
+    /**
+     * Starts the server in debug mode with suspend set in domain.xml
+     */
     @Param(optional = true, shortName = "d", defaultValue = "false")
     private boolean debug;
+    
+    /**
+     * Starts the server in debug mode with suspend on
+     */
+    @Param(optional = true, shortName = "s", defaultValue = "false")
+    private boolean suspend;
+
     @Param(name = "domain_name", primary = true, optional = true)
     private String domainName0;
-    @Param(name = "dry-run", shortName = "n", optional = true,
-            defaultValue = "false")
+
+    @Param(name = "dry-run", shortName = "n", optional = true, defaultValue = "false")
     private boolean dry_run;
+
     @Param(name = "drop-interrupted-commands", optional = true, defaultValue = "false")
     private boolean drop_interrupted_commands;
 
     @Inject
-    ServerEnvironment senv;
+    ServerEnvironment serverEnvironment;
+
+    private GFLauncherInfo launchParameters;
+    private GFLauncher glassFishLauncher;
+    private StartServerHelper startServerHelper;
     
-    private static final LocalStringsImpl strings =
-            new LocalStringsImpl(StartDomainCommand.class);
     // the name of the master password option
-    private StartServerHelper helper;
     private String newpwName = Environment.getPrefix() + "NEWPASSWORD";
 
     @Override
     public List<String> getLauncherArgs() {
-        return launcher.getCommandLine();
+        return glassFishLauncher.getCommandLine();
     }
 
     @Override
     public RuntimeType getType() {
-        return RuntimeType.DAS;
+        return DAS;
     }
 
     @Override
-    protected void validate()
-            throws CommandException, CommandValidationException {
+    protected void validate() throws CommandException, CommandValidationException {
         setDomainName(domainName0);
         super.validate();
     }
@@ -96,30 +121,26 @@
     @Override
     protected int executeCommand() throws CommandException {
         try {
-            // createLauncher needs to go before the helper is created!!
+            // createLauncher needs to go before the startServerHelper is created!!
             createLauncher();
-            final String mpv = getMasterPassword();
+            String masterPassword = getMasterPassword();
 
-            helper = new StartServerHelper(
-                    logger,
-                    programOpts.isTerse(),
-                    getServerDirs(),
-                    launcher,
-                    mpv,
-                    debug);
+            startServerHelper = new StartServerHelper(logger, programOpts.isTerse(), getServerDirs(), glassFishLauncher, masterPassword);
 
-            if (helper.prepareForLaunch() == false)
+            if (startServerHelper.prepareForLaunch() == false) {
                 return ERROR;
+            }
 
-            if (!upgrade && launcher.needsManualUpgrade()) {
+            if (!upgrade && glassFishLauncher.needsManualUpgrade()) {
                 logger.info(strings.get("manualUpgradeNeeded"));
                 return ERROR;
             }
-            doAutoUpgrade(mpv);
+            
+            doAutoUpgrade(masterPassword);
 
             if (dry_run) {
                 logger.fine(Strings.get("dry_run_msg"));
-                List<String> cmd = launcher.getCommandLine();
+                List<String> cmd = glassFishLauncher.getCommandLine();
                 StringBuilder sb = new StringBuilder();
                 for (String s : cmd) {
                     sb.append(s);
@@ -131,194 +152,170 @@
 
             doAdminPasswordCheck();
 
-            // launch returns very quickly if verbose is not set
+            // Launch returns very quickly if verbose is not set
             // if verbose is set then it returns after the domain dies
-            launcher.launch();
+            glassFishLauncher.launch();
 
             if (verbose || upgrade || watchdog) { // we can potentially loop forever here...
                 while (true) {
-                    int returnValue = launcher.getExitValue();
+                    int returnValue = glassFishLauncher.getExitValue();
 
                     switch (returnValue) {
-                        case CLIConstants.RESTART_NORMAL:
-                            logger.info(strings.get("restart"));
-                            break;
-                        case CLIConstants.RESTART_DEBUG_ON:
-                            logger.info(strings.get("restartChangeDebug", "on"));
-                            info.setDebug(true);
-                            break;
-                        case CLIConstants.RESTART_DEBUG_OFF:
-                            logger.info(strings.get("restartChangeDebug", "off"));
-                            info.setDebug(false);
-                            break;
-                        default:
-                            return returnValue;
+                    case RESTART_NORMAL:
+                        logger.info(strings.get("restart"));
+                        break;
+                    case RESTART_DEBUG_ON:
+                        logger.info(strings.get("restartChangeDebug", "on"));
+                        launchParameters.setDebug(true);
+                        break;
+                    case RESTART_DEBUG_OFF:
+                        logger.info(strings.get("restartChangeDebug", "off"));
+                        launchParameters.setDebug(false);
+                        break;
+                    default:
+                        return returnValue;
                     }
 
-                    if (env.debug())
-                        System.setProperty(CLIConstants.WALL_CLOCK_START_PROP,
-                                "" + System.currentTimeMillis());
+                    if (env.debug()) {
+                        System.setProperty(WALL_CLOCK_START_PROP, "" + System.currentTimeMillis());
+                    }
 
-                    launcher.relaunch();
+                    glassFishLauncher.relaunch();
                 }
 
-            }
-            else {
-                helper.waitForServer();
-                helper.report();
+            } else {
+                startServerHelper.waitForServer();
+                startServerHelper.report();
                 return SUCCESS;
             }
-        }
-        catch (GFLauncherException gfle) {
+        } catch (GFLauncherException gfle) {
             throw new CommandException(gfle.getMessage());
-        }
-        catch (MiniXmlParserException me) {
+        } catch (MiniXmlParserException me) {
             throw new CommandException(me);
         }
     }
 
     /**
-     * Create a launcher for the domain specified by arguments to
-     * this command.  The launcher is for a server of the specified type.
-     * Sets the launcher and info fields.
-     * It has to be public because it is part of an interface
+     * Create a glassFishLauncher for the domain specified by arguments to this command. The glassFishLauncher is for a server of the
+     * specified type. Sets the glassFishLauncher and launchParameters fields. It has to be public because it is part of an interface
      */
     @Override
-    public void createLauncher()
-            throws GFLauncherException, MiniXmlParserException {
-        launcher = GFLauncherFactory.getInstance(getType());
-        info = launcher.getInfo();
+    public void createLauncher() throws GFLauncherException, MiniXmlParserException {
+        glassFishLauncher = GFLauncherFactory.getInstance(getType());
+        launchParameters = glassFishLauncher.getInfo();
 
-        info.setDomainName(getDomainName());
-        info.setDomainParentDir(getDomainsDir().getPath());
-        info.setVerbose(verbose || upgrade);
-        info.setDebug(debug);
-        info.setUpgrade(upgrade);
-        info.setWatchdog(watchdog);
-        info.setDropInterruptedCommands(drop_interrupted_commands);
+        launchParameters.setDomainName(getDomainName());
+        launchParameters.setDomainParentDir(getDomainsDir().getPath());
+        launchParameters.setVerbose(verbose || upgrade);
+        launchParameters.setSuspend(suspend);
+        launchParameters.setDebug(debug);
+        launchParameters.setUpgrade(upgrade);
+        launchParameters.setWatchdog(watchdog);
+        launchParameters.setDropInterruptedCommands(drop_interrupted_commands);
 
-        info.setRespawnInfo(programOpts.getClassName(),
-                programOpts.getClassPath(),
-                respawnArgs());
+        launchParameters.setRespawnInfo(programOpts.getClassName(), programOpts.getClassPath(), respawnArgs());
 
-        launcher.setup();
+        glassFishLauncher.setup();
     }
 
     /**
-     * Return the asadmin command line arguments necessary to start
-     * this domain admin server.
+     * Return the asadmin command line arguments necessary to start this domain admin server.
      */
     private String[] respawnArgs() {
-        List<String> args = new ArrayList<String>(15);
+        List<String> args = new ArrayList<>(15);
         args.addAll(Arrays.asList(programOpts.getProgramArguments()));
 
         // now the start-domain specific arguments
-        args.add(getName());    // the command name
+        args.add(getName()); // the command name
         args.add("--verbose=" + String.valueOf(verbose));
         args.add("--watchdog=" + String.valueOf(watchdog));
         args.add("--debug=" + String.valueOf(debug));
         args.add("--domaindir");
         args.add(getDomainsDir().toString());
         if (ok(getDomainName()))
-            args.add(getDomainName());  // the operand
+         {
+            args.add(getDomainName()); // the operand
+        }
 
-        if (logger.isLoggable(Level.FINER))
-            logger.log(Level.FINER, "Respawn args: {0}", args.toString());
+        if (logger.isLoggable(FINER)) {
+            logger.log(FINER, "Respawn args: {0}", args.toString());
+        }
         String[] a = new String[args.size()];
         args.toArray(a);
         return a;
     }
 
     /*
-     * This is useful for debugging restart-domain problems.
-     * In that case the Server process will run this class and it is fairly
-     * involved to attach a debugger (though not bad -- see RestartDomain on
-     * the server to see how).  Standard output disappears.  This is a
-     * generally useful method.  Feel free to copy & paste!
-     */
-    private void debug(String s) {
-        PrintStream ps = null;
-        try {
-            ps = new PrintStream(new FileOutputStream("startdomain.txt", true));
-            ps.println(new Date().toString() + ":  " + s);
-        } catch (FileNotFoundException ex) {
-            //
-        } finally {
-            if (ps != null)
-                ps.close();
-        }
-    }
-
-    /*
-     * If this domain needs to be upgraded and --upgrade wasn't
-     * specified, first start the domain to do the upgrade and
-     * then start the domain again for real.
+     * If this domain needs to be upgraded and --upgrade wasn't specified, first start the domain to do the upgrade and then
+     * start the domain again for real.
      */
     private void doAutoUpgrade(String mpv) throws GFLauncherException, MiniXmlParserException, CommandException {
-        if (upgrade || !launcher.needsAutoUpgrade())
+        if (upgrade || !glassFishLauncher.needsAutoUpgrade()) {
             return;
+        }
 
         logger.info(strings.get("upgradeNeeded"));
-        info.setUpgrade(true);
-        launcher.setup();
-        launcher.launch();
-        Process p = launcher.getProcess();
+        launchParameters.setUpgrade(true);
+        glassFishLauncher.setup();
+        glassFishLauncher.launch();
+        Process glassFishProcess = glassFishLauncher.getProcess();
         int exitCode = -1;
         try {
-            exitCode = p.waitFor();
-        }
-        catch (InterruptedException ex) {
+            exitCode = glassFishProcess.waitFor();
+        } catch (InterruptedException ex) {
             // should never happen
         }
+        
         if (exitCode != SUCCESS) {
-            ProcessStreamDrainer psd =
-                    launcher.getProcessStreamDrainer();
+            ProcessStreamDrainer psd = glassFishLauncher.getProcessStreamDrainer();
             String output = psd.getOutErrString();
-            if (ok(output))
-                throw new CommandException(
-                        strings.get("upgradeFailedOutput",
-                        info.getDomainName(), exitCode, output));
-            else
-                throw new CommandException(strings.get("upgradeFailed",
-                        info.getDomainName(), exitCode));
+            if (ok(output)) {
+                throw new CommandException(strings.get("upgradeFailedOutput", launchParameters.getDomainName(), exitCode, output));
+            } else {
+                throw new CommandException(strings.get("upgradeFailed", launchParameters.getDomainName(), exitCode));
+            }
         }
         logger.info(strings.get("upgradeSuccessful"));
 
-        // need a new launcher to start the domain for real
+        // need a new glassFishLauncher to start the domain for real
         createLauncher();
         // continue with normal start...
     }
 
     /*
-     * Check to make sure that at least one admin user is able to login.
-     * If none is found, then prompt for an admin password.
+     * Check to make sure that at least one admin user is able to login. If none is found, then prompt for an admin
+     * password.
      *
-     * NOTE: this depends on launcher.setup having already been called.
+     * NOTE: this depends on glassFishLauncher.setup having already been called.
      */
     private void doAdminPasswordCheck() throws CommandException {
-        String arfile = launcher.getAdminRealmKeyFile();
-        if (arfile != null) {
+        String adminRealmKeyFile = glassFishLauncher.getAdminRealmKeyFile();
+        if (adminRealmKeyFile != null) {
             try {
-                FileRealmHelper ar = new FileRealmHelper(arfile);
-                if (!ar.hasAuthenticatableUser()) {
+                FileRealmHelper fileRealmHelper = new FileRealmHelper(adminRealmKeyFile);
+                if (!fileRealmHelper.hasAuthenticatableUser()) {
+                    
                     // Prompt for the password for the first user and set it
-                    Set<String> names = ar.getUserNames();
-                    if (names == null || names.isEmpty()) {
+                    Set<String> adminUsers = fileRealmHelper.getUserNames();
+                    if (adminUsers == null || adminUsers.isEmpty()) {
                         throw new CommandException("no admin users");
                     }
-                    String auser = names.iterator().next();
+                    
+                    String firstAdminUser = adminUsers.iterator().next();
                     ParamModelData npwo = new ParamModelData(newpwName, String.class, false, null);
-                    npwo.prompt = strings.get("new.adminpw", auser);
-                    npwo.promptAgain = strings.get("new.adminpw.again", auser);
+                    npwo.prompt = strings.get("new.adminpw", firstAdminUser);
+                    npwo.promptAgain = strings.get("new.adminpw.again", firstAdminUser);
                     npwo.param._password = true;
+                    
                     logger.info(strings.get("new.adminpw.prompt"));
-                    char[] npwArr = super.getPassword(npwo, null, true);
-                    String npw = npwArr != null ? new String(npwArr) : null;
-                    if (npw == null) {
+                    char[] newPasswordArray = super.getPassword(npwo, null, true);
+                    String newPassword = newPasswordArray != null ? new String(newPasswordArray) : null;
+                    if (newPassword == null) {
                         throw new CommandException(strings.get("no.console"));
                     }
-                    ar.updateUser(auser, auser, npw.toCharArray(), null);
-                    ar.persist();
+                    
+                    fileRealmHelper.updateUser(firstAdminUser, firstAdminUser, newPassword.toCharArray(), null);
+                    fileRealmHelper.persist();
                 }
             } catch (IOException ioe) {
                 throw new CommandException(ioe);
diff --git a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/StartServerHelper.java b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/StartServerHelper.java
index 0285bc3..5a34c48 100644
--- a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/StartServerHelper.java
+++ b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/StartServerHelper.java
@@ -16,15 +16,22 @@
 
 package com.sun.enterprise.admin.servermgmt.cli;
 
-import com.sun.enterprise.admin.cli.CLIConstants;
-import com.sun.enterprise.admin.cli.Environment;
-import com.sun.enterprise.admin.cli.ProgramOptions;
-import com.sun.enterprise.util.OS;
+import static com.sun.enterprise.admin.cli.CLIConstants.DEATH_TIMEOUT_MS;
+import static com.sun.enterprise.admin.cli.CLIConstants.MASTER_PASSWORD;
+import static com.sun.enterprise.admin.cli.CLIConstants.WAIT_FOR_DAS_TIME_MS;
+import static com.sun.enterprise.util.StringUtils.ok;
+import static com.sun.enterprise.util.net.NetUtils.isRunning;
+import static java.util.logging.Level.FINER;
+
 import java.io.File;
 import java.io.IOException;
-import java.util.*;
-import java.util.logging.Level;
+import java.util.List;
 import java.util.logging.Logger;
+
+import org.glassfish.api.admin.CommandException;
+
+import com.sun.enterprise.admin.cli.CLIUtil;
+import com.sun.enterprise.admin.cli.Environment;
 import com.sun.enterprise.admin.launcher.GFLauncher;
 import com.sun.enterprise.admin.launcher.GFLauncherException;
 import com.sun.enterprise.admin.launcher.GFLauncherInfo;
@@ -34,40 +41,57 @@
 import com.sun.enterprise.util.HostAndPort;
 import com.sun.enterprise.util.io.ServerDirs;
 import com.sun.enterprise.util.net.NetUtils;
-import org.glassfish.api.admin.CommandException;
-import static com.sun.enterprise.util.StringUtils.ok;
-import static com.sun.enterprise.admin.cli.CLIConstants.WAIT_FOR_DAS_TIME_MS;
-import com.sun.enterprise.admin.cli.CLIUtil;
 
 /**
- * Java does not allow multiple inheritance.  Both StartDomainCommand and
- * StartInstanceCommand have common code but they are already in a different
- * hierarchy of classes.  The first common baseclass is too far away -- e.g.
- * no "launcher" variable, etc.
+ * Java does not allow multiple inheritance. Both StartDomainCommand and StartInstanceCommand have common code but they
+ * are already in a different hierarchy of classes. The first common baseclass is too far away -- e.g. no "launcher"
+ * variable, etc.
  *
- * Instead -- put common code in here and call it as common utilities
- * This class is designed to be thread-safe and IMMUTABLE
+ * Instead -- put common code in here and call it as common utilities This class is designed to be thread-safe and
+ * IMMUTABLE
+ *
  * @author bnevins
  */
 public class StartServerHelper {
-    public StartServerHelper(Logger logger0, boolean terse0,
-            ServerDirs serverDirs0, GFLauncher launcher0,
-            String masterPassword0, boolean debug0) {
-        logger = logger0;
-        terse = terse0;
-        launcher = launcher0;
+
+    // only set when actively trouble-shooting or investigating...
+    private static final boolean DEBUG_MESSAGES_ON = false;
+    private static final LocalStringsImpl strings = new LocalStringsImpl(StartServerHelper.class);
+
+    private final boolean terse;
+    private final GFLauncher launcher;
+    private final Logger logger;
+    private final File pidFile;
+    private final GFLauncherInfo info;
+    private final List<HostAndPort> addresses;
+    private final ServerDirs serverDirs;
+    private final String masterPassword;
+    private final String serverOrDomainName;
+    private final int debugPort;
+    private final boolean isDebugSuspend;
+    
+    public StartServerHelper(Logger logger, boolean terse, ServerDirs serverDirs, GFLauncher launcher, String masterPassword) {
+        this(logger, terse, serverDirs, launcher, masterPassword, false);
+    }
+
+
+    public StartServerHelper(Logger logger, boolean terse, ServerDirs serverDirs, GFLauncher launcher, String masterPassword, boolean debug) {
+        this.logger = logger;
+        this.terse = terse;
+        this.launcher = launcher;
         info = launcher.getInfo();
 
-        if (info.isDomain())
+        if (info.isDomain()) {
             serverOrDomainName = info.getDomainName();
-        else
+        } else {
             serverOrDomainName = info.getInstanceName();
+        }
 
         addresses = info.getAdminAddresses();
-        serverDirs = serverDirs0;
+        this.serverDirs = serverDirs;
         pidFile = serverDirs.getPidFile();
-        masterPassword = masterPassword0;
-        debug = debug0;
+        this.masterPassword = masterPassword;
+        
         // it will be < 0 if both --debug is false and debug-enabled=false in jvm-config
         debugPort = launcher.getDebugPort();
         isDebugSuspend = launcher.isDebugSuspend();
@@ -77,7 +101,6 @@
         }
     }
 
-    // TODO check the i18n messages
     public void waitForServer() throws CommandException {
         long startWait = System.currentTimeMillis();
         if (!terse) {
@@ -88,79 +111,74 @@
         boolean alive = false;
         int count = 0;
 
-        pinged:
-        while (!timedOut(startWait)) {
+        pinged: while (!timedOut(startWait)) {
             if (pidFile != null) {
-                if (logger.isLoggable(Level.FINER))
+                if (logger.isLoggable(FINER)) {
                     logger.finer("Check for pid file: " + pidFile);
+                }
                 if (pidFile.exists()) {
                     alive = true;
                     break pinged;
                 }
-            }
-            else {
-                // first, see if the admin port is responding
+            } else {
+                // First, see if the admin port is responding
                 // if it is, the DAS is up
-                for (HostAndPort addr : addresses) {
-                    if (NetUtils.isRunning(addr.getHost(), addr.getPort())) {
+                for (HostAndPort address : addresses) {
+                    if (isRunning(address.getHost(), address.getPort())) {
                         alive = true;
                         break pinged;
                     }
                 }
             }
 
-            // check to make sure the DAS process is still running
+            // Check to make sure the DAS process is still running
             // if it isn't, startup failed
             try {
-                Process p = launcher.getProcess();
-                int exitCode = p.exitValue();
+                Process glassFishProcess = launcher.getProcess();
+                int exitCode = glassFishProcess.exitValue();
                 // uh oh, DAS died
                 String sname;
 
-                if (info.isDomain())
+                if (info.isDomain()) {
                     sname = "domain " + info.getDomainName();
-                else
+                } else {
                     sname = "instance " + info.getInstanceName();
+                }
 
                 ProcessStreamDrainer psd = launcher.getProcessStreamDrainer();
                 String output = psd.getOutErrString();
-                if (ok(output))
-                    throw new CommandException(strings.get("serverDiedOutput",
-                            sname, exitCode, output));
-                else
-                    throw new CommandException(strings.get("serverDied",
-                            sname, exitCode));
-            }
-            catch (GFLauncherException ex) {
-                // should never happen
-            }
-            catch (IllegalThreadStateException ex) {
-                // process is still alive
-            }
+                if (ok(output)) {
+                    throw new CommandException(strings.get("serverDiedOutput", sname, exitCode, output));
+                } else {
+                    throw new CommandException(strings.get("serverDied", sname, exitCode));
+                }
+            } catch (GFLauncherException | IllegalThreadStateException ex) {
+                // should never happen or process is still alive
+            } 
 
-            // wait before checking again
+            // Wait before checking again
             try {
                 Thread.sleep(100);
-                if (!terse && count++ % 10 == 0)
+                if (!terse && count++ % 10 == 0) {
                     System.out.print(".");
-            }
-            catch (InterruptedException ex) {
+                }
+            } catch (InterruptedException ex) {
                 // don't care
             }
         }
 
-        if (!terse)
+        if (!terse) {
             System.out.println();
+        }
 
         if (!alive) {
             String msg;
-            String time = "" + (WAIT_FOR_DAS_TIME_MS / 1000);
-            if (info.isDomain())
-                msg = strings.get("serverNoStart", strings.get("DAS"),
-                        info.getDomainName(), time);
-            else
-                msg = strings.get("serverNoStart", strings.get("INSTANCE"),
-                        info.getInstanceName(), time);
+            String time = "" + WAIT_FOR_DAS_TIME_MS / 1000;
+            if (info.isDomain()) {
+                msg = strings.get("serverNoStart", strings.get("DAS"), info.getDomainName(), time);
+            } else {
+                msg = strings.get("serverNoStart", strings.get("INSTANCE"), info.getInstanceName(), time);
+            }
 
             throw new CommandException(msg);
         }
@@ -168,6 +186,7 @@
 
     /**
      * Run a series of commands to prepare for a launch.
+     *
      * @return false if there was a problem.
      */
     public boolean prepareForLaunch() throws CommandException {
@@ -175,8 +194,9 @@
         waitForParentToDie();
         setSecurity();
 
-        if (checkPorts() == false)
+        if (checkPorts() == false) {
             return false;
+        }
 
         deletePidFile();
 
@@ -188,32 +208,26 @@
 
         try {
             logfile = launcher.getLogFilename();
-        }
-        catch (GFLauncherException ex) {
-            logfile = "UNKNOWN";        // should never happen
+        } catch (GFLauncherException ex) {
+            logfile = "UNKNOWN"; // should never happen
         }
 
         int adminPort = -1;
         String adminPortString = "-1";
 
         try {
-            if (addresses != null && addresses.size() > 0)
+            if (addresses != null && addresses.size() > 0) {
                 adminPort = addresses.get(0).getPort();
+            }
             // To avoid having the logger do this: port = 4,848
             // so we do the conversion to a string ourselves
             adminPortString = "" + adminPort;
-        }
-        catch (Exception e) {
-            //ignore
+        } catch (Exception e) {
+            // ignore
         }
 
-        logger.info(strings.get(
-                "ServerStart.SuccessMessage",
-                info.isDomain() ? "domain " : "instance",
-                serverDirs.getServerName(),
-                serverDirs.getServerDir(),
-                logfile,
-                adminPortString));
+        logger.info(strings.get("ServerStart.SuccessMessage", info.isDomain() ? "domain " : "instance", serverDirs.getServerName(), serverDirs.getServerDir(),
+                logfile, adminPortString));
 
         if (debugPort >= 0) {
             logger.info(strings.get("ServerStart.DebuggerMessage", "" + debugPort));
@@ -221,26 +235,25 @@
     }
 
     /**
-     * If the parent is a GF server -- then wait for it to die.  This is part
-     * of the Client-Server Restart Dance!
-     * THe dying server called us with the system property AS_RESTART set to its pid
-     * @throws CommandException if we timeout waiting for the parent to die or
-     *  if the admin ports never free up
+     * If the parent is a GF server -- then wait for it to die. This is part of the Client-Server Restart Dance! THe dying
+     * server called us with the system property AS_RESTART set to its pid
+     *
+     * @throws CommandException if we timeout waiting for the parent to die or if the admin ports never free up
      */
     private void waitForParentToDie() throws CommandException {
         // we also come here with just a regular start in which case there is
         // no parent, and the System Property is NOT set to anything...
         String pids = System.getProperty("AS_RESTART");
 
-        if (!ok(pids))
+        if (!ok(pids)) {
             return;
+        }
 
         int pid = -1;
 
         try {
             pid = Integer.parseInt(pids);
-        }
-        catch (Exception e) {
+        } catch (Exception e) {
             pid = -1;
         }
         waitForParentDeath(pid);
@@ -260,12 +273,13 @@
     private void deletePidFile() {
         String msg = serverDirs.deletePidFile();
 
-        if (msg != null && logger.isLoggable(Level.FINER))
+        if (msg != null && logger.isLoggable(FINER)) {
             logger.finer(msg);
+        }
     }
 
     private void setSecurity() {
-        info.addSecurityToken(CLIConstants.MASTER_PASSWORD, masterPassword);
+        info.addSecurityToken(MASTER_PASSWORD, masterPassword);
     }
 
     private String adminPortInUse() {
@@ -275,20 +289,20 @@
     private String adminPortInUse(List<HostAndPort> adminAddresses) {
         // it returns a String for logging --- if desired
         for (HostAndPort addr : adminAddresses) {
-            if (!NetUtils.isPortFree(addr.getHost(), addr.getPort()))
-                return strings.get("ServerRunning",
-                        Integer.toString(addr.getPort()));
+            if (!NetUtils.isPortFree(addr.getHost(), addr.getPort())) {
+                return strings.get("ServerRunning", Integer.toString(addr.getPort()));
+            }
         }
 
         return null;
     }
 
     // use the pid we received from the parent server and platform specific tools
-    // to see FOR SURE when the entire JVM process is gone.  This solves
+    // to see FOR SURE when the entire JVM process is gone. This solves
     // potential niggling bugs.
     private void waitForParentDeath(int pid) throws CommandException {
         if (pid < 0) {
-            // can not happen.  (Famous Last Words!)
+            // can not happen. (Famous Last Words!)
             new ParentDeathWaiterPureJava();
             return;
         }
@@ -300,9 +314,7 @@
                 if (b == null) {
                     // this means we were unable to find out from the OS if the process
                     // is running or not
-                    debugMessage("ProcessUtils.isProcessRunning(" + pid + ") "
-                            + "returned null which means we can't get process "
-                            + "info on this platform.");
+                    debugMessage("ProcessUtils.isProcessRunning(" + pid + ") " + "returned null which means we can't get process " + "info on this platform.");
 
                     new ParentDeathWaiterPureJava();
                     return;
@@ -314,16 +326,14 @@
                 // else parent is still breathing...
                 debugMessage("Wait one more second for parent to die...");
                 Thread.sleep(1000);
-            }while (!timedOut(start, CLIConstants.DEATH_TIMEOUT_MS));
+            } while (!timedOut(start, DEATH_TIMEOUT_MS));
 
-        }
-        catch (Exception e) {
-            // fall through.  Normal returns are in the block above
+        } catch (Exception e) {
+            // fall through. Normal returns are in the block above
         }
 
         // abnormal return path
-        throw new CommandException(
-                strings.get("deathwait_timeout", CLIConstants.DEATH_TIMEOUT_MS));
+        throw new CommandException(strings.get("deathwait_timeout", DEATH_TIMEOUT_MS));
     }
 
     private static boolean timedOut(long startTime) {
@@ -331,7 +341,7 @@
     }
 
     private static boolean timedOut(long startTime, long span) {
-        return (System.currentTimeMillis() - startTime) > span;
+        return System.currentTimeMillis() - startTime > span;
     }
 
     private static void debugMessage(String s) {
@@ -341,68 +351,50 @@
         // we will not even see AS_DEBUG!
         if (DEBUG_MESSAGES_ON) {
             Environment env = new Environment();
-            CLIUtil.writeCommandToDebugLog("restart-debug", env, new String[]{"DEBUG MESSAGE FROM RESTART JVM", s}, 99999);
+            CLIUtil.writeCommandToDebugLog("restart-debug", env, new String[] { "DEBUG MESSAGE FROM RESTART JVM", s }, 99999);
         }
     }
-    private final boolean terse;
-    private final GFLauncher launcher;
-    private final Logger logger;
-    private final File pidFile;
-    private final GFLauncherInfo info;
-    private final List<HostAndPort> addresses;
-    private final ServerDirs serverDirs;
-    private final String masterPassword;
-    private final String serverOrDomainName;
-    private final boolean debug;
-    private final int debugPort;
-    private final boolean isDebugSuspend;
-    // only set when actively trouble-shooting or investigating...
-    private final static boolean DEBUG_MESSAGES_ON = false;
-    private static final LocalStringsImpl strings =
-            new LocalStringsImpl(StartServerHelper.class);
 
     /**
-     * bnevins
-     * the restart flag is set by the RestartDomain command in the local
-     * server.  The dying server has started a new JVM process and is
-     * running this code.  Our official parent process is the dying server.
-     * The ParentDeathWaiterPureJava waits for the parent process to disappear.
-     * see RestartDomainCommand in core/kernel for more details
+     * bnevins the restart flag is set by the RestartDomain command in the local server. The dying server has started a new
+     * JVM process and is running this code. Our official parent process is the dying server. The ParentDeathWaiterPureJava
+     * waits for the parent process to disappear. see RestartDomainCommand in core/kernel for more details
      */
     private class ParentDeathWaiterPureJava implements Runnable {
         @Override
-        @SuppressWarnings("empty-statement")
         public void run() {
             try {
                 // When parent process is almost dead, in.read returns -1 (EOF)
                 // as the pipe breaks.
 
-                while (System.in.read() >= 0);
-            }
-            catch (IOException ex) {
+                while (System.in.read() >= 0) {
+                    ;
+                }
+            } catch (IOException ex) {
                 // ignore
             }
 
             // The port may take some time to become free after the pipe breaks
-            while (adminPortInUse(addresses) != null)
+            while (adminPortInUse(addresses) != null) {
                 ;
+            }
             success = true;
         }
 
         private ParentDeathWaiterPureJava() throws CommandException {
             try {
-                Thread t = new Thread(this);
-                t.start();
-                t.join(CLIConstants.DEATH_TIMEOUT_MS);
-            }
-            catch (Exception e) {
+                Thread deathWaiterThread = new Thread(this);
+                deathWaiterThread.start();
+                deathWaiterThread.join(DEATH_TIMEOUT_MS);
+            } catch (Exception e) {
                 // ignore!
             }
 
-            if (!success)
-                throw new CommandException(
-                        strings.get("deathwait_timeout", CLIConstants.DEATH_TIMEOUT_MS));
+            if (!success) {
+                throw new CommandException(strings.get("deathwait_timeout", DEATH_TIMEOUT_MS));
+            }
         }
+
         boolean success = false;
     }
 }
diff --git a/nucleus/common/common-util/src/main/java/com/sun/enterprise/util/FelixPrettyPrinter.java b/nucleus/common/common-util/src/main/java/com/sun/enterprise/util/FelixPrettyPrinter.java
new file mode 100644
index 0000000..6cb5421
--- /dev/null
+++ b/nucleus/common/common-util/src/main/java/com/sun/enterprise/util/FelixPrettyPrinter.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2008, 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 com.sun.enterprise.util;
+
+public class FelixPrettyPrinter {
+    
+    /**
+     * Prints exception messages from Felix bundle classloading in a more human readable way.
+     * 
+     * @param message
+     * @return
+     */
+    public static String prettyPrintExceptionMessage(String message) {
+        StringBuilder messageBuilder = new StringBuilder();
+        int index = message.indexOf("Unable to resolve");
+        int indent = 0;
+        while (index >= 0) {
+            printLn(messageBuilder, indent, "Unable to resolve");
+            index += "Unable to resolve".length();
+            
+            int index2 = message.indexOf("missing requirement", index);
+            if (index2 >= 0) {
+                
+                indent++;
+                
+                // Module name would be e.g.
+                // org.glassfish.server.internal.batch.glassfish-batch-connector [103](R 103.0):
+                String module = message.substring(index, index2);
+                
+                // Remove the duplicate number
+                if (module.contains("(R")) {
+                    module = module.substring(0, module.indexOf("(R"));
+                }
+                
+                printLn(messageBuilder, indent, module);
+                printLn(messageBuilder, indent, "missing requirement");
+                
+                index = index2 + "missing requirement".length();
+               
+                // In GlassFish and in a classloader the search is always for package, so we can 
+                // use that as a delimiter here
+                index = message.indexOf("osgi.wiring.package; ", index);
+                if (index >= 0) {
+                    
+                    indent++;
+                    
+                    // Remainder of input now looks like this:
+                    
+                    // osgi.wiring.package; (&(osgi.wiring.package=org.glassfish.grizzly)(version>=2.4.0)(!(version>=3.0.0))) 
+                    
+                    // Skip over "osgi.wiring.package; ", we're always searching for this so 
+                    // no need to print it.
+                    index += "osgi.wiring.package; ".length();
+                    
+                    // Now extracting this:
+                    // "(&(osgi.wiring.package=org.glassfish.grizzly)(version>=2.4.0)(!(version>=3.0.0)))"
+                    index2 = message.indexOf(" ", index);
+                    
+                    String packageAndVersion = message.substring(index, index2);
+                    
+                    // Make it a little less "cramped"
+                    // "(&(package=org.glassfish.grizzly) (version>=2.4.0) (!(version>=3.0.0)))"
+                    packageAndVersion = packageAndVersion.replace("osgi.wiring.package", "package");
+                    packageAndVersion = packageAndVersion.replace(")(", ") (");
+                    packageAndVersion = packageAndVersion.replace("=", " = ");
+                    packageAndVersion = packageAndVersion.replace("> =", " >=");
+                    packageAndVersion = packageAndVersion.replace("< =", " <=");
+                    
+                    // Remove outer braces
+                    // "&(package=org.glassfish.grizzly) (version>=2.4.0) (!(version>=3.0.0))"
+                    if (packageAndVersion.startsWith("(")) {
+                        packageAndVersion = packageAndVersion.substring(1);
+                    }
+                    if (packageAndVersion.endsWith(")")) {
+                        packageAndVersion = packageAndVersion.substring(0, packageAndVersion.length()-1);
+                    }
+
+                    printLn(messageBuilder, indent, packageAndVersion);
+                    
+                    // If there's a "caused by:", print it and increase the indent
+                    index = message.indexOf("caused by: ", index2);
+                    if (index >= 0) {
+                        
+                        printLn(messageBuilder, indent, "caused by:");
+                        
+                        indent++;
+                        index += "caused by: ".length();
+                    }
+                }
+                
+            }
+            
+            index = index2;
+            
+            index = message.indexOf("Unable to resolve", index);
+        }
+        
+        return messageBuilder.toString();
+    }
+    
+    private static void printLn(StringBuilder messageBuilder, int indent, String message) {
+        for (int i=0; i<(indent * 4); i++) {
+            messageBuilder.append(" ");
+        }
+        
+        messageBuilder.append(message.trim())
+                      .append("\n");
+    }
+    
+    public static void main(String[] args) {
+        String test = "Caused by: org.osgi.framework.BundleException: Unable to resolve org.glassfish.server.internal.batch.glassfish-batch-connector [103](R 103.0): missing requirement [org.glassfish.server.internal.batch.glassfish-batch-connector [103](R 103.0)] osgi.wiring.package; (osgi.wiring.package=com.ibm.jbatch.spi) [caused by: Unable to resolve org.glassfish.server.internal.batch.payara-jbatch [325](R 325.0): missing requirement [org.glassfish.server.internal.batch.payara-jbatch [325](R 325.0)] osgi.wiring.package; (osgi.wiring.package=org.glassfish.weld) [caused by: Unable to resolve org.glassfish.server.internal.web.weld-integration [395](R 395.0): missing requirement [org.glassfish.server.internal.web.weld-integration [395](R 395.0)] osgi.wiring.package; (&(osgi.wiring.package=com.sun.faces.spi)(version>=2.3.0)(!(version>=3.0.0)))]] Unresolved requirements: [[org.glassfish.server.internal.batch.glassfish-batch-connector [103](R 103.0)] osgi.wiring.package; (osgi.wiring.package=com.ibm.jbatch.spi)]";
+
+        String test1 = prettyPrintExceptionMessage(test);
+        
+        String test2 = prettyPrintExceptionMessage(" (java.lang.String) Unable to resolve org.glassfish.jersey.containers.jersey-container-grizzly2-http [142](R 142.0): missing requirement [org.glassfish.jersey.containers.jersey-container-grizzly2-http [142](R 142.0)] osgi.wiring.package; (&(osgi.wiring.package=org.glassfish.grizzly)(version>=2.4.0)(!(version>=3.0.0))) Unresolved requirements: [[org.glassfish.jersey.containers.jersey-container-grizzly2-http [142](R 142.0)] osgi.wiring.package; (&(osgi.wiring.package=org.glassfish.grizzly)(version>=2.4.0)(!(version>=3.0.0)))]");
+        
+        System.out.println(test1);
+        System.out.println("\n\n");
+        System.out.println(test2);
+    }
+
+}
diff --git a/nucleus/common/common-util/src/main/java/com/sun/enterprise/util/SystemPropertyConstants.java b/nucleus/common/common-util/src/main/java/com/sun/enterprise/util/SystemPropertyConstants.java
index a3091fc..c153239 100644
--- a/nucleus/common/common-util/src/main/java/com/sun/enterprise/util/SystemPropertyConstants.java
+++ b/nucleus/common/common-util/src/main/java/com/sun/enterprise/util/SystemPropertyConstants.java
@@ -16,11 +16,11 @@
 
 package com.sun.enterprise.util;
 
-import com.sun.enterprise.util.i18n.StringManager;
 import java.io.File;
 
-public class SystemPropertyConstants
-{
+import com.sun.enterprise.util.i18n.StringManager;
+
+public class SystemPropertyConstants {
 
     /**
      * Field used by Monitoring to encode a forward slash and/or dot
@@ -34,105 +34,97 @@
     public static final String UNIX_ASENV_FILENAME = "asenv.conf";
 
     /**
-     * Field 
+     * Field
      */
     public static final String WINDOWS_ASENV_FILENAME = "asenv.bat";
 
     /**
-     * Field 
+     * Field
      */
-    public static final String WEB_SERVICES_LIB_PROPERTY =
-        "com.sun.aas.webServicesLib";
-
-    /**
-     * Field 
-     */
-    public static final String PERL_ROOT_PROPERTY = "com.sun.aas.perlRoot";
-
-    /**
-     * Field 
-     */
-    public static final String IMQ_LIB_PROPERTY = "com.sun.aas.imqLib";
-
-    /**
-     * Field 
-     */
-    public static final String IMQ_BIN_PROPERTY = "com.sun.aas.imqBin";
-
-    /**
-     * Field 
-     */
-    public static final String CONFIG_ROOT_PROPERTY = "com.sun.aas.configRoot";
-
-    /**
-     * Field 
-     */
-    public static final String INSTALL_ROOT_PROPERTY =
-        "com.sun.aas.installRoot";
+    public static final String WEB_SERVICES_LIB_PROPERTY = "com.sun.aas.webServicesLib";
 
     /**
      * Field
      */
-    public static final String PRODUCT_ROOT_PROPERTY =
-        "com.sun.aas.productRoot";
+    public static final String PERL_ROOT_PROPERTY = "com.sun.aas.perlRoot";
 
     /**
-     * Field 
+     * Field
+     */
+    public static final String IMQ_LIB_PROPERTY = "com.sun.aas.imqLib";
+
+    /**
+     * Field
+     */
+    public static final String IMQ_BIN_PROPERTY = "com.sun.aas.imqBin";
+
+    /**
+     * Field
+     */
+    public static final String CONFIG_ROOT_PROPERTY = "com.sun.aas.configRoot";
+
+    /**
+     * Field
+     */
+    public static final String INSTALL_ROOT_PROPERTY = "com.sun.aas.installRoot";
+
+    /**
+     * Field
+     */
+    public static final String PRODUCT_ROOT_PROPERTY = "com.sun.aas.productRoot";
+
+    /**
+     * Field
      */
     public static final String JAVA_ROOT_PROPERTY = "com.sun.aas.javaRoot";
     public static final String JAVA_ROOT_PROPERTY_ASENV = "com.sun.aas.javaRoot.asenv";
 
     /**
-     * Field 
+     * Field
      */
     public static final String ICU_LIB_PROPERTY = "com.sun.aas.icuLib";
 
     /**
-     * Field 
+     * Field
      */
-    public static final String DEFAULT_LOCALE_PROPERTY =
-        "com.sun.aas.defaultLocale";
+    public static final String DEFAULT_LOCALE_PROPERTY = "com.sun.aas.defaultLocale";
 
     /**
-     * Field 
+     * Field
      */
-    public static final String DOMAINS_ROOT_PROPERTY =
-        "com.sun.aas.domainsRoot";
+    public static final String DOMAINS_ROOT_PROPERTY = "com.sun.aas.domainsRoot";
 
     /**
-     * Field 
+     * Field
      */
-    public static final String INSTANCE_ROOT_PROPERTY =
-        "com.sun.aas.instanceRoot";
-
-    /**
-     * The certificate nick name specified in the System-Jmx-Conenctor
-     * of the DAS with which a Node Agent synchronizes
-     */
-    public static final String AGENT_CERT_NICKNAME =
-        "com.sun.aas.agentCertNickname";
+    public static final String INSTANCE_ROOT_PROPERTY = "com.sun.aas.instanceRoot";
     
-    public static final String AGENT_ROOT_PROPERTY =
-        "com.sun.aas.agentRoot";
-    
-    public static final String AGENT_NAME_PROPERTY =
-        "com.sun.aas.agentName";
+    /**
+     * Field
+     */
+    public static final String DEBUG_MODE_PROPERTY = "com.sun.aas.debugMode";
 
     /**
-     * Field 
+     * The certificate nick name specified in the System-Jmx-Conenctor of the DAS with which a Node Agent synchronizes
      */
-    public static final String WEBCONSOLE_LIB_PROPERTY =
-        "com.sun.aas.webconsoleLib";
-    public static final String WEBCONSOLE_APP_PROPERTY =
-        "com.sun.aas.webconsoleApp";
+    public static final String AGENT_CERT_NICKNAME = "com.sun.aas.agentCertNickname";
 
-    public static final String JATO_ROOT_PROPERTY =
-        "com.sun.aas.jatoRoot";
+    public static final String AGENT_ROOT_PROPERTY = "com.sun.aas.agentRoot";
+
+    public static final String AGENT_NAME_PROPERTY = "com.sun.aas.agentName";
+
+    /**
+     * Field
+     */
+    public static final String WEBCONSOLE_LIB_PROPERTY = "com.sun.aas.webconsoleLib";
+    public static final String WEBCONSOLE_APP_PROPERTY = "com.sun.aas.webconsoleApp";
+
+    public static final String JATO_ROOT_PROPERTY = "com.sun.aas.jatoRoot";
 
     public static final String ANT_ROOT_PROPERTY = "com.sun.aas.antRoot";
 
     public static final String ANT_LIB_PROPERTY = "com.sun.aas.antLib";
-    
+
     public static final String JHELP_ROOT_PROPERTY = "com.sun.aas.jhelpRoot";
 
     /** name of the server instance key */
@@ -144,45 +136,38 @@
     /** name of the HADB location property **/
     public static final String HADB_ROOT_PROPERTY = "com.sun.aas.hadbRoot";
 
-        public static final String NSS_ROOT_PROPERTY = "com.sun.aas.nssRoot";
+    public static final String NSS_ROOT_PROPERTY = "com.sun.aas.nssRoot";
 
-    public static final String NSS_BIN_PROPERTY = "com.sun.aas.nssBin";        
+    public static final String NSS_BIN_PROPERTY = "com.sun.aas.nssBin";
 
     public static final String NATIVE_LAUNCHER = "com.sun.aas.nativeLauncher";
-    public static final String NATIVE_LAUNCHER_LIB_PREFIX = "com.sun.aas.nativeLauncherLibPrefix";       
-    
+    public static final String NATIVE_LAUNCHER_LIB_PREFIX = "com.sun.aas.nativeLauncherLibPrefix";
+
     public static final String KEYSTORE_PROPERTY = "javax.net.ssl.keyStore";
-    public static final String JKS_KEYSTORE = 
-        System.getProperty("file.separator") + "config" +
-        System.getProperty("file.separator") + "keystore.jks";
+    public static final String JKS_KEYSTORE = System.getProperty("file.separator") + "config" + System.getProperty("file.separator") + "keystore.jks";
 
     public static final String TRUSTSTORE_PROPERTY = "javax.net.ssl.trustStore";
-    public static final String JKS_TRUSTSTORE = 
-        System.getProperty("file.separator") + "config" +
-        System.getProperty("file.separator") + "cacerts.jks";
-   
-    public static final String ADMIN_REALM = "admin-realm"; 
+    public static final String JKS_TRUSTSTORE = System.getProperty("file.separator") + "config" + System.getProperty("file.separator") + "cacerts.jks";
+
+    public static final String ADMIN_REALM = "admin-realm";
     public static final String NSS_DB_PROPERTY = "com.sun.appserv.nss.db";
 
     public static final String NSS_DB_PASSWORD_PROPERTY = "com.sun.appserv.nss.db.password";
 
-    public static final String CLIENT_TRUSTSTORE_PROPERTY = 
-        TRUSTSTORE_PROPERTY;
-        //"com.sun.appserv.client.truststore";
+    public static final String CLIENT_TRUSTSTORE_PROPERTY = TRUSTSTORE_PROPERTY;
+    // "com.sun.appserv.client.truststore";
 
-    public static final String CLIENT_TRUSTSTORE_PASSWORD_PROPERTY =
-        "javax.net.ssl.trustStorePassword";
-        //"com.sun.appserv.client.truststore.password";
-    
+    public static final String CLIENT_TRUSTSTORE_PASSWORD_PROPERTY = "javax.net.ssl.trustStorePassword";
+    // "com.sun.appserv.client.truststore.password";
+
     public static final String PID_FILE = ".__com_sun_appserv_pid";
     public static final String REF_TS_FILE = "admsn";
-    
-    public static final String KILLSERV_SCRIPT = "killserv";    
-    
+
+    public static final String KILLSERV_SCRIPT = "killserv";
+
     public static final String KILL_SERV_UNIX = "killserv";
     public static final String KILL_SERV_WIN = "killserv.bat";
-    public static final String KILL_SERV_OS     = 
-        OS.isWindows() ? KILL_SERV_WIN : KILL_SERV_UNIX;
+    public static final String KILL_SERV_OS = OS.isWindows() ? KILL_SERV_WIN : KILL_SERV_UNIX;
 
     @Deprecated
     public static final String DEFAULT_SERVER_INSTANCE_NAME = "server";
@@ -190,16 +175,16 @@
     public static final String DAS_SERVER_NAME = "server";
     public static final String DAS_SERVER_CONFIG = "server-config";
 
-    public static final String JDMK_HOME_PROPERTY="com.sun.aas.jdmkHome";
-    
-    public static final String DERBY_ROOT_PROPERTY="com.sun.aas.derbyRoot";
+    public static final String JDMK_HOME_PROPERTY = "com.sun.aas.jdmkHome";
+
+    public static final String DERBY_ROOT_PROPERTY = "com.sun.aas.derbyRoot";
 
     /** Java ES Monitoring Framework install directory */
-    public static final String MFWK_HOME_PROPERTY="com.sun.aas.mfwkHome";
- 
-    /* An implementation note: This variable should be defined at one place.
-     * I have chosen this location because most of the other modules depend
-     * on appserv-commons for compilation.
+    public static final String MFWK_HOME_PROPERTY = "com.sun.aas.mfwkHome";
+
+    /*
+     * An implementation note: This variable should be defined at one place. I have chosen this location because most of the
+     * other modules depend on appserv-commons for compilation.
      */
     /** name of the domain key */
     public static final String DOMAIN_NAME = "domain.name";
@@ -207,98 +192,102 @@
     public static final String CONFIG_NAME_PROPERTY = "com.sun.aas.configName";
     public static final String DOCROOT_PROPERTY = "docroot";
     public static final String ACCESSLOG_PROPERTY = "accesslog";
-    public static final String DEFAULT_SERVER_SOCKET_ADDRESS="0.0.0.0";
-    public static final String CLUSTER_AWARE_FEATURE_FACTORY_CLASS 
-        = "com.sun.enterprise.ee.server.pluggable.EEPluggableFeatureImpl";
+    public static final String DEFAULT_SERVER_SOCKET_ADDRESS = "0.0.0.0";
+    public static final String CLUSTER_AWARE_FEATURE_FACTORY_CLASS = "com.sun.enterprise.ee.server.pluggable.EEPluggableFeatureImpl";
     public static final String DROP_INTERRUPTED_COMMANDS = "org.glassfish.job-manager.drop-interrupted-commands";
-    
+
     /** Name of the default config that determines the configuration for the instances */
     public static final String TEMPLATE_CONFIG_NAME = "default-config";
     public static final String DEFAULT_ADMIN_USER = "admin";
     public static final String DEFAULT_ADMIN_PASSWORD = "";
-    
+
     private static final StringManager sm = StringManager.getManager(SystemPropertyConstants.class);
+    
+    public static final String OPEN = "${";
+    public static final String CLOSE = "}";
 
-
-    /** A method that returns the passed String as a property that can
-     * be replaced at run time.
-     * @param name String that represents a property, e.g INSTANCE_ROOT_PROPERTY
-     * in this class. The String may not be null.
-     * @return a String that represents the replaceable value of passed String. Generally
-     * speaking it will be decorated with a pair of braces with $ in the front (e.g. "a" will be returned as "${a}").
+    /**
+     * A method that returns the passed String as a property that can be replaced at run time.
+     *
+     * @param name String that represents a property, e.g INSTANCE_ROOT_PROPERTY in this class. The String may not be null.
+     * @return a String that represents the replaceable value of passed String. Generally speaking it will be decorated with
+     * a pair of braces with $ in the front (e.g. "a" will be returned as "${a}").
      * @throws IllegalArgumentException if the passed String is null
      */
-	public static final String getPropertyAsValue(final String name) {
+    public static final String getPropertyAsValue(final String name) {
         if (name == null) {
-            final String pn = "spc.null_name";
-            final String pv = "property";
-            throw new IllegalArgumentException(sm.getString(pn, pv));
-        }
-        final StringBuffer sb   = new StringBuffer();
-        sb.append(OPEN).append(name).append(CLOSE);
-        return ( sb.toString() );
-	}
-        
-        public static final String OPEN       = "${";
-        public static final String CLOSE      = "}";
-        
-        /** Returns the string removing the "system-property syntax" from it.
-         * If the given string is not in "system-property syntax" the same string is returned.
-         * The "system-propery syntax" is "${...}"
-         * The given String may not be null.
-         * The returned String may be an empty String, if it is of the form "${}" (rarely so).
-         */
-        public static final String unSystemProperty(final String sp) {
-            if (sp == null) 
-                throw new IllegalArgumentException ("null_arg");
-            String ret = sp;
-            if (isSystemPropertySyntax(sp)) {
-                ret = sp.substring(2, sp.length() - 1);
-            }
-            return ( ret );
+            throw new IllegalArgumentException(sm.getString("spc.null_name", "property"));
         }
         
-        public static final boolean isSystemPropertySyntax(final String s) {
-            if ( s == null)
-                throw new IllegalArgumentException ("null_arg");
-            boolean sp = false;
-            if (s.startsWith(OPEN) && s.endsWith(CLOSE))
-                sp = true;
-            return ( sp );
+        return new StringBuffer().append(OPEN)
+                                 .append(name)
+                                 .append(CLOSE)
+                                 .toString();
+    }
+
+    /**
+     * Returns the string removing the "system-property syntax" from it. If the given string is not in "system-property
+     * syntax" the same string is returned. The "system-propery syntax" is "${...}" The given String may not be null. The
+     * returned String may be an empty String, if it is of the form "${}" (rarely so).
+     */
+    public static final String unSystemProperty(final String sp) {
+        if (sp == null) {
+            throw new IllegalArgumentException("null_arg");
         }
-    
-    /** Returns the default value (as would appear in the domain.xml on installation)
-     * of docroot of a virtual server, as a String. Never returns a null.
-     * Returned String contains no backslashes.
-     * Note that it is <b> not <b> the absolute value of the path on a file system.
+        
+        String ret = sp;
+        if (isSystemPropertySyntax(sp)) {
+            ret = sp.substring(2, sp.length() - 1);
+        }
+        
+        return ret;
+    }
+
+    public static final boolean isSystemPropertySyntax(final String s) {
+        if (s == null) {
+            throw new IllegalArgumentException("null_arg");
+        }
+        
+        boolean sp = false;
+        if (s.startsWith(OPEN) && s.endsWith(CLOSE)) {
+            sp = true;
+        }
+        
+        return sp;
+    }
+
+    /**
+     * Returns the default value (as would appear in the domain.xml on installation) of docroot of a virtual server, as a
+     * String. Never returns a null. Returned String contains no backslashes. Note that it is <b> not <b> the absolute value
+     * of the path on a file system.
      */
     public static final String getDocRootDefaultValue() {
-        final StringBuffer sb = new StringBuffer(getPropertyAsValue(INSTANCE_ROOT_PROPERTY));
-        return ( sb.append("/docroot").toString() );
+        return new StringBuffer(getPropertyAsValue(INSTANCE_ROOT_PROPERTY)).append("/docroot").toString();
     }
-    
-    /** Returns the default value (as would appear in the domain.xml on installation)
-     * of file where the acess log of a virtual server is stored, as a String. Never returns a null.
-     * Returned String contains no backslashes.
-     * Note that it is <b> not <b> the absolute value of the path on a file system.
+
+    /**
+     * Returns the default value (as would appear in the domain.xml on installation) of file where the acess log of a
+     * virtual server is stored, as a String. Never returns a null. Returned String contains no backslashes. Note that it is
+     * <b> not <b> the absolute value of the path on a file system.
      */
     public static final String getAccessLogDefaultValue() {
-        final StringBuffer sb = new StringBuffer(getPropertyAsValue(INSTANCE_ROOT_PROPERTY));
-        return ( sb.append("/logs/access").toString() );
+        return new StringBuffer(getPropertyAsValue(INSTANCE_ROOT_PROPERTY)).append("/logs/access").toString();
     }
-    
-    /** Returns the system specific file.separator delimited path to the asadmin script. Any changes to file layout should
 
-     * be reflected here. The path will contain '/' as the separator character, regardless of operating
-     * platform. Never returns a null. Assumes the the property "INSTALL_ROOT_PROPERTY" is set in the VM
-     * before calling this. As of now (September 2005) all the server instances and asadmin VM itself has
-     * this property set. The method does not guarantee that the script exists on the given system. It should
-     * only be used when caller wants to know the location of the script. Caller should make sure it exists.
-     * @return String representing the Path to asadmin script. Might return a string beginning with "null", if
-     * the INSTALL_ROOT_PROPERTY is not defined
+    /**
+     * Returns the system specific file.separator delimited path to the asadmin script. Any changes to file layout should
+     *
+     * be reflected here. The path will contain '/' as the separator character, regardless of operating platform. Never
+     * returns a null. Assumes the the property "INSTALL_ROOT_PROPERTY" is set in the VM before calling this. As of now
+     * (September 2005) all the server instances and asadmin VM itself has this property set. The method does not guarantee
+     * that the script exists on the given system. It should only be used when caller wants to know the location of the
+     * script. Caller should make sure it exists.
+     *
+     * @return String representing the Path to asadmin script. Might return a string beginning with "null", if the
+     * INSTALL_ROOT_PROPERTY is not defined
      */
     public static final String getAsAdminScriptLocation() {
-        return getAdminScriptLocation(System.getProperty(SystemPropertyConstants.INSTALL_ROOT_PROPERTY));
+        return getAdminScriptLocation(System.getProperty(INSTALL_ROOT_PROPERTY));
     }
 
     public static final String getAsAdminScriptLocation(String installRoot) {
@@ -306,27 +295,28 @@
     }
 
     public static final String getAdminScriptLocation(String installRoot) {
-        final StringBuilder sb = new StringBuilder();
-        final String ext = OS.isWindows() ? OS.WINDOWS_BATCH_FILE_EXTENSION : "";
-        final String ASADMIN = "nadmin";
-        final String suffix = new StringBuilder("lib").append(System.getProperty("file.separator")).append(ASADMIN).append(ext).toString();
+        StringBuilder sb = new StringBuilder();
+        String ext = OS.isWindows() ? OS.WINDOWS_BATCH_FILE_EXTENSION : "";
+        String ASADMIN = "nadmin";
+        String suffix = new StringBuilder("lib").append(System.getProperty("file.separator")).append(ASADMIN).append(ext).toString();
+
         sb.append(installRoot);
         final String fs = System.getProperty("file.separator");
-        if (!sb.toString().endsWith(fs))
+        if (!sb.toString().endsWith(fs)) {
             sb.append(fs);
+        }
         sb.append(suffix);
 
-        return ( sb.toString() );
+        return sb.toString();
     }
 
-    /** Returns the component identifier associated with the INSTALL_ROOT.
-     *  For example if INSTALL_ROOT is /home/glassfish6/glassfish the
-     *  component name will "glassfish".
+    /**
+     * Returns the component identifier associated with the INSTALL_ROOT. For example if INSTALL_ROOT is
+     * /home/glassfish6/glassfish the component name will "glassfish".
+     *
      * @return String representing the component identifier.
      */
     public static final String getComponentName() {
-        final File installRootFile = new File(System.getProperty(
-            SystemPropertyConstants.INSTALL_ROOT_PROPERTY));
-        return installRootFile.getName();
+        return new File(System.getProperty(INSTALL_ROOT_PROPERTY)).getName();
     }
 }
diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/APIClassLoaderServiceImpl.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/APIClassLoaderServiceImpl.java
index 810c5cf..fa76156 100644
--- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/APIClassLoaderServiceImpl.java
+++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/APIClassLoaderServiceImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2018 Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -16,90 +16,99 @@
 
 package com.sun.enterprise.v3.server;
 
-import com.sun.enterprise.module.HK2Module;
-import com.sun.enterprise.module.ModuleLifecycleListener;
-import com.sun.enterprise.module.ModuleState;
-import com.sun.enterprise.module.ModulesRegistry;
-import com.sun.enterprise.module.common_impl.CompositeEnumeration;
+import static com.sun.enterprise.util.FelixPrettyPrinter.prettyPrintExceptionMessage;
+import static com.sun.enterprise.util.SystemPropertyConstants.DEBUG_MODE_PROPERTY;
+import static java.util.Collections.enumeration;
+import static java.util.logging.Level.FINE;
+import static java.util.logging.Level.SEVERE;
+
 import java.io.IOException;
 import java.net.URL;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.Set;
-import java.util.logging.Level;
 import java.util.logging.Logger;
-import jakarta.inject.Inject;
+
 import org.glassfish.hk2.api.PostConstruct;
 import org.glassfish.kernel.KernelLoggerInfo;
 import org.jvnet.hk2.annotations.Service;
 
+import com.sun.enterprise.module.HK2Module;
+import com.sun.enterprise.module.ModuleLifecycleListener;
+import com.sun.enterprise.module.ModuleState;
+import com.sun.enterprise.module.ModulesRegistry;
+import com.sun.enterprise.module.common_impl.CompositeEnumeration;
+
+import jakarta.inject.Inject;
+
 /**
- * This class is responsible for creating a ClassLoader that can
- * load classes exported by the system for public use. We call those classes public APIs and
- * the corresponding class loader is called APIClassLoader.
- * Such classes include Java EE API, AMX API, appserv-ext API, etc.
- * CommonClassLoader delegates to this class loader.
- * This class has a punch-in mechanism to do special handling of META-INF/mailcap and META-INF/services resources.
+ * This class is responsible for creating a ClassLoader that can load classes exported by the system for public use. We
+ * call those classes public APIs and the corresponding class loader is called APIClassLoader. Such classes include Java
+ * EE API, AMX API, appserv-ext API, etc. CommonClassLoader delegates to this class loader. This class has a punch-in
+ * mechanism to do special handling of META-INF/mailcap and META-INF/services resources.
  *
  * @author Sanjeeb.Sahoo@Sun.COM
  */
 @Service
 public class APIClassLoaderServiceImpl implements PostConstruct {
 
-    /*
-     * Implementation Note:
-     * 1. This class currently depends on a special which is configured such that it can load all public APIs.
-     * The APIClassLoader is a wrapper around such a module's loader. This is how we are indepdendent of
-     * actual module system like OSGi. So far it has worked when we run in OSGi mode as well as when we run
-     * in a single classpath mode.
-     * 2. APIClassLoader maintains a blacklist, i.e., classes and resources that could not be loaded to avoid
-     * unnecessary delegation. It flushes that list everytime a new bundle is installed in the system.
-     * This takes care of performance problem in typical production use of GlassFish.
-     *
-     * TODO:
-     * 1. We need to add an upper threshold for blacklist to avoid excessive use of memory.
-     * 2. Externalize punch-in facility. We don't want to know about things like MAILCAP file in this class.
-     */
-
-    private ClassLoader theAPIClassLoader;
-    
-    @Inject
-    ModulesRegistry mr;
-    
     /**
      * This is the module that we delegate to.
      */
-    private static final String APIExporterModuleName =
-            "GlassFish-Application-Common-Module"; // NOI18N
+    private static final String APIExporterModuleName = "GlassFish-Application-Common-Module"; // NOI18N
     private static final String MAILCAP = "META-INF/mailcap";
     private static final String META_INF_SERVICES = "META-INF/services/"; // NOI18N
 
-    private static final String PUNCHIN_MODULE_STATE_PROP =
-            "glassfish.kernel.apicl.punchin.module.state"; // NOI18N
+    private static final String PUNCHIN_MODULE_STATE_PROP = "glassfish.kernel.apicl.punchin.module.state"; // NOI18N
 
     // set to NEW to maintain backward compatibility. We should change it to RESOLVED after we have
-    // done enough testing to make susre there are no regressions.
+    // done enough testing to make sure there are no regressions.
     public final ModuleState PUNCHIN_MODULE_STATE_DEFAULT_VALUE = ModuleState.NEW;
 
     private static final Enumeration<URL> EMPTY_URLS = new Enumeration<URL>() {
 
+        @Override
         public boolean hasMoreElements() {
             return false;
         }
 
+        @Override
         public URL nextElement() {
             throw new NoSuchElementException();
         }
     };
+    
     final static Logger logger = KernelLoggerInfo.getLogger();
+    
     private HK2Module APIModule;
+    
+    /*
+     * Implementation Note: 
+     * 
+     * 1. This class currently depends on a special which is configured such that it can load all
+     * public APIs. The APIClassLoader is a wrapper around such a module's loader. This is how we are independent of actual
+     * module system like OSGi. So far it has worked when we run in OSGi mode as well as when we run in a single classpath
+     * mode. 
+     * 
+     * 2. APIClassLoader maintains a blacklist, i.e., classes and resources that could not be loaded to avoid
+     * unnecessary delegation. It flushes that list every time a new bundle is installed in the system. This takes care of
+     * performance problem in typical production use of GlassFish.
+     *
+     * TODO: 1. We need to add an upper threshold for blacklist to avoid excessive use of memory. 2. Externalize punch-in
+     * facility. We don't want to know about things like MAILCAP file in this class.
+     */
 
+    private ClassLoader theAPIClassLoader;
+
+    @Inject
+    ModulesRegistry modulesRegistry;
+
+    @Override
     public void postConstruct() {
         try {
             createAPIClassLoader();
@@ -110,33 +119,36 @@
 
     private void createAPIClassLoader() throws IOException {
 
-        APIModule = mr.getModules(APIExporterModuleName).iterator().next();
-        assert (APIModule != null);
-        final ClassLoader apiModuleLoader = APIModule.getClassLoader();
+        // The default module to load from is the common module, this dynamically loads from every other module.
+        APIModule = modulesRegistry.getModules(APIExporterModuleName).iterator().next();
+        assert APIModule != null;
+        
         /*
-         * We don't directly retrun APIModule's class loader, because
-         * that class loader does not delegate to the parent. Instead, it
-         * relies on OSGi bundle or some such module implementation to load the classes. That behavior is
-         * fine if we want to mimic underlying module system's classloading semantics. But, APIClassLoader has a
-         * slightly different requirement. It has to use classic delegation model as well so that
-         * deployed applications can use classes made available via extension class loader.
-         * Since the parent of bundle classloader will have glassfish launching classes, felix or any other
-         * OSGi framework classes and their dependencies, we don't want to delegate to such a class loader.
-         * Instead, we delegate to JRE's extension class loader if we don't find any class via APIModuleLoader.
-         * With this, user can actually embed a different version of Felix as part of their app.
+         * We don't directly return APIModule's class loader, because that class loader does not delegate to the parent.
+         * 
+         * Instead, it relies on OSGi bundle or some such module implementation to load the classes. That behavior is fine if we
+         * want to mimic underlying module system's classloading semantics. But, APIClassLoader has a slightly different
+         * requirement. It has to use classic delegation model as well so that deployed applications can use classes made
+         * available via extension class loader. 
+         * 
+         * Since the parent of bundle classloader will have glassfish launching classes,
+         * felix or any other OSGi framework classes and their dependencies, we don't want to delegate to such a class loader.
+         * 
+         * Instead, we delegate to JRE's extension class loader if we don't find any class via APIModuleLoader. With this, user
+         * can actually embed a different version of Felix as part of their app.
          */
-        theAPIClassLoader = new APIClassLoader(apiModuleLoader, getExtensionClassLoader());
-        logger.logp(Level.FINE, "APIClassLoaderService", "createAPIClassLoader",
-                "APIClassLoader = {0}", new Object[]{theAPIClassLoader});
+        theAPIClassLoader = new APIClassLoader(APIModule.getClassLoader(), getExtensionClassLoader());
+        logger.logp(FINE, "APIClassLoaderService", "createAPIClassLoader", "APIClassLoader = {0}", new Object[] { theAPIClassLoader });
     }
 
     private ClassLoader getExtensionClassLoader() {
         if (System.getSecurityManager() != null) {
             return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                @Override
                 public ClassLoader run() {
                     return ClassLoader.getSystemClassLoader().getParent();
                 }
-            });        
+            });
         } else {
             return ClassLoader.getSystemClassLoader().getParent();
         }
@@ -148,44 +160,50 @@
 
     private class APIClassLoader extends ClassLoader {
 
+        private final ClassLoader apiModuleLoader;
+        
         // list of not found classes and resources.
         // the string represents resource name, so foo/Bar.class for foo.Bar
         private Set<String> blacklist;
-        private final ClassLoader apiModuleLoader;
-        private ModuleState punchInModuleState = ModuleState.valueOf(System.getProperty(PUNCHIN_MODULE_STATE_PROP,
-                PUNCHIN_MODULE_STATE_DEFAULT_VALUE.toString()));
+        
+        private ModuleState punchInModuleState = 
+            ModuleState.valueOf(System.getProperty(PUNCHIN_MODULE_STATE_PROP, PUNCHIN_MODULE_STATE_DEFAULT_VALUE.toString()));
 
         /**
-         * This method takes two classloaders which is unusual. Both the class loaders are consulted,
-         * so they both are delegates, but depending on the class/resource being requested, one is preferred
-         * over the other. The second argument is the classic parent class loader, where as the first one
-         * is the module system gateway classloader. For all java.* names, we consult only the parent loader.
-         * For any other names, we first consult the gateway loader and then parent. See more comments in
-         * {@link #loadClass(String)} method implementation of this class.
+         * This method takes two classloaders which is unusual. Both the class loaders are consulted, so they both are
+         * delegates, but depending on the class/resource being requested, one is preferred over the other. The second argument
+         * is the classic parent class loader, where as the first one is the module system gateway classloader. For all java.*
+         * names, we consult only the parent loader. For any other names, we first consult the gateway loader and then parent.
+         * See more comments in {@link #loadClass(String)} method implementation of this class.
+         *
          * @param apiModuleLoader ClassLoader corresponding to the APIModule
-         * @param parent ClassLoader that's consulted for all java.* classes and for classes
-         * not found via apiModuleLoader
+         * @param parent ClassLoader that's consulted for all java.* classes and for classes not found via apiModuleLoader
          */
         public APIClassLoader(ClassLoader apiModuleLoader, ClassLoader parent) {
             super(parent);
             this.apiModuleLoader = apiModuleLoader;
-            blacklist = new HashSet<String>();
+            blacklist = new HashSet<>();
 
             // add a listener to manage blacklist in APIClassLoader
-            mr.register(new ModuleLifecycleListener() {
+            modulesRegistry.register(new ModuleLifecycleListener() {
+                @Override
                 public void moduleInstalled(HK2Module module) {
                     clearBlackList();
                 }
 
+                @Override
                 public void moduleResolved(HK2Module module) {
                 }
 
+                @Override
                 public void moduleStarted(HK2Module module) {
                 }
 
+                @Override
                 public void moduleStopped(HK2Module module) {
                 }
 
+                @Override
                 public void moduleUpdated(HK2Module module) {
                     clearBlackList();
                 }
@@ -197,65 +215,97 @@
         public Class<?> loadClass(String name) throws ClassNotFoundException {
             return loadClass(name, false);
         }
+        
+       
 
         @Override
         protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
             // First check if we know this can't be loaded
-            final String resourceName = convertToResourceName(name);
+            String resourceName = convertToResourceName(name);
             if (isBlackListed(resourceName)) {
                 throw new ClassNotFoundException(name);
             }
 
             // Then check if the class has already been loaded
-            Class c = findLoadedClass(name);
-            if (c == null) {
+            Class<?> loadedClass = findLoadedClass(name);
+            
+            if (loadedClass == null) {
                 if (!name.startsWith("java.")) { // java classes always come from parent
                     try {
-                        c = apiModuleLoader.loadClass(name); // we ignore the resolution flag
+                        loadedClass = apiModuleLoader.loadClass(name); // we ignore the resolution flag
                     } catch (ClassNotFoundException cnfe) {
-                        // punch in. find the provider class, no matter where we are.
-                        HK2Module m = mr.getProvidingModule(name);
-                        if (m != null) {
-                            if(select(m)) {
-                                return m.getClassLoader().loadClass(name); // abort search if we fail to load.
+                        
+                        // Punch in. 
+                        // Find the module that provides the class, no matter where we are.
+                        HK2Module classProvidingModule = modulesRegistry.getProvidingModule(name);
+                        
+                        if (classProvidingModule != null) {
+                            if (select(classProvidingModule)) {
+                                try {
+                                    return classProvidingModule.getClassLoader().loadClass(name); // abort search if we fail to load.
+                                } catch (ClassNotFoundException cnfe2) {
+                                    
+                                    // Only in debug mode, since the child classloader can legitimately  try other souces to load a class
+                                    if ((Boolean.valueOf(System.getProperty(DEBUG_MODE_PROPERTY)))) {
+                                        logger.logp(SEVERE, "APIClassLoaderServiceImpl$APIClassLoader", "loadClass", name, cnfe2);
+
+                                        if (cnfe2.getCause() != null) {
+                                            String message = prettyPrintExceptionMessage(cnfe2.getCause().getMessage());
+
+                                            if (message != null && !message.isEmpty()) {
+                                                logger.logp(SEVERE, "APIClassLoaderServiceImpl$APIClassLoader", "loadClass", 
+                                                        
+                                                    "\nFailed loading class " + name + " by API Class Loader\n\n" +    
+                                                    message + "\n");
+                                            }
+                                        }
+                                    }
+                                    
+                                    throw cnfe2;
+                                    
+                                }
                             } else {
-                                logger.logp(Level.FINE, "APIClassLoaderServiceImpl$APIClassLoader", "loadClass",
-                                        "Skipping loading {0} from module {1} as this module is not yet resolved.",
-                                        new Object[]{name, m});
+                                logger.logp(FINE, "APIClassLoaderServiceImpl$APIClassLoader", "loadClass",
+                                        "Skipping loading {0} from module {1} as this module is not yet resolved.", new Object[] { name, classProvidingModule });
                             }
                         }
                     }
                 }
-                if (c == null) {
-                    // Call super class implementation which takes care of
-                    // delegating to parent.
+                
+                // This would be called for javax.* classes, and in the rare(?) case there's no providing module.
+                if (loadedClass == null) {
+                    // Call super class implementation which takes care of delegating to parent.
                     try {
-                        c = super.loadClass(name, resolve);
+                        loadedClass = super.loadClass(name, resolve);
                     } catch (ClassNotFoundException e) {
                         addToBlackList(resourceName);
                         throw e;
                     }
                 }
             }
-            return c;
+            
+            return loadedClass;
         }
 
         /**
-         * Select this module if it meets punch-in criteria. At this point of implementation, the criteria is
-         * very simple. It checks to see if the module's state is greater than equal to what is configured in
-         * {@link #punchInModuleState}.
-         * 
-         * @param m
+         * Select this module if it meets punch-in criteria. At this point of implementation, the criteria is very simple. It
+         * checks to see if the module's state is greater than equal to what is configured in {@link #punchInModuleState}.
+         *
+         * @param module
          * @return
          */
-        private boolean select(HK2Module m) {
-            ModuleState state = m.getState();
+        private boolean select(HK2Module module) {
+            ModuleState state = module.getState();
+            
             return state.compareTo(punchInModuleState) >= 0 && state != ModuleState.ERROR;
         }
 
         @Override
         public URL getResource(String name) {
-            if (isBlackListed(name)) return null;
+            if (isBlackListed(name)) {
+                return null;
+            }
+            
             URL url = null;
             if (!name.startsWith("java/")) {
                 url = apiModuleLoader.getResource(name);
@@ -267,29 +317,33 @@
                 if (name.equals(MAILCAP)) {
                     // punch in for META-INF/mailcap files.
                     // see issue #8426
-                    for (HK2Module m : mr.getModules()) {
-                        if (!select(m)) continue;
-                        if ((url = m.getClassLoader().getResource(name)) != null) {
+                    for (HK2Module module : modulesRegistry.getModules()) {
+                        if (!select(module)) {
+                            continue;
+                        }
+                        if ((url = module.getClassLoader().getResource(name)) != null) {
                             return url;
                         }
                     }
-                } else if(name.startsWith(META_INF_SERVICES)) {
+                } else if (name.startsWith(META_INF_SERVICES)) {
                     // punch in to find the service loader from any module
                     // If this is a META-INF/services lookup, search in every
                     // modules that we know of.
-                    String serviceName = name.substring(
-                            META_INF_SERVICES.length());
+                    String serviceName = name.substring(META_INF_SERVICES.length());
 
-                    for( HK2Module m : mr.getModules() ) {
-                        if (!select(m)) continue;
-                        List<URL> list = m.getMetadata().getDescriptors(
-                                serviceName);
-                        if(!list.isEmpty()) {
+                    for (HK2Module module : modulesRegistry.getModules()) {
+                        if (!select(module)) {
+                            continue;
+                        }
+                        
+                        List<URL> list = module.getMetadata().getDescriptors(serviceName);
+                        if (!list.isEmpty()) {
                             return list.get(0);
                         }
                     }
                 }
             }
+            
             // Either requested resource belongs to java/ namespace or
             // it was not found in any of the bundles, so call
             // super class implementation which will delegate to parent.
@@ -297,6 +351,7 @@
             if (url == null) {
                 addToBlackList(name);
             }
+            
             return url;
         }
 
@@ -306,6 +361,7 @@
         private ClassLoader getParent_() {
             if (System.getSecurityManager() != null) {
                 return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                    @Override
                     public ClassLoader run() {
                         return getParent();
                     }
@@ -317,11 +373,12 @@
 
         @Override
         public Enumeration<URL> getResources(String name) throws IOException {
-            List<Enumeration<URL>> enumerators = new ArrayList<Enumeration<URL>>();
+            List<Enumeration<URL>> enumerators = new ArrayList<>();
             enumerators.add(findResources(name));
             if (getParent_() != null) {
                 enumerators.add(getParent_().getResources(name));
             }
+            
             return new CompositeEnumeration(enumerators);
         }
 
@@ -332,42 +389,58 @@
         @Override
         protected Enumeration<URL> findResources(String name) throws IOException {
             if (!name.startsWith("java/")) {
-                List<Enumeration<URL>> enumerations = new ArrayList<Enumeration<URL>>();
+                
+                List<Enumeration<URL>> enumerations = new ArrayList<>();
                 Enumeration<URL> apiResources = apiModuleLoader.getResources(name);
                 if (apiResources.hasMoreElements()) {
                     enumerations.add(apiResources);
                 }
 
-                // now punch-ins for various cases that require special handling
+                // Now punch-ins for various cases that require special handling
+                
                 if (name.equals(MAILCAP)) {
-                     // punch in for META-INF/mailcap files. see issue #8426
-                    for (HK2Module m : mr.getModules()) {
-                        if (!select(m)) continue; // We don't look in unresolved modules
-                        if (m == APIModule) continue; // we have already looked up resources in apiModuleLoader
-                        enumerations.add(m.getClassLoader().getResources(name));
+                    
+                    // Punch in for META-INF/mailcap files. see issue #8426
+                    for (HK2Module module : modulesRegistry.getModules()) {
+                        if (!select(module)) {
+                            continue; // We don't look in unresolved modules
+                        }
+                        
+                        if (module == APIModule) {
+                            continue; // we have already looked up resources in apiModuleLoader
+                        }
+                        
+                        enumerations.add(module.getClassLoader().getResources(name));
                     }
                 } else if (name.startsWith(META_INF_SERVICES)) {
-                    // punch in. find the service loader from any module
+                    
+                    // Punch in. find the service loader from any module
+                    
                     String serviceName = name.substring(META_INF_SERVICES.length());
-                    List<URL> punchedInURLs = new ArrayList<URL>();
-                    for (HK2Module m : mr.getModules()) {
-                        if (!select(m)) continue; // We don't look in modules that don't meet punch in criteria
-                        if (m == APIModule) continue; // we have already looked up resources in apiModuleLoader
-                        punchedInURLs.addAll(m.getMetadata().getDescriptors(serviceName));
+                    List<URL> punchedInURLs = new ArrayList<>();
+                    for (HK2Module module : modulesRegistry.getModules()) {
+                        if (!select(module)) {
+                            continue; // We don't look in modules that don't meet punch in criteria
+                        }
+                        if (module == APIModule) {
+                            continue; // we have already looked up resources in apiModuleLoader
+                        }
+                        punchedInURLs.addAll(module.getMetadata().getDescriptors(serviceName));
                     }
+                    
                     if (!punchedInURLs.isEmpty()) {
-                        enumerations.add(Collections.enumeration(punchedInURLs));
+                        enumerations.add(enumeration(punchedInURLs));
                     }
                 }
 
-                // now assemble the result and return
+                // Now assemble the result and return
                 switch (enumerations.size()) {
-                    case 0:
-                        return EMPTY_URLS;
-                    case 1:
-                        return enumerations.get(0);
-                    default:
-                        return new CompositeEnumeration(enumerations);
+                case 0:
+                    return EMPTY_URLS;
+                case 1:
+                    return enumerations.get(0);
+                default:
+                    return new CompositeEnumeration(enumerations);
                 }
             }
             return EMPTY_URLS;
@@ -379,8 +452,7 @@
         }
 
         /**
-         * Takes a class name as used in Class.forName and converts it to a resource name as used in
-         * ClassLoader.getResource
+         * Takes a class name as used in Class.forName and converts it to a resource name as used in ClassLoader.getResource
          *
          * @param className className to be converted
          * @return equivalent resource name
diff --git a/nucleus/core/kernel/src/test/java/com/sun/enterprise/v3/server/APIClassLoaderServiceImplTest.java b/nucleus/core/kernel/src/test/java/com/sun/enterprise/v3/server/APIClassLoaderServiceImplTest.java
index 3b5d254..96fdd66 100644
--- a/nucleus/core/kernel/src/test/java/com/sun/enterprise/v3/server/APIClassLoaderServiceImplTest.java
+++ b/nucleus/core/kernel/src/test/java/com/sun/enterprise/v3/server/APIClassLoaderServiceImplTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2018 Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -28,149 +28,142 @@
 import com.sun.enterprise.module.single.SingleModulesRegistry;
 
 public class APIClassLoaderServiceImplTest {
-	int loadClassCalls;
-	int getResourceCalls;
+    int loadClassCalls;
+    int getResourceCalls;
 
-	@Before
-	public void setUp() {
-		loadClassCalls = 0;
-		getResourceCalls = 0;
-	}
+    @Before
+    public void setUp() {
+        loadClassCalls = 0;
+        getResourceCalls = 0;
+    }
 
-	/**
-	 * This test ensures that the ApiClassLoaderService will not attempt to load a class or find a resource after 
-	 * an initial negative result until a module is installed or update. 
-	 */
-	@Test
-	public void testBlackList() {
-		APIClassLoaderServiceImpl apiClassLoaderService = new APIClassLoaderServiceImpl();
+    /**
+     * This test ensures that the ApiClassLoaderService will not attempt to load a class or find a resource after an initial
+     * negative result until a module is installed or update.
+     */
+    @Test
+    public void testBlackList() {
+        try {
+            APIClassLoaderServiceImpl apiClassLoaderService = new APIClassLoaderServiceImpl();
 
-		// set up a fake ModulesRegistry to exercise ModulesRegistry lifecycle
-		// events
-		FakeClassLoader classLoader = new FakeClassLoader(getClass()
-				.getClassLoader());
-		FakeModulesRegistry mr = new FakeModulesRegistry(classLoader);
+            // Set up a fake ModulesRegistry to exercise ModulesRegistry lifecycle events
+            FakeClassLoader classLoader = new FakeClassLoader(getClass().getClassLoader());
+            FakeModulesRegistry fakeModulesRegistry = new FakeModulesRegistry(classLoader);
 
-		apiClassLoaderService.mr = mr;
+            apiClassLoaderService.modulesRegistry = fakeModulesRegistry;
 
-		assertEquals(0, mr.getLifecycleListeners().size());
+            assertEquals(0, fakeModulesRegistry.getLifecycleListeners().size());
 
-		apiClassLoaderService.postConstruct();
+            apiClassLoaderService.postConstruct();
 
-		List<ModuleLifecycleListener> lifecycleListeners = mr
-				.getLifecycleListeners();
+            List<ModuleLifecycleListener> lifecycleListeners = fakeModulesRegistry.getLifecycleListeners();
 
-		assertEquals(
-				"apiClassLoaderService should have registered a lifecycle listener",
-				1, mr.getLifecycleListeners().size());
+            assertEquals("apiClassLoaderService should have registered a lifecycle listener", 1, fakeModulesRegistry.getLifecycleListeners().size());
 
-		ModuleLifecycleListener lifecycleListener = lifecycleListeners
-				.iterator().next();
+            ModuleLifecycleListener lifecycleListener = lifecycleListeners.iterator().next();
 
-		// assert that the classloader isn't called on to load the same bad
-		// class twice
-		assertEquals(0, loadClassCalls);
+            
+            // assert that the classloader isn't called on to load the same bad
+            // class twice
+            assertEquals(0, loadClassCalls);
 
-		final String BAD_CLASSNAME = "BADCLASS";
+            final String BAD_CLASSNAME = "BADCLASS";
 
-		try {
-			apiClassLoaderService.getAPIClassLoader().loadClass(BAD_CLASSNAME);
-		} catch (ClassNotFoundException e) {
-			// ignore
-		}
+            try {
+                apiClassLoaderService.getAPIClassLoader().loadClass(BAD_CLASSNAME);
+            } catch (ClassNotFoundException e) {
+                // ignore
+            }
 
-		assertEquals("Classloader.loadClass not called at all", 1,
-				loadClassCalls);
+            assertEquals("Classloader.loadClass not called at all", 1, loadClassCalls);
 
-		try {
-			apiClassLoaderService.getAPIClassLoader().loadClass(BAD_CLASSNAME);
-		} catch (ClassNotFoundException e) {
-			// ignore
-		}
+            try {
+                apiClassLoaderService.getAPIClassLoader().loadClass(BAD_CLASSNAME);
+            } catch (ClassNotFoundException e) {
+                // ignore
+            }
 
-		assertEquals(
-				"blacklist not honored, excessive call to classloader.load", 1,
-				loadClassCalls);
+            assertEquals("blacklist not honored, excessive call to classloader.load", 1, loadClassCalls);
 
-		// try same thing with resources
+            
+            // try same thing with resources
 
-		assertEquals(0, getResourceCalls); // sanity
+            assertEquals(0, getResourceCalls); // sanity
 
-		final String BAD_RESOURCE = "BADRESOURCE";
+            final String BAD_RESOURCE = "BADRESOURCE";
 
-		apiClassLoaderService.getAPIClassLoader().getResource(BAD_RESOURCE);
+            apiClassLoaderService.getAPIClassLoader().getResource(BAD_RESOURCE);
 
-		assertEquals("Classloader.findResource not called at all", 1,
-				getResourceCalls);
+            assertEquals("Classloader.findResource not called at all", 1, getResourceCalls);
 
-		apiClassLoaderService.getAPIClassLoader().getResource(BAD_RESOURCE);
+            apiClassLoaderService.getAPIClassLoader().getResource(BAD_RESOURCE);
 
-		assertEquals(
-				"blacklist not honored, excessive call to classloader.getResource",
-				1, getResourceCalls);
+            assertEquals("blacklist not honored, excessive call to classloader.getResource", 1, getResourceCalls);
 
-		//
-		// Now signal that a new module has been loaded, clearing the blacklist
-		//
+            
+            //
+            // Now signal that a new module has been loaded, clearing the blacklist
+            //
 
-		lifecycleListener.moduleInstalled(null);
+            lifecycleListener.moduleInstalled(null);
 
-		apiClassLoaderService.getAPIClassLoader().getResource(BAD_RESOURCE);
-		assertEquals("blacklist did not clear after a module was installed", 2,
-				getResourceCalls);
+            apiClassLoaderService.getAPIClassLoader().getResource(BAD_RESOURCE);
+            assertEquals("blacklist did not clear after a module was installed", 2, getResourceCalls);
 
-		try {
-			apiClassLoaderService.getAPIClassLoader().loadClass(BAD_CLASSNAME);
-		} catch (ClassNotFoundException e) {
-			// ignore
-		}
+            try {
+                apiClassLoaderService.getAPIClassLoader().loadClass(BAD_CLASSNAME);
+            } catch (ClassNotFoundException e) {
+                // ignore
+            }
 
-		assertEquals("blacklist did not clear after a module was installed", 2,
-				loadClassCalls);
+            assertEquals("blacklist did not clear after a module was installed", 2, loadClassCalls);
 
-		//
-		// Now signal that a new module has been updated, clearing the blacklist
-		//
+            
+            //
+            // Now signal that a new module has been updated, clearing the blacklist
+            //
 
-		lifecycleListener.moduleUpdated(null);
+            lifecycleListener.moduleUpdated(null);
 
-		apiClassLoaderService.getAPIClassLoader().getResource(BAD_RESOURCE);
-		assertEquals("blacklist did not clear after a module was updated", 3,
-				getResourceCalls);
+            apiClassLoaderService.getAPIClassLoader().getResource(BAD_RESOURCE);
+            assertEquals("blacklist did not clear after a module was updated", 3, getResourceCalls);
 
-		try {
-			apiClassLoaderService.getAPIClassLoader().loadClass(BAD_CLASSNAME);
-		} catch (ClassNotFoundException e) {
-			// ignore
-		}
+            try {
+                apiClassLoaderService.getAPIClassLoader().loadClass(BAD_CLASSNAME);
+            } catch (ClassNotFoundException e) {
+                // ignore
+            }
 
-		assertEquals("blacklist did not clear after a module was updated", 3,
-				loadClassCalls);
+            assertEquals("blacklist did not clear after a module was updated", 3, loadClassCalls);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw e;
+        }
 
-	}
+    }
 
-	class FakeModulesRegistry extends SingleModulesRegistry {
-		public FakeModulesRegistry(ClassLoader cl) {
-			super(cl);
-		}
-	}
+    class FakeModulesRegistry extends SingleModulesRegistry {
+        public FakeModulesRegistry(ClassLoader cl) {
+            super(cl);
+        }
+    }
 
-	class FakeClassLoader extends ClassLoader {
-		public FakeClassLoader(ClassLoader parent) {
-			super(parent);
-		}
+    class FakeClassLoader extends ClassLoader {
+        public FakeClassLoader(ClassLoader parent) {
+            super(parent);
+        }
 
-		@Override
-		public Class<?> loadClass(String arg0) throws ClassNotFoundException {
-			loadClassCalls++;
-			return super.loadClass(arg0);
-		}
+        @Override
+        public Class<?> loadClass(String arg0) throws ClassNotFoundException {
+            loadClassCalls++;
+            return super.loadClass(arg0);
+        }
 
-		@Override
-		protected URL findResource(String arg0) {
-			getResourceCalls++;
-			return super.findResource(arg0);
-		}
+        @Override
+        protected URL findResource(String arg0) {
+            getResourceCalls++;
+            return super.findResource(arg0);
+        }
 
-	}
+    }
 }
diff --git a/nucleus/hk2/config-generator/pom.xml b/nucleus/hk2/config-generator/pom.xml
index b27e4e9..1db9f24 100644
--- a/nucleus/hk2/config-generator/pom.xml
+++ b/nucleus/hk2/config-generator/pom.xml
@@ -64,17 +64,17 @@
         <dependency>
             <groupId>org.apache.maven</groupId>
             <artifactId>maven-plugin-api</artifactId>
-            <version>3.3.9</version>
+            <version>3.6.3</version>
         </dependency>
         <dependency>
             <groupId>org.apache.maven</groupId>
             <artifactId>maven-core</artifactId>
-            <version>3.3.9</version>
+            <version>3.6.3</version>
         </dependency>
         <dependency>
             <groupId>org.glassfish.jaxb</groupId>
             <artifactId>codemodel</artifactId>
-            <version>2.3.0</version>
+            <version>3.0.0-M4</version>
         </dependency>
         <dependency>
             <groupId>jakarta.annotation</groupId>
diff --git a/nucleus/parent/pom.xml b/nucleus/parent/pom.xml
index 2632fc3..d8d1916 100644
--- a/nucleus/parent/pom.xml
+++ b/nucleus/parent/pom.xml
@@ -90,7 +90,7 @@
 
         <!-- Jakarta Validation -->
         <jakarta.validation.version>3.0.0-M1</jakarta.validation.version>        
-        <hibernate-validator.version>7.0.0.Alpha2</hibernate-validator.version>
+        <hibernate-validator.version>7.0.0.Alpha3</hibernate-validator.version>
 
         <!-- Jakarta Web Services -->
         <webservices.version>3.0.0-M2</webservices.version>
@@ -117,7 +117,7 @@
         <jakarta.annotation-api.version>2.0.0-RC1</jakarta.annotation-api.version>
 
         <!-- GlassFish Components -->                                   
-        <glassfish-corba.version>4.2.0</glassfish-corba.version>
+        <glassfish-corba.version>4.2.1</glassfish-corba.version>
         <grizzly.version>3.0.0-M1</grizzly.version>
         <grizzly.npn.version>1.9</grizzly.npn.version>
         <glassfish-management-api.version>3.2.3</glassfish-management-api.version>
@@ -137,14 +137,14 @@
         <stax-api.version>1.0-2</stax-api.version>
         <slf4j.version>1.7.21</slf4j.version>
         <jboss.logging.annotation.version>2.2.1.Final</jboss.logging.annotation.version>
-        <javassist.version>3.26.0-GA</javassist.version>
+        <javassist.version>3.27.0-GA</javassist.version>
         <jboss.logging.version>3.4.1.Final</jboss.logging.version>
         <fasterxml.classmate.version>1.5.1</fasterxml.classmate.version>
         <jsch.version>0.1.56</jsch.version>
         <antlr.version>2.7.8</antlr.version>
         <ant.version>1.10.2</ant.version>
-        <jackson.version>2.10.2</jackson.version>
-        <jettison.version>1.4.0</jettison.version>
+        <jackson.version>2.11.0</jackson.version>
+        <jettison.version>1.4.1</jettison.version>
         <mimepull.version>1.9.13</mimepull.version>
         <asm.version>7.3.1</asm.version>
 
@@ -747,7 +747,7 @@
             <dependency>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>org.apache.felix.webconsole</artifactId>
-                <version>4.3.16</version>
+                <version>4.5.2</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.felix</groupId>
@@ -915,7 +915,7 @@
             <dependency>
                 <groupId>commons-io</groupId>
                 <artifactId>commons-io</artifactId>
-                <version>2.6</version>
+                <version>2.7</version>
             </dependency>
             <dependency>
                 <groupId>org.glassfish.external</groupId>
@@ -925,7 +925,7 @@
             <dependency>
                 <groupId>org.apache.ant</groupId>
                 <artifactId>ant-launcher</artifactId>
-                <version>1.10.7</version>
+                <version>1.10.8</version>
             </dependency>
             <dependency>
                 <groupId>org.glassfish.external</groupId>
@@ -985,7 +985,7 @@
             <dependency>
                <groupId>org.apache.felix</groupId>
                <artifactId>org.apache.felix.fileinstall</artifactId>
-               <version>3.6.4</version>
+               <version>3.6.6</version>
             </dependency>
             <dependency>
                <groupId>org.apache.felix</groupId>
@@ -999,7 +999,7 @@
             <dependency>
                <groupId>org.apache.felix</groupId>
                <artifactId>org.apache.felix.scr</artifactId>
-               <version>2.1.16</version>
+               <version>2.1.20</version>
             </dependency>
             <dependency>
                 <groupId>org.osgi</groupId>
@@ -1026,7 +1026,7 @@
             <dependency>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
-                <version>3.1.1</version>
+                <version>3.2.0</version>
             </dependency>
             <dependency>
                 <groupId>org.ow2.asm</groupId>