[maven-release-plugin]  copy for tag uima-ducc-2.2.0

git-svn-id: https://svn.apache.org/repos/asf/uima/uima-ducc/tags/uima-ducc-2.2.0@1781556 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/RELEASE_NOTES.html b/RELEASE_NOTES.html
index ca7b154..0beb736 100755
--- a/RELEASE_NOTES.html
+++ b/RELEASE_NOTES.html
@@ -29,7 +29,8 @@
 <p>
 <a href="#what.is.uima-ducc">1. What is UIMA-DUCC?</a><br/>
 <a href="#major.changes">2. Major Changes in this Release</a><br/>
-<a href="#migration">3. Migration from a Prior Release</a><br/></p>  
+<a href="#migration">3. Migration from a Prior Release</a><br/>  
+<a href="#migration">4. Limitations</a><br/></p>  
    
 <h2><a name="what.is.uima-ducc">1. What is UIMA-DUCC?</a></h2>
 <p>
@@ -59,6 +60,7 @@
 <li>Enhanced DUCC Job Driver (JD) to provide individual work item performance breakdowns</li>
 <li>Modified DUCC to restrict broker use to ducc user only</li>
 <li>On process launch failure, agent supplies a reason for failure for display in ducc mon</li>
+<li>Added duplicate daemon detector to prevent starting duplicate DUCC daemon</li>
 <li>Many DUCC Database improvements </li>
 <li>Many DUCC webpage improvements </li>
 
diff --git a/issuesFixed/jira-report.html b/issuesFixed/jira-report.html
deleted file mode 100644
index e55ccb1..0000000
--- a/issuesFixed/jira-report.html
+++ /dev/null
@@ -1,283 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<!-- Generated by Apache Maven Doxia Site Renderer 1.4 at 2017-01-04 -->
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-    <title>JIRA Report - JIRA Report</title>
-    <style type="text/css" media="all">
-      @import url("./css/maven-base.css");
-      @import url("./css/maven-theme.css");
-      @import url("./css/site.css");
-    </style>
-    <link rel="stylesheet" href="./css/print.css" type="text/css" media="print" />
-    <meta name="Date-Revision-yyyymmdd" content="20170104" />
-    <meta http-equiv="Content-Language" content="en" />
-        
-        </head>
-  <body class="composite">
-    <div id="banner">
-                      <div class="clear">
-        <hr/>
-      </div>
-    </div>
-    <div id="breadcrumbs">
-            
-                    
-                <div class="xleft">
-        <span id="publishDate">Last Published: 2017-01-04</span>
-                  &nbsp;| <span id="projectVersion">Version: ${project.version}</span>
-                      </div>
-            <div class="xright">        
-                    
-      </div>
-      <div class="clear">
-        <hr/>
-      </div>
-    </div>
-    <div id="leftColumn">
-      <div id="navcolumn">
-             
-                    
-                                      <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
-        <img class="poweredBy" alt="Built by Maven" src="./images/logos/maven-feather.png" />
-      </a>
-                   
-                    
-            </div>
-    </div>
-    <div id="bodyColumn">
-      <div id="contentBox">
-        <div class="section">
-<h2>JIRA Report<a name="JIRA_Report"></a></h2><a name="JIRA_Report"></a>
-<table border="0" class="bodyTable">
-<tr class="a">
-<th>Type</th>
-<th>Key</th>
-<th>Status</th>
-<th>Summary</th></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5048">UIMA-5048</a></td>
-<td>Closed</td>
-<td>DUCC Orchestrator (OR) record Process Manager (PM) Job CommandLine requests</td></tr>
-<tr class="a">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5049">UIMA-5049</a></td>
-<td>Closed</td>
-<td>uima-ducc-demo adjustments</td></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5053">UIMA-5053</a></td>
-<td>Closed</td>
-<td>DUCC ducc_watcher optional admin script to determine status and send notifications</td></tr>
-<tr class="a">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5057">UIMA-5057</a></td>
-<td>Closed</td>
-<td>DUCC Orchestrator (OR) handle down JD node</td></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5059">UIMA-5059</a></td>
-<td>Resolved</td>
-<td>DUCC WS should compile jsps into $DUCC_HOME/tmp/ducc/jsp</td></tr>
-<tr class="a">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5060">UIMA-5060</a></td>
-<td>Closed</td>
-<td>DUCC Orchestrator (OR) &quot;warm&quot; restart issues</td></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5075">UIMA-5075</a></td>
-<td>Closed</td>
-<td>DUCC should check that it runs with the uid of the installer</td></tr>
-<tr class="a">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5080">UIMA-5080</a></td>
-<td>Closed</td>
-<td>DUCC uses UIMA-AS's dd2spring.xsl file which generates an obsolete dtd</td></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5084">UIMA-5084</a></td>
-<td>Closed</td>
-<td>DUCC Web Server (WS) does not reflect PM to Agent publication size on Daemons page</td></tr>
-<tr class="a">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5098">UIMA-5098</a></td>
-<td>Closed</td>
-<td>DUCC Agent does not handle /bin/cgcreate failure properly on re-start when there are left over processes</td></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5110">UIMA-5110</a></td>
-<td>Closed</td>
-<td>DUCC Job Driver (JD) erroneously logs ***** TIMEOUT *****</td></tr>
-<tr class="a">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5114">UIMA-5114</a></td>
-<td>Closed</td>
-<td>DUCC Web Server (WS) needs better user validation for login</td></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5124">UIMA-5124</a></td>
-<td>Closed</td>
-<td>DUCC-MON doesn't display the Reason for WaitingForResources for jobs</td></tr>
-<tr class="a">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5145">UIMA-5145</a></td>
-<td>Resolved</td>
-<td>DUCC attempts to run even if the DB doesn't start</td></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5152">UIMA-5152</a></td>
-<td>Closed</td>
-<td>DUCC may let a JP grab some WIs if pre-empted just as initilization completes</td></tr>
-<tr class="a">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5157">UIMA-5157</a></td>
-<td>Closed</td>
-<td>DUCC shutdown sequence leaves agents running</td></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5170">UIMA-5170</a></td>
-<td>Resolved</td>
-<td>When pages have &quot;no data&quot; indicate if because not logged in or data missing</td></tr>
-<tr class="a">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5188">UIMA-5188</a></td>
-<td>Closed</td>
-<td>UIMA-DUCC: the PM logs excessively</td></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5197">UIMA-5197</a></td>
-<td>Closed</td>
-<td>DUCC Web Server (WS) support startsWith function, when not present in browser's js</td></tr>
-<tr class="a">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5210">UIMA-5210</a></td>
-<td>Closed</td>
-<td>UIMA-Ducc: Rogue process detector broken for services</td></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5213">UIMA-5213</a></td>
-<td>Closed</td>
-<td>UIMA-DUCC: deprecate ducc.agent.node.metrics.sys.gid.max</td></tr>
-<tr class="a">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5232">UIMA-5232</a></td>
-<td>Closed</td>
-<td>DUCC missing DUCC Book documentation</td></tr>
-<tr class="b">
-<td>Bug</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5239">UIMA-5239</a></td>
-<td>Closed</td>
-<td>DUCC Web Server (WS) too verbose with logging disk info</td></tr>
-<tr class="a">
-<td>Documentation</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5158">UIMA-5158</a></td>
-<td>Closed</td>
-<td>DUCC Job Driver (JD) should provide individual work item performance breakdowns</td></tr>
-<tr class="b">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-4795">UIMA-4795</a></td>
-<td>Closed</td>
-<td>DUCC ducc.properties itself should comprise the DUCC Book documentation</td></tr>
-<tr class="a">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-4856">UIMA-4856</a></td>
-<td>Closed</td>
-<td>DUCC broker should be restricted to ducc use only</td></tr>
-<tr class="b">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5047">UIMA-5047</a></td>
-<td>Closed</td>
-<td>UIMA-DUCC: refactor agent code which gathers node and process metrics</td></tr>
-<tr class="a">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5086">UIMA-5086</a></td>
-<td>Resolved</td>
-<td>DUCC should consider slightly larger machines when reserving a whole machine</td></tr>
-<tr class="b">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5109">UIMA-5109</a></td>
-<td>Closed</td>
-<td>DUCC Web Server (WS) does not display Services deployments that have Completed</td></tr>
-<tr class="a">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5122">UIMA-5122</a></td>
-<td>Closed</td>
-<td>DUCC Database (db) admin tool for save &amp; restore</td></tr>
-<tr class="b">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5138">UIMA-5138</a></td>
-<td>Closed</td>
-<td>DUCC Database (db) improvements and exploitations</td></tr>
-<tr class="a">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5175">UIMA-5175</a></td>
-<td>Closed</td>
-<td>DUCC remove obsolete code and configuration data</td></tr>
-<tr class="b">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5181">UIMA-5181</a></td>
-<td>Closed</td>
-<td>DUCC Web Server (WS) Viz should display actual and schedulable sizes in concordance with Machines page</td></tr>
-<tr class="a">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5182">UIMA-5182</a></td>
-<td>Resolved</td>
-<td>ducc-mon should hide/show other large values when displaying Job, AP, or Service specifications</td></tr>
-<tr class="b">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5183">UIMA-5183</a></td>
-<td>Closed</td>
-<td>Support &quot;fenced-off&quot; worker nodes with read-only access to DUCC_HOME</td></tr>
-<tr class="a">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5186">UIMA-5186</a></td>
-<td>Closed</td>
-<td>DUCC Web Server (WS) should support other than jobs page as the default home</td></tr>
-<tr class="b">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5193">UIMA-5193</a></td>
-<td>Closed</td>
-<td>DUCC failover support (static)</td></tr>
-<tr class="a">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5196">UIMA-5196</a></td>
-<td>Closed</td>
-<td>DUCC Web Server (WS) file pager usability improvement</td></tr>
-<tr class="b">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5206">UIMA-5206</a></td>
-<td>Closed</td>
-<td>DUCC Web Server (WS) should provide restriction on responses comprising user data</td></tr>
-<tr class="a">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5212">UIMA-5212</a></td>
-<td>Closed</td>
-<td>DUCC Database (db) user &quot;guest&quot; with r/o access should employ private pw</td></tr>
-<tr class="b">
-<td>Improvement</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5215">UIMA-5215</a></td>
-<td>Closed</td>
-<td>DUCC: on process launch failure agent should set reason to content of stderr </td></tr>
-<tr class="a">
-<td>New Feature</td>
-<td><a class="externalLink" href="https://issues.apache.org/jira/browse/UIMA-5226">UIMA-5226</a></td>
-<td>Closed</td>
-<td>DUCC script to assist in gathering problem determination information</td></tr></table></div>
-      </div>
-    </div>
-    <div class="clear">
-      <hr/>
-    </div>
-    <div id="footer">
-      <div class="xright">
-              Copyright &#169;  All Rights Reserved.      
-                    
-                  </div>
-      <div class="clear">
-        <hr/>
-      </div>
-    </div>
-  </body>
-</html>
diff --git a/src/main/admin/ducc_util.py b/src/main/admin/ducc_util.py
index ca99c87..6eaf4b3 100644
--- a/src/main/admin/ducc_util.py
+++ b/src/main/admin/ducc_util.py
@@ -771,7 +771,7 @@
             procname = toks[2]
             fullargs = toks[3:]
 
-            if ( not ('java' in procname) ):
+            if ( not ('java' in procname) and not ('JIT' in procname)):
                 continue
 
             cont = False
diff --git a/src/main/admin/start_ducc b/src/main/admin/start_ducc
index 7384cf6..cb90164 100644
--- a/src/main/admin/start_ducc
+++ b/src/main/admin/start_ducc
@@ -222,8 +222,9 @@
 
     def invalid(self, *msg):
         if ( msg[0] != None ):
+            print
             print ' '.join(msg)
-
+            print
         print "For usage run"
         print "    start_ducc -h"
         print 'or'
@@ -246,12 +247,15 @@
         self.pids.load_if_exists(self.pid_file)
         
         try:
-            opts, args = getopt.getopt(argv, 'c:mn:sh?v', ['component=', 'components=', 'help', 'nodelist=', 'cold', 'warm', 'nothreading'])
+            opts, args = getopt.getopt(argv, 'c:mn:sh?v', ['component=', 'help', 'nodelist=', 'cold', 'warm', 'nothreading'])
         except:
             self.invalid('Invalid arguments', ' '.join(argv))
-                       
+
+        if (len(args) > 0):
+            self.invalid('Invalid extra args: ', ' '.join(args))
+                      
         for ( o, a ) in opts:
-            if o in ( '-c', '--components' ): 
+            if o in ( '-c', '--component' ): 
                 if (a.strip() == 'head'):
             		components.append('or')
             		components.append('pm')
@@ -276,7 +280,7 @@
             elif ( o == '-?'):
                 self.usage(None)
             else:
-                self.invalid('bad args: ', ' '.join(argv))
+                self.invalid('bad arg: ', o, 'in:', ' '.join(argv))
 
         if not self.installed():
             print "Head node is not initialized.  Have you run ducc_post_install?"
diff --git a/src/main/admin/stop_ducc b/src/main/admin/stop_ducc
index e377d97..b45d6e3 100644
--- a/src/main/admin/stop_ducc
+++ b/src/main/admin/stop_ducc
@@ -184,12 +184,15 @@
         wait_time = 60
 
         try:
-            opts, args = getopt.getopt(argv, 'ac:n:kn:w:qh?v', ['all', 'component=', 'components=', 'help', 'nodelist=', 'kill', 'quiesce', 'nothreading', 'wait'])
+            opts, args = getopt.getopt(argv, 'ac:n:kn:w:qh?v', ['all', 'component=', 'help', 'nodelist=', 'kill', 'quiesce', 'nothreading', 'wait'])
         except:
             self.invalid('Invalid arguments ' + ' '.join(argv))
+
+        if (len(args) > 0):
+            self.invalid('Invalid extra args: ', ' '.join(args))
         
         for ( o, a ) in opts:
-            if o in ('-c', '--component', '--components'):
+            if o in ('-c', '--component' ):
             	if (a.strip() == 'head'):
             		components.append('or')
             		components.append('pm')
@@ -223,8 +226,7 @@
             elif ( o == '-?'):
                self.usage(None)
             else:
-                print 'badarg', a
-                self.invalid('bad arg: ' + a)
+                self.invalid('bad arg: ' + o)
 
         if ( quiesce ):
             if ( all ):
diff --git a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/config/AgentConfiguration.java b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/config/AgentConfiguration.java
index ab303ec..f2e181b 100644
--- a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/config/AgentConfiguration.java
+++ b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/config/AgentConfiguration.java
@@ -23,13 +23,10 @@
 
 import javax.annotation.PostConstruct;
 
-import org.apache.activemq.camel.component.ActiveMQComponent;
 import org.apache.camel.CamelContext;
-import org.apache.camel.Component;
 import org.apache.camel.Exchange;
 import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
-import org.apache.camel.Route;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.dataformat.xstream.XStreamDataFormat;
 import org.apache.camel.impl.DefaultClassResolver;
@@ -495,8 +492,7 @@
   public ProcessMetricsProcessor processMetricsProcessor(NodeAgent agent, IDuccProcess process,
           ManagedProcess managedProcess) throws Exception {
     if (Utils.isLinux()) {
-      return new LinuxProcessMetricsProcessor(logger, process, agent, "/proc/" + process.getPID()
-              + "/statm", "/proc/stat", "/proc/" + process.getPID() + "/stat", managedProcess);
+      return new LinuxProcessMetricsProcessor(logger, process, agent, managedProcess);
     } else {
       return new DefaultProcessMetricsProcessor(process, agent);
     }
diff --git a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/DuccCommandExecutor.java b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/DuccCommandExecutor.java
index a1d8793..f7d49fe 100644
--- a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/DuccCommandExecutor.java
+++ b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/DuccCommandExecutor.java
@@ -309,7 +309,9 @@
 		return ( ((ManagedProcess) managedProcess).getDuccProcess().getProcessState()
 				.equals(ProcessState.Running) ||
 				((ManagedProcess) managedProcess).getDuccProcess().getProcessState()
-				.equals(ProcessState.Initializing)	
+				.equals(ProcessState.Initializing) ||
+				((ManagedProcess) managedProcess).getDuccProcess().getProcessState()
+				.equals(ProcessState.Starting)
 				); 	
 	}
 	private void stopProcess(ICommandLine cmdLine, String[] cmd)
diff --git a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/ManagedProcess.java b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/ManagedProcess.java
index fc384f5..42dcc2e 100644
--- a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/ManagedProcess.java
+++ b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/ManagedProcess.java
@@ -415,7 +415,7 @@
 			} else {
 				if ( !isAP && !isstopping ) {
 					// check if process exited while in Initializing state  
-					if ( ProcessState.Initializing.equals(pstate) ) {
+					if ( ProcessState.Initializing.equals(pstate) || ProcessState.Starting.equals(pstate)) {
 						getDuccProcess().setReasonForStoppingProcess(ReasonForStoppingProcess.FailedInitialization.toString());
 		                log("ManagedProcess.drainProcessStreams",
 				    "Process Failed while in initializing state - setting reason to "+getDuccProcess().getReasonForStoppingProcess());
diff --git a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/metrics/collectors/NodeLoadAverageCollector.java b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/metrics/collectors/NodeLoadAverageCollector.java
index 49e7e0f..695dbae 100644
--- a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/metrics/collectors/NodeLoadAverageCollector.java
+++ b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/metrics/collectors/NodeLoadAverageCollector.java
@@ -15,64 +15,54 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
-*/
+ */
 package org.apache.uima.ducc.agent.metrics.collectors;
 
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.io.RandomAccessFile;
 import java.util.concurrent.Callable;
 
 import org.apache.uima.ducc.common.node.metrics.NodeLoadAverage;
 import org.apache.uima.ducc.common.node.metrics.UptimeNodeLoadAverage;
 
+public class NodeLoadAverageCollector implements
+		Callable<NodeLoadAverage> {
 
-public class NodeLoadAverageCollector extends AbstractMetricCollector 
-implements Callable<NodeLoadAverage>{
-  
- public NodeLoadAverageCollector() {
-	super(null,0,0);
-	
- }
-  public NodeLoadAverageCollector(RandomAccessFile metricFile,  int howMany, int offset) {
-    super(metricFile, howMany, offset);
-  }
+	public NodeLoadAverageCollector() {
+	}
 
-  public NodeLoadAverage call() throws Exception {
-    //super.parseMetricFile();
-    
-//	 UptimeNodeLoadAverage uptimeLoadAverage = new UptimeNodeLoadAverage();
-	 return collect();
-	 //return new NodeLoadAverageInfo(super.metricFileContents, super.metricFieldOffsets, super.metricFieldLengths);
-  }
+	public NodeLoadAverage call() throws Exception {
+		return collect();
+	}
+
 	private NodeLoadAverage collect() throws Exception {
-		   InputStream stream = null;
-		   BufferedReader reader = null;
-		   UptimeNodeLoadAverage uptimeLoadAverage = new UptimeNodeLoadAverage(); 
-		   ProcessBuilder pb = 
-				   new ProcessBuilder("uptime");;
-	       pb.redirectErrorStream(true);
-		   Process proc = pb.start();
-		   //  spawn uptime command and scrape the output
-		   stream = proc.getInputStream();
-		   reader = new BufferedReader(new InputStreamReader(stream));
-		   String line;
-		   String regex = "\\s+";
-		   String filter = "load average:";
-		   // read the next line from ps output
-		   while ((line = reader.readLine()) != null) {
-//			   System.out.println("UPTIME:"+line);
-		       int pos=0;   
-			   if ( (pos = line.indexOf(filter)) > -1 ) {
-		          String la =  line.substring(pos+filter.length()).replaceAll(regex,"");
-				  String[] averages = la.split(",");
-				  uptimeLoadAverage.setLoadAvg1(averages[0]);
-				  uptimeLoadAverage.setLoadAvg5(averages[1]);
-				  uptimeLoadAverage.setLoadAvg15(averages[2]);
-			   }
-		   }
-		   proc.waitFor();
-		   return uptimeLoadAverage; 
+		InputStream stream = null;
+		BufferedReader reader = null;
+		UptimeNodeLoadAverage uptimeLoadAverage = new UptimeNodeLoadAverage();
+		ProcessBuilder pb = new ProcessBuilder("uptime");
+		;
+		pb.redirectErrorStream(true);
+		Process proc = pb.start();
+		// spawn uptime command and scrape the output
+		stream = proc.getInputStream();
+		reader = new BufferedReader(new InputStreamReader(stream));
+		String line;
+		String regex = "\\s+";
+		String filter = "load average:";
+		// read the next line from ps output
+		while ((line = reader.readLine()) != null) {
+			int pos = 0;
+			if ((pos = line.indexOf(filter)) > -1) {
+				String la = line.substring(pos + filter.length()).replaceAll(
+						regex, "");
+				String[] averages = la.split(",");
+				uptimeLoadAverage.setLoadAvg1(averages[0]);
+				uptimeLoadAverage.setLoadAvg5(averages[1]);
+				uptimeLoadAverage.setLoadAvg15(averages[2]);
+			}
 		}
+		proc.waitFor();
+		return uptimeLoadAverage;
+	}
 }
diff --git a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/DefaultNodeInventoryProcessor.java b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/DefaultNodeInventoryProcessor.java
index e79b07a..7ba3b0b 100644
--- a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/DefaultNodeInventoryProcessor.java
+++ b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/DefaultNodeInventoryProcessor.java
@@ -225,10 +225,9 @@
 							.append(" Resident Memory=")
 							.append(p.getValue().getResidentMemory())
 							.append(" Init Stats List Size:"
-									+ pipelineInitStats).
-							// append(" end init:"+endInit).
-							// append(" start run:"+startRun).
-							append("] ");
+									+ pipelineInitStats)
+							.append(" Reason: "+p.getValue().getReasonForStoppingProcess())		
+							.append("] ");
 					if (p.getValue().getProcessState()
 							.equals(ProcessState.Stopped)
 							|| p.getValue().getProcessState()
diff --git a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxNodeMetricsProcessor.java b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxNodeMetricsProcessor.java
index 5d9c817..3ff6eff 100644
--- a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxNodeMetricsProcessor.java
+++ b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxNodeMetricsProcessor.java
@@ -126,9 +126,7 @@
 
 			NodeMemInfoCollector memCollector = new NodeMemInfoCollector(MeminfoTargetFields);
 			Future<NodeMemory> nmiFuture = pool.submit(memCollector);
-//			NodeLoadAverageCollector loadAvgCollector = new NodeLoadAverageCollector(
-//					loadAvgFile, 5, 0);
-			// 
+
 			NodeLoadAverageCollector loadAvgCollector = new NodeLoadAverageCollector();
 
 			Future<NodeLoadAverage> loadFuture = pool.submit(loadAvgCollector);
diff --git a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxProcessMetricsProcessor.java b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxProcessMetricsProcessor.java
index 6b4bce7..66a698d 100644
--- a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxProcessMetricsProcessor.java
+++ b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxProcessMetricsProcessor.java
@@ -19,7 +19,6 @@
 package org.apache.uima.ducc.agent.processors;
 
 import java.io.FileNotFoundException;
-import java.io.RandomAccessFile;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
@@ -33,9 +32,7 @@
 import org.apache.uima.ducc.agent.metrics.collectors.ProcessResidentMemoryCollector;
 import org.apache.uima.ducc.agent.metrics.collectors.ProcessSwapUsageCollector;
 import org.apache.uima.ducc.common.agent.metrics.cpu.ProcessCpuUsage;
-import org.apache.uima.ducc.common.agent.metrics.memory.DuccProcessResidentMemory;
 import org.apache.uima.ducc.common.agent.metrics.memory.ProcessResidentMemory;
-import org.apache.uima.ducc.common.agent.metrics.swap.DuccProcessSwapSpaceUsage;
 import org.apache.uima.ducc.common.agent.metrics.swap.ProcessMemoryPageLoadUsage;
 import org.apache.uima.ducc.common.agent.metrics.swap.ProcessSwapSpaceUsage;
 import org.apache.uima.ducc.common.node.metrics.ProcessGarbageCollectionStats;
@@ -48,9 +45,6 @@
 
 public class LinuxProcessMetricsProcessor extends BaseProcessor implements
 		ProcessMetricsProcessor {
-	private RandomAccessFile statmFile;
-
-	private RandomAccessFile processStatFile;
 
 	private long previousCPUReadingInMillis = 0;
 	
@@ -79,12 +73,8 @@
 	
 	
 	public LinuxProcessMetricsProcessor(DuccLogger logger,
-			IDuccProcess process, NodeAgent agent, String statmFilePath,
-			String nodeStatFilePath, String processStatFilePath,
-			ManagedProcess managedProcess) throws FileNotFoundException {
+			IDuccProcess process, NodeAgent agent, ManagedProcess managedProcess) throws FileNotFoundException {
 		this.logger = logger;
-		statmFile = new RandomAccessFile(statmFilePath, "r");
-		processStatFile = new RandomAccessFile(processStatFilePath, "r");
 		this.managedProcess = managedProcess;
 		this.agent = agent;
 		pool = Executors.newCachedThreadPool();
@@ -123,12 +113,6 @@
 	public void close() {
 		closed = true;
 		try {
-			if (statmFile != null && statmFile.getFD().valid()) {
-				statmFile.close();
-			}
-			if (processStatFile != null && processStatFile.getFD().valid()) {
-				processStatFile.close();
-			}
 			this.stop();
 		} catch (Exception e) {
 			e.printStackTrace();
diff --git a/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/main/DuccService.java b/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/main/DuccService.java
index 84c0a8f..703d506 100644
--- a/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/main/DuccService.java
+++ b/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/main/DuccService.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -41,18 +41,18 @@
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
 /**
- * 
+ *
  * Main program to launch Ducc Component process. Launch configuration is provided
  * in properties file via -Dducc.deploy.configuration=<file.properties>. Entries
  * in this file are used to enrich System properties. Any value in the properties
- * file can be overriden with a -D<key>=<value> where <key> matches a key in 
+ * file can be overriden with a -D<key>=<value> where <key> matches a key in
  * properties file. To launch multiple Ducc components in the same jvm, list them
  * in ducc.deploy.components property. For example,
- * 
+ *
  *  ducc.deploy.components=jm,rm
- *  
+ *
  *  The above will launch Job Manager and Resource Manager in the same jvm.
- *  
+ *
  *
  */
 public class DuccService extends AbstractDuccComponent {
@@ -63,15 +63,15 @@
     private static DuccLogger globalLogger = null;
     private ApplicationContext context;
     Map<String,AbstractDuccComponent> duccComponents = null;
-    
+
     private Object investmentInstance;
-    
+
     private String[] args = null;
 	public DuccService() {
 		super("");
-        
-        //	Plugin UncaughtExceptionHandler to handle OOM and any 
-        //  unhandled runtime exceptions 
+
+        //	Plugin UncaughtExceptionHandler to handle OOM and any
+        //  unhandled runtime exceptions
         Thread.currentThread().setUncaughtExceptionHandler(this);
 	}
 
@@ -106,9 +106,9 @@
 
 	/**
 	 * Exits process if given configuration class is either null or not set (empty).
-	 *  
+	 *
 	 * @param classToVerify - class name to check
-	 * @param reason - 
+	 * @param reason -
 	 */
 	private void exitIfInvalid( String componentName, String classToVerify, String reason) {
 		if ( classToVerify == null || classToVerify.trim().length() == 0) {
@@ -118,9 +118,9 @@
 	}
 	/**
 	 * Extracts component configuration classes from System properties
-	 * 
+	 *
 	 * @return - array of configuration classes
-	 * 
+	 *
 	 * @throws DuccComponentInitializationException - if no components provided for loading
 	 */
 	private Class<?>[] getComponentsToLoad() throws Exception {
@@ -128,7 +128,7 @@
 		if ( componentsToLoad == null || componentsToLoad.length == 0 ) {
 			throw new DuccComponentInitializationException("Ducc Component not specified. Provide Ducc Component(s) to Load via -D"+DUCC_DEPLOY_COMPONENTS+" System property");
 		}
-		List<Class<?>> components = new ArrayList<Class<?>>(); 
+		List<Class<?>> components = new ArrayList<Class<?>>();
 		for( String componentToLoad : componentsToLoad ) {
 			String configurationClassName = System.getProperty("ducc."+componentToLoad+".configuration.class");
 			exitIfInvalid(componentToLoad, configurationClassName, "Configuration Class Name");
@@ -139,8 +139,8 @@
 		return configClasses;
 	}
 	/**
-	 * Initializes Ducc component(s) based on provided configuration.  
-	 * 
+	 * Initializes Ducc component(s) based on provided configuration.
+	 *
 	 * @throws Exception
 	 */
 	public void boot(String[] args) throws Exception {
@@ -150,16 +150,16 @@
         // enable hangup support so you can press ctrl + c to terminate the JVM
         main.enableHangupSupport();
         //	Load ducc properties file and enrich System properties. It supports
-        //  overrides for entries in ducc properties file. Any key in the ducc 
+        //  overrides for entries in ducc properties file. Any key in the ducc
         //	property file can be overriden with -D<key>=<value>
 		loadProperties(DUCC_PROPERTY_FILE);
 
 		System.out.println(System.getProperties());
-		//	Extract component configuration classes available in System properties 
+		//	Extract component configuration classes available in System properties
 		Class<?>[] configClasses = getComponentsToLoad();
 		//	Configure via Spring DI using named Spring's Java Config magic.
-		//	Multiple component configurations can be loaded into a Spring container. 
-		context = 
+		//	Multiple component configurations can be loaded into a Spring container.
+		context =
 			new AnnotationConfigApplicationContext(configClasses);
 		//	Extract all Ducc components from Spring container
 		duccComponents =
@@ -186,7 +186,7 @@
   }
 	public AbstractDuccComponent getComponentInstance(String componentKey) {
     //  Extract all Ducc components from Spring container
-    Map<String,AbstractDuccComponent> duccComponents = 
+    Map<String,AbstractDuccComponent> duccComponents =
       context.getBeansOfType(AbstractDuccComponent.class);
     for(Map.Entry<String, AbstractDuccComponent> duccComponent: duccComponents.entrySet()) {
       if ( componentKey.equals(duccComponent.getKey())) {
@@ -198,12 +198,12 @@
 	/**
 	 * This method returns an instance of IJobProcessor which would only exist
 	 * in a JP and UIMA-based AP.
-	 * 
+	 *
 	 * @return - IJobProcessor instance
 	 */
 	public IJobProcessor getJobProcessorComponent() {
 	    //  Extract all Ducc components from Spring container
-	    Map<String,AbstractDuccComponent> duccComponents = 
+	    Map<String,AbstractDuccComponent> duccComponents =
 	      context.getBeansOfType(AbstractDuccComponent.class);
 	    // scan for component which implements IJobProcessor interface.
 	    for(Map.Entry<String, AbstractDuccComponent> duccComponent: duccComponents.entrySet()) {
@@ -220,7 +220,7 @@
 	 */
 	public AbstractDuccComponent getComponentByInstanceType(Class<?> instanceType) {
 	    //  Extract all Ducc components from Spring container
-	    Map<String,AbstractDuccComponent> duccComponents = 
+	    Map<String,AbstractDuccComponent> duccComponents =
 	      context.getBeansOfType(AbstractDuccComponent.class);
 	    for(Map.Entry<String, AbstractDuccComponent> duccComponent: duccComponents.entrySet()) {
 	        return duccComponent.getValue();
@@ -255,7 +255,7 @@
 			duccComponent.start(this, args);
 			//getDuccLogger().info("setProcessor", null, "... Component started: job-process");
 		}
-		
+
 	}
 	public void stop() throws Exception {
 		if ( main.isStarted() ) {
@@ -267,29 +267,27 @@
 			getDuccLogger().shutdown();
 		}
 	}
-	
+
 	public static void main(String[] args) {
 		DuccService duccService = null;
 		try {
-			// run duplicate daemon detector to make sure we dont start
-			// multiple copies of Ducc daemons. It checks of this process
-			// is a duplicate of OR, WS, PM, RM, SM, or Agent. The code
-			// simply exits if another instance is running.
-			DuplicateDuccDaemonProcessDetector daemonDetector =
-					new DuplicateDuccDaemonProcessDetector();
-			String thisProcessDaemonType = System.getProperty(DUCC_DEPLOY_COMPONENTS);
-			if ( daemonDetector.isThisProcessDuplicateDaemon(thisProcessDaemonType) ) {
-				System.out.println("Ducc Daemon process "+thisProcessDaemonType+" is already running - duplicates are not allowed - exiting ...");
-				System.exit(1);
-			}
-
-			
 			if ( Utils.findDuccHome() == null ) {
                 //findDuccHome places it into System.properties
 				System.out.println("Unable to Launch Ducc Service - DUCC_HOME not defined. Add it to your environment or provide it with -DDUCC_HOME=<path>");
 				System.exit(-1);
 			}
 
+			// Run duplicate daemon detector to make sure we dont start
+            // multiple copies of Ducc daemons. It checks of this process
+            // is a duplicate of OR, WS, PM, RM, SM, or Agent. The code
+            // simply exits if another instance is running.
+			// (Must first find DUCC_HOME so can read ducc.propeties)
+            String dup = DuplicateDuccDaemonProcessDetector.checkForDuplicate();
+            if (dup != null) {
+                System.out.println("ERROR - DUCC Daemon process already running - " + dup);
+                System.exit(1);
+            }
+
             if ( System.getenv(IDuccUser.EnvironmentVariable.DUCC_IP.value()) == null ) {
                 NodeIdentity ni = new NodeIdentity();
                 System.setProperty(IDuccUser.EnvironmentVariable.DUCC_IP.value(), ni.getIp());
@@ -302,7 +300,7 @@
 
 			duccService = new DuccService();
 			duccService.boot(args);
-			
+
 		} catch( DuccComponentInitializationException e) {
 			e.printStackTrace();
 			if ( duccService != null ) {
@@ -314,7 +312,7 @@
 			}
 		} catch( Exception e) {
 			e.printStackTrace();
-			
+
 		}
 	}
 
@@ -329,7 +327,7 @@
             }
         }
     }
-    
+
 	public String getLogLevel(String clz) {
 		@SuppressWarnings("unchecked")
 		Enumeration<Logger> loggers = LogManager.getCurrentLoggers();
@@ -352,7 +350,7 @@
 		this.investmentInstance = instance;
 	}
 	public void registerInvestmentResetCallback(Object o, Method m) throws Exception {
-		Method investmentInstanceMethod = 
+		Method investmentInstanceMethod =
 				investmentInstance.getClass().getDeclaredMethod("setJobComponent", Object.class, Method.class);
 		investmentInstanceMethod.invoke(investmentInstance, o,m);
 	}
diff --git a/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/node/DuplicateDuccDaemonProcessDetector.java b/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/node/DuplicateDuccDaemonProcessDetector.java
index 1eba8de..5ef9447 100644
--- a/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/node/DuplicateDuccDaemonProcessDetector.java
+++ b/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/node/DuplicateDuccDaemonProcessDetector.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -19,241 +19,86 @@
 package org.apache.uima.ducc.common.node;
 
 import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
 
+import org.apache.uima.ducc.common.utils.DuccPropertiesResolver;
 import org.apache.uima.ducc.common.utils.Utils;
 
 public class DuplicateDuccDaemonProcessDetector {
-	private static String thisProcessPID = Utils.getPID();
-	private static String ducc_user = System.getProperty("user.name");
-	private static final String brokerProcessId = "-Dactivemq.base";
-	private static final String duccDaemonId = "-Dducc.deploy.components";
-	private static final String[] processCollectorCommandLine = 
-			new String[] {"ps","-Ao","user:12,pid,ppid,uid,args", "--no-heading"};
 
-	
-	public enum DuccDaemonType {
-		
-		AGENT("agent"),OR("orchestrator"),
-		RM("rm"),SM("sm"),BROKER("broker"),
-		WS("ws"), PM("pm"),NotDuccDaemon("");
-		private final String daemonType;
+    static public String checkForDuplicate() {
+        String deployFlag = "ducc.deploy.components";
+        String virtualFlag = "ducc.agent.virtual";
+        String javaCmd = DuccPropertiesResolver.getInstance().getProperty("ducc.jvm");
+        if (javaCmd == null) {
+            return "ERROR - this is not a DUCC launched process (ducc.jvm missing)";
+        }
 
-		private DuccDaemonType(String type) {
-			daemonType = type;
-		}
-		
-		public String getName() {
-			return daemonType;
-		}
-	}
-	public static void main(String[] args) {
+        String myType = System.getProperty(deployFlag);
+        if (myType == null || myType.equals("jd") || myType.equals("jp")) {
+            return null;
+        }
+        String myPid = Utils.getPID();
+        String userid = System.getProperty("user.name");
+        boolean isAgent = myType.equals("agent");
+        String myVirtualIp = System.getProperty(virtualFlag);
 
-		DuplicateDuccDaemonProcessDetector processCollector =
-				new DuplicateDuccDaemonProcessDetector();
-		String thisProcessDaemonType = System.getProperty(duccDaemonId.substring(2)); // skip -D
-		processCollector.isThisProcessDuplicateDaemon(thisProcessDaemonType);  
-	}
-	/**
-	 * Checks if this process is another instance of PM, OR, SM, RM, WS, or Agent.
-	 * The JD, JP, and Services are excluded from the check although the bootstrapping
-	 * code is the same as the real daemons. 
-	 * 
-	 * @param daemonName
-	 * @return
-	 */
-	public boolean isThisProcessDuplicateDaemon(String daemonName ) {
-		// Convert this daemon type ("or", "sm", etc) to enumeration type.
-		// Returns NotDuccDaemon if this process is not a true ducc daemon,
-		// WS, RM, PM, SM, OR, or Agent.
-		DuccDaemonType thisDuccDaemonType = getDaemonTypeForName(daemonName);
-		// If cant convert to enumeration type, this process is not a ducc daemon
-		if ( !thisDuccDaemonType.equals(DuccDaemonType.NotDuccDaemon)) {
-			return isThisProcessDuplicateDaemon(thisDuccDaemonType);
-		}
-		return false;
-	}
-	/**
-	 * Launches ps command and scrapes a list of processes currently running on a node
-	 * to detect if this process is a duplicate of already running Ducc daemon.
-	 * 
-	 * @param thisDuccDaemonType - this process daemon type (OR, WS, PM, etc)
-	 * 
-	 * @return true if this process is a duplicate of a running ducc daemon, otherwise false.
-	 */
-	public boolean isThisProcessDuplicateDaemon(DuccDaemonType thisDuccDaemonType) {
-		try {
-			// launch 'ps' command and return a list of running processes on this node
-			List<RunningProcess> allProcesses = 
-					getAllProcessesRunningOnNodeNow();
-			
-			for( RunningProcess process : allProcesses ) {
-				// exclude this process from the check
-				if ( thisProcessPID.equals(process.getPid()) ) {
-					continue; // skip this process
-				}
-				// only care about current user processes
-				if (ducc_user.equals(process.getUserName()) ) {
-					// extract process type ("ws", "or",etc. Returns NotDuccDaemon otherwise.
-					// It checks the value of -Dducc.deploy.components property to determine
-					// if it is a daemon process.
-					DuccDaemonType runningDuccDaemonType = 
-							duccDaemonType(process.getCommandline());
-					// Only care about Ducc daemon processes
-					if (DuccDaemonType.NotDuccDaemon.equals(runningDuccDaemonType)) {
-						continue; // skip
-					} else if ( thisDuccDaemonType.equals(runningDuccDaemonType) ) {
-						/****** FOUND DUPLICATE DUCC DAEMON ******/
-						System.out.println("The Ducc daemon:"+runningDuccDaemonType.getName()+" is already runninig - duplicates are not allowed");
-						return true;
-					} else {
-					//	System.out.println("Process PID:"+process.getPid()+" Ducc Daemon:"+runningDuccDaemonType.getName());
-					}
-				}
-			}
-		} catch( Exception e) {
-			e.printStackTrace();
-		}
-		return false;
-	}
-	
-	public List<RunningProcess> getAllProcessesRunningOnNodeNow() throws RuntimeException {
-		BufferedReader reader = null;
-		List<RunningProcess> nodeProcessList = new ArrayList<RunningProcess>();
-		try {
-			InputStream inputStream = launchProcessCollector(processCollectorCommandLine);
-		    reader = new BufferedReader(new InputStreamReader(inputStream));
-		    String line;
-		    String regex = "\\s+";
-		    
-	        // read the next line from ps output
-		    while ((line = reader.readLine()) != null) {
-		      String tokens[] = line.split(regex);
-		      if ( tokens.length > 0 ) {
-		    	 // copy the whole command line starting at index 4 
-		    	 String[] commandLine = Arrays.copyOfRange(tokens, 4, tokens.length);
-		    	  
-		       	 RunningProcess p = 
-		                      new RunningProcess().
-		                      withUserName(tokens[0]).
-		                      withPid(tokens[1]).
-		                      withParentPid(tokens[2]).
-		                      withUserId(tokens[3]).
-		                      withCommandline(commandLine);
-		       	 
-		            // add process to a list which is used to look up each process parent
-		         nodeProcessList.add(p);
-		      }
-		    }
-		} catch( Exception e) {
-			e.printStackTrace();
-		} finally {
-			try {
-				reader.close();
-			} catch( IOException ioe) {
-			}
-		}
-		return nodeProcessList;
-	}
-	
-	private InputStream launchProcessCollector(String[] processCommandLine) throws Exception {
-		InputStream inputStream = null;
-	
-        ProcessBuilder pb = new ProcessBuilder(processCommandLine);
-	    pb.redirectErrorStream(true);
-	    Process proc = pb.start();
-	    //  spawn ps command and scrape the output
-	    inputStream = proc.getInputStream();
-        return inputStream;
-	}
-	private DuccDaemonType getDaemonTypeForName(String aName) {
-    	for( DuccDaemonType dt : DuccDaemonType.values() ) {
-    		if ( dt.getName().equals(aName)) {
-    			return dt;
-    		}
-    	}
-    	return DuccDaemonType.NotDuccDaemon;
-	}
-	  private DuccDaemonType duccDaemonType(String[] tokens) {
-		  DuccDaemonType daemonType = DuccDaemonType.NotDuccDaemon;
-		  
-		  for( String token : tokens ) {
-		      if ( token.startsWith(duccDaemonId)) {
-		        int pos = token.indexOf("=");
-		        if ( pos > -1 ) {
-		        	String daemon = token.substring(pos+1);
-		        	for( DuccDaemonType dt : DuccDaemonType.values() ) {
-		        		if ( dt.getName().equals(daemon)) {
-		        			return dt;
-		        		}
-		        	}
-		        }
-		      } else if (token.startsWith(brokerProcessId)) {
-		    	  daemonType = DuccDaemonType.BROKER;
-		    	  break;
-		      }
-		    }
-		    return daemonType;
-		  }
+        String[] cmdLine = new String[]{"ps", "--user", userid, "-o", "pid,args", "--no-heading"};
+        ProcessBuilder pb = new ProcessBuilder(cmdLine);
+        pb.redirectErrorStream(true);
 
-	  private class RunningProcess {
-		  String pid;
-		  String userName;
-		  String userId;
-		  String parentPid;
-		  String[] commandline;
-		  
-		  
-		public String getPid() {
-			return pid;
-		}
+        try {
+            Process proc = pb.start();
+            BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+            String line;
+            String dupProcess = null;
+            // "pid cmd args ...."
+            while ((line = reader.readLine()) != null) {
+                String[] toks = line.trim().split("\\s+");
+                // Ignore this process and any non-java ones and all others once a duplicate exists
+                if (toks.length < 2 || toks[0].equals(myPid) || !toks[1].equals(javaCmd) || dupProcess != null) {
+                    continue;
+                }
+                String virtualIp = null;
+                for (String tok : toks) {
+                    String[] parts = tok.split("=", 2);
+                    if (parts.length == 2) {
+                        if (parts[0].equals("-D" + deployFlag)) {
+                            if (myType.equals(parts[1])) {
+                                dupProcess = line;
+                            }
+                        } else if (isAgent) {
+                            if (parts[0].equals("-D" + virtualFlag)) {
+                                virtualIp = parts[1];
+                            }
+                        }
+                    }
+                }
+                // Ignore duplicate agents with different IPs, unless one is not virtual.
+                if (dupProcess != null && isAgent) {
+                    if (myVirtualIp != null && virtualIp != null && !virtualIp.equals(myVirtualIp)) {
+                        dupProcess = null;
+                    }
+                }
+            }
+            proc.waitFor();
+            reader.close();
+            return dupProcess;
 
-		protected RunningProcess withPid(String pid) {
-			this.pid = pid;
-			return this;
-		}
+        } catch (Exception e) {
+            return "Exception: " + e;
+        }
+    }
 
-		public String getUserName() {
-			return userName;
-		}
-
-		protected RunningProcess withUserName(String userName) {
-			this.userName = userName;
-			return this;
-		}
-
-		@SuppressWarnings("unused")
-		public String getUserId() {
-			return userId;
-		}
-
-		protected RunningProcess withUserId(String userId) {
-			this.userId = userId;
-			return this;
-		}
-
-		@SuppressWarnings("unused")
-		public String getParentPid() {
-			return parentPid;
-		}
-
-		protected RunningProcess withParentPid(String parentPid) {
-			this.parentPid = parentPid;
-			return this;
-		}
-
-		public String[] getCommandline() {
-			return commandline;
-		}
-
-		protected RunningProcess withCommandline(String[] commandline) {
-			this.commandline = commandline;
-			return this;
-		}
-	  }
+    public static void main(String[] args) {
+        if ( Utils.findDuccHome() == null ) {
+            System.out.println("ERROR - failed to find DUCC_HOME");
+        }
+        String dup = checkForDuplicate();
+        if (dup == null) {
+            System.out.println("Duplicate daeomon NOT found");
+        } else {
+            System.out.println("Duplicate daemon found: " + dup);
+        }
+    }
 }
diff --git a/uima-ducc-examples/src/main/java/org/apache/uima/ducc/test/randomsleep/FixedSleepAE.java b/uima-ducc-examples/src/main/java/org/apache/uima/ducc/test/randomsleep/FixedSleepAE.java
index 4e40c0e..de1468d 100644
--- a/uima-ducc-examples/src/main/java/org/apache/uima/ducc/test/randomsleep/FixedSleepAE.java
+++ b/uima-ducc-examples/src/main/java/org/apache/uima/ducc/test/randomsleep/FixedSleepAE.java
@@ -106,13 +106,18 @@
         int i_exit   = getIntFromEnv("AE_INIT_EXIT" , false);
         int i_itime  = getIntFromEnv("AE_INIT_TIME" , true );
         int i_irange = getIntFromEnv("AE_INIT_RANGE", true );
-
-        if ( i_error > 0 ) {
-            int toss = nextrand(100);
-            if ( logger != null )
-               logger.log(Level.INFO, "Init errors: probability[" + i_error + "] toss[" + toss + "]");
-            if ( i_error > toss ) {
-                throwAnException("Random Error in Initialization");
+        int i_fail_init_now = getIntFromEnv("AE_FAIL_INIT",false);
+        
+        if ( i_fail_init_now > 0 ) {
+            throwAnException("Simulated Error in Initialization");
+        } else {
+            if ( i_error > 0 ) {
+                int toss = nextrand(100);
+                if ( logger != null )
+                   logger.log(Level.INFO, "Init errors: probability[" + i_error + "] toss[" + toss + "]");
+                if ( i_error > toss ) {
+                    throwAnException("Random Error in Initialization");
+                }
             }
         }
 
diff --git a/uima-ducc-examples/src/main/scripts/start_sim b/uima-ducc-examples/src/main/scripts/start_sim
index 8ce34a2..c9d4988 100755
--- a/uima-ducc-examples/src/main/scripts/start_sim
+++ b/uima-ducc-examples/src/main/scripts/start_sim
@@ -92,7 +92,8 @@
             CMDPARMS.append('-XX:HeapDumpPath='+ducc_heap_dump_path)
             
         CMDPARMS.append('-Dducc.agent.node.metrics.fake.memory.size=' + str(memory))
-        CMDPARMS.append('-Dducc.agent.virtual')
+        # Put virtual IP on command line for duplicate daemon detector
+        CMDPARMS.append('-Dducc.agent.virtual=' + ip)
         CMDPARMS.append('org.apache.uima.ducc.common.main.DuccService')
         
         print "Start agent with pnode", pnode, "IP", ip, "memory", memory
diff --git a/uima-ducc-orchestrator/src/main/java/org/apache/uima/ducc/orchestrator/ProcessAccounting.java b/uima-ducc-orchestrator/src/main/java/org/apache/uima/ducc/orchestrator/ProcessAccounting.java
index 4655965..e9fab74 100644
--- a/uima-ducc-orchestrator/src/main/java/org/apache/uima/ducc/orchestrator/ProcessAccounting.java
+++ b/uima-ducc-orchestrator/src/main/java/org/apache/uima/ducc/orchestrator/ProcessAccounting.java
@@ -484,6 +484,24 @@
 		logger.trace(methodName, job.getDuccId(), messages.fetch("exit"));
 	}
 	
+	private boolean changed(String s1, String s2) {
+		boolean retVal = false;
+		if((s1 == null) && (s2 == null)) {
+		}
+		else if((s1 == null) && (s2 != null)) {
+			retVal = true;
+		}
+		else if((s1 != null) && (s2 == null)) {
+			retVal = true;
+		}
+		else if(s1.equals(s2)) {
+		}
+		else {
+			retVal = true;
+		}
+		return retVal;
+	}
+	
 	private void copyReasonForStoppingProcess(IDuccWorkJob job, IDuccProcess inventoryProcess, IDuccProcess process) {
 		String methodName = "copyReasonForStoppingProcess";
 		logger.trace(methodName, job.getDuccId(), messages.fetch("enter"));
@@ -496,26 +514,16 @@
 		case Killed:
 			String reasonNew = inventoryProcess.getReasonForStoppingProcess();
 			String reasonOld = process.getReasonForStoppingProcess();
-			String extendedReasonNew = inventoryProcess.getExtendedReasonForStoppingProcess();
-			if(reasonNew != null) {
-				if(reasonOld == null) {
-					process.setReasonForStoppingProcess(reasonNew);
-					logger.info(methodName, job.getDuccId(), process.getDuccId(), messages.fetchLabel("process reason code")+process.getReasonForStoppingProcess());
-					if(extendedReasonNew != null) {
-						process.setExtendedReasonForStoppingProcess(extendedReasonNew);
-						logger.info(methodName, job.getDuccId(), process.getDuccId(), messages.fetchLabel("process extended reason code")+process.getExtendedReasonForStoppingProcess());
-					}
-				}
-				else if(!reasonNew.equals(reasonOld)) {
-					process.setReasonForStoppingProcess(reasonNew);
-					logger.info(methodName, job.getDuccId(), process.getDuccId(), messages.fetchLabel("process reason code")+process.getReasonForStoppingProcess());
-					if(extendedReasonNew != null) {
-						process.setExtendedReasonForStoppingProcess(extendedReasonNew);
-						logger.info(methodName, job.getDuccId(), process.getDuccId(), messages.fetchLabel("process extended reason code")+process.getExtendedReasonForStoppingProcess());
-					}
-				}
+			if(changed(reasonOld, reasonNew)) {
+				process.setReasonForStoppingProcess(reasonNew);
+				logger.info(methodName, job.getDuccId(), process.getDuccId(), messages.fetchLabel("process reason code")+reasonOld+"->"+reasonNew);
 			}
-			
+			String extendedReasonNew = inventoryProcess.getExtendedReasonForStoppingProcess();
+			String extendedReasonOld = process.getExtendedReasonForStoppingProcess();
+			if(changed(extendedReasonOld, extendedReasonNew)) {
+				process.setExtendedReasonForStoppingProcess(extendedReasonNew);
+				logger.info(methodName, job.getDuccId(), process.getDuccId(), messages.fetchLabel("process extended reason code")+extendedReasonOld+"->"+extendedReasonNew);
+			}
 			break;
 		default:
 			break;
diff --git a/uima-ducc-parent/pom.xml b/uima-ducc-parent/pom.xml
index f51ea5c..03f00d3 100644
--- a/uima-ducc-parent/pom.xml
+++ b/uima-ducc-parent/pom.xml
@@ -159,7 +159,7 @@
 		<google.gson.version>2.2.2</google.gson.version>
 		<cglib.version>2.2.0</cglib.version>
 		<libpam.version>1.7</libpam.version>
-		<jna.version>4.2.2</jna.version>
+		<jna.version>4.0.0</jna.version>
 		<datatables.version>1.9.1</datatables.version>
 		<jetty.version>9.2.13.v20150730</jetty.version>
 		<orbit-org-apache-jasper.version>2.1.0.v201110031002</orbit-org-apache-jasper.version>
diff --git a/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java b/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java
index 26ce85f..93080bc 100644
--- a/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java
+++ b/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java
@@ -1310,6 +1310,7 @@
         }
         // keep services with autostart=true or with active references 
         // running with at least one instance on a rebalance
+        // UIMA-4995 May happen when pinger says both delete 1 and add 1
         if ((this.isAutostart() || (this.countReferences() > 0) ) && instances == 0) {
           instances = 1;
         }
@@ -1451,7 +1452,7 @@
                 //
                 // TODO: Update the ducc_services CLI to allow stop and restart of specific instances without counting failure.
                 if ( stoppedInstance.isStopped() ) {
-                    logger.info(methodName, id, "Instance", inst_id, "is manually stopped.  Not restarting.");
+                    logger.info(methodName, id, "Instance", inst_id, "stopped by SM.  Not restarting.");
                 } else {
                     // An instance stopped and we (SM) didn't ask it to - by definition this is failure no matter how it exits.
                     
@@ -2224,7 +2225,6 @@
 
     synchronized void stopAll()
     {
-        instances = 0;     // Reduce the target count to 0 to ensure no more are started UIMA-5244
         stop(implementors.size());
     }
 
@@ -2235,6 +2235,7 @@
     {
         disable(reason);
         stopAll();
+        // instances = 0;     // Is this needed to ensure no more are started? UIMA-5244
     }
 
     // /**
@@ -2265,7 +2266,7 @@
         public void run()
         {
             String methodName = "LingerTask.run";
-            logger.debug(methodName, id, "Lingering stop completes.");
+            logger.info(methodName, id, "Linger time reached ... stopping all instances.");
             // doesn't matter how its started i think, we have to set this flag off when we stop
             linger = null;
             setReferenced(false);
diff --git a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/configuration/jp/JobProcessComponent.java b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/configuration/jp/JobProcessComponent.java
index 51bb831..03ef44d 100644
--- a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/configuration/jp/JobProcessComponent.java
+++ b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/configuration/jp/JobProcessComponent.java
@@ -99,9 +99,17 @@
 			if ( message == null ) {

 				message = super.getProcessJmxUrl();

 			}

+			

 			if ( !state.name().equals(currentState.name())) {

-				currentState = state;

-				logger.info("setState", null, "Notifying Agent New State:"+state.name());

+				if ( state.equals(ProcessState.Stopping) && 

+						(currentState.equals(ProcessState.Initializing ) ||

+						 currentState.equals(ProcessState.Undefined ) ||

+						 currentState.equals(ProcessState.Starting ) ) ) {

+					currentState = ProcessState.FailedInitialization;

+				} else {

+					currentState = state;

+				}

+				logger.info("setState", null, "Notifying Agent New State::::"+currentState.name());

 				if ( agent != null ) {

 					agent.notify(currentState, message);

 				}

diff --git a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcess.java b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcess.java
index 6004c4e..98511ee 100644
--- a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcess.java
+++ b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcess.java
@@ -34,6 +34,19 @@
 
 public class DuccProcess implements IDuccProcess {
 
+	public enum SpecialValue { 
+		Unknown(-100),
+		Unavailable(-1),
+		;
+		long sv = 0;
+		private SpecialValue(long value) {
+			sv = value;
+		}
+		long getlong() {
+			return sv;
+		}
+	}
+	
 	/**
 	 * please increment this sUID when removing or modifying a field
 	 */
@@ -62,9 +75,9 @@
 	private boolean initialized = false;
 	private int exitCode;
 	private CGroup cgroup;
-	private long majorFaults;
-	private long swapUsage;
-	private long swapUsageMax;
+	private long majorFaults = SpecialValue.Unknown.getlong();
+	private long swapUsage= SpecialValue.Unknown.getlong();
+	private long swapUsageMax= SpecialValue.Unknown.getlong();
 	private long wiMillisInvestment;
 	private long currentCPU;
 	
diff --git a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcessConcurrentMap.java b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcessConcurrentMap.java
index 3a0b11f..3fb5050 100644
--- a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcessConcurrentMap.java
+++ b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcessConcurrentMap.java
@@ -28,6 +28,7 @@
 import org.apache.uima.ducc.common.utils.DuccLogger;
 import org.apache.uima.ducc.common.utils.id.DuccId;
 import org.apache.uima.ducc.transport.Constants;
+import org.apache.uima.ducc.transport.event.common.DuccProcess.SpecialValue;
 import org.apache.uima.ducc.transport.event.common.IProcessState.ProcessState;
 
 public class DuccProcessConcurrentMap extends ConcurrentHashMap<DuccId,IDuccProcess> implements IDuccProcessMap {
@@ -335,39 +336,136 @@
 		return list.size();
 	}
 	
+	/*
+	 * return actual count if all non-negative (all have cgroups)
+	 * return -1 if all -1 (none have cgroups)
+	 * return -2 if mixed (some do and some don't have cgroups) but retVal would have been == 0
+	 * return -3 if mixed (some do and some don't have cgroups) but retVal would have been > 0
+	 */
 	public long getPgInCount() {
 		long retVal = 0;
+		boolean flagCgroup = false;
+		boolean flagNoCgroup = false;
 		synchronized(this) {
 			Iterator<IDuccProcess> iterator = this.values().iterator();
 			while(iterator.hasNext()) {
 				IDuccProcess process = iterator.next();
-				retVal += process.getMajorFaults();
+				long value = process.getMajorFaults();
+				if(value == SpecialValue.Unknown.getlong()) {
+					// skip it
+				}
+				else {
+					if(value < 0) {
+						flagNoCgroup = true;
+					}
+					else {
+						flagCgroup = true;
+						retVal += value;
+					}
+				}
 			}
 		}
+		if(flagCgroup && flagNoCgroup) {
+			if(retVal > 0){
+				retVal = -3;
+			}
+			else {
+				retVal = -2;
+			}
+		}
+		else if(flagNoCgroup) {
+			retVal = -1;
+		}
 		return retVal;
 	}
 	
+	/*
+	 * return actual count if all non-negative (all have cgroups)
+	 * return -1 if all -1 (none have cgroups)
+	 * return -2 if mixed (some do and some don't have cgroups) but retVal would have been == 0
+	 * return -3 if mixed (some do and some don't have cgroups) but retVal would have been > 0
+	 */
 	public double getSwapUsageGb() {
 		double retVal = 0;
+		boolean flagCgroup = false;
+		boolean flagNoCgroup = false;
 		synchronized(this) {
 			Iterator<IDuccProcess> iterator = this.values().iterator();
 			while(iterator.hasNext()) {
 				IDuccProcess process = iterator.next();
-				double swap = process.getSwapUsage();
-				retVal += swap/Constants.GB;
+				double value = process.getSwapUsage();
+				if(value == SpecialValue.Unknown.getlong()) {
+					// skip it
+				}
+				else {
+					if(value < 0) {
+						flagNoCgroup = true;
+					}
+					else {
+						flagCgroup = true;
+						retVal += value/Constants.GB;
+					}
+				}
 			}
 		}
+		if(flagCgroup && flagNoCgroup) {
+			if(retVal > 0){
+				retVal = -3;
+			}
+			else {
+				retVal = -2;
+			}
+		}
+		else if(flagNoCgroup) {
+			retVal = -1;
+		}
 		return retVal;
 	}
 	
+	/*
+	 * return actual count if all non-negative (all have cgroups)
+	 * return -1 if all -1 (none have cgroups)
+	 * return -2 if mixed (some do and some don't have cgroups) but retVal would have been == 0
+	 * return -3 if mixed (some do and some don't have cgroups) but retVal would have been > 0
+	 */
 	public double getSwapUsageGbMax() {
 		double retVal = 0;
-		synchronized(this) {
-			Iterator<IDuccProcess> iterator = this.values().iterator();
-			while(iterator.hasNext()) {
-				IDuccProcess process = iterator.next();
-				double swap = process.getSwapUsageMax();
-				retVal += swap/Constants.GB;
+		double swap = getSwapUsageGb();
+		if(swap < 0) {
+			retVal = swap;
+		}
+		else {
+			boolean flagCgroup = false;
+			boolean flagNoCgroup = false;
+			synchronized(this) {
+				Iterator<IDuccProcess> iterator = this.values().iterator();
+				while(iterator.hasNext()) {
+					IDuccProcess process = iterator.next();
+					double value = process.getSwapUsageMax();
+					if(value == SpecialValue.Unknown.getlong()) {
+						// skip it
+					}
+					else {
+						if(value < 0) {
+							flagNoCgroup = true;
+						}
+						else {
+							flagCgroup = true;
+							retVal += value/Constants.GB;
+						}
+					}
+				}
+			}
+			if(flagCgroup && flagNoCgroup) {
+				if(retVal > 0){
+					retVal = -3;
+				}
+				else {
+					retVal = -2;
+				}
+			}
+			else if(flagNoCgroup) {
+				retVal = -1;
 			}
 		}
 		return retVal;
diff --git a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcessMap.java b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcessMap.java
index cacc2b3..c1066b0 100644
--- a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcessMap.java
+++ b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccProcessMap.java
@@ -28,6 +28,7 @@
 import org.apache.uima.ducc.common.utils.DuccLogger;
 import org.apache.uima.ducc.common.utils.id.DuccId;
 import org.apache.uima.ducc.transport.Constants;
+import org.apache.uima.ducc.transport.event.common.DuccProcess.SpecialValue;
 import org.apache.uima.ducc.transport.event.common.IProcessState.ProcessState;
 
 public class DuccProcessMap extends TreeMap<DuccId,IDuccProcess> implements IDuccProcessMap {
@@ -341,39 +342,136 @@
 		return list.size();
 	}
 	
+	/*
+	 * return actual count if all non-negative (all have cgroups)
+	 * return -1 if all -1 (none have cgroups)
+	 * return -2 if mixed (some do and some don't have cgroups) but retVal would have been == 0
+	 * return -3 if mixed (some do and some don't have cgroups) but retVal would have been > 0
+	 */
 	public long getPgInCount() {
 		long retVal = 0;
+		boolean flagCgroup = false;
+		boolean flagNoCgroup = false;
 		synchronized(this) {
 			Iterator<IDuccProcess> iterator = this.values().iterator();
 			while(iterator.hasNext()) {
 				IDuccProcess process = iterator.next();
-				retVal += process.getMajorFaults();
+				long value = process.getMajorFaults();
+				if(value == SpecialValue.Unknown.getlong()) {
+					// skip it
+				}
+				else {
+					if(value < 0) {
+						flagNoCgroup = true;
+					}
+					else {
+						flagCgroup = true;
+						retVal += value;
+					}
+				}
 			}
 		}
+		if(flagCgroup && flagNoCgroup) {
+			if(retVal > 0){
+				retVal = -3;
+			}
+			else {
+				retVal = -2;
+			}
+		}
+		else if(flagNoCgroup) {
+			retVal = -1;
+		}
 		return retVal;
 	}
 	
+	/*
+	 * return actual count if all non-negative (all have cgroups)
+	 * return -1 if all -1 (none have cgroups)
+	 * return -2 if mixed (some do and some don't have cgroups) but retVal would have been == 0
+	 * return -3 if mixed (some do and some don't have cgroups) but retVal would have been > 0
+	 */
 	public double getSwapUsageGb() {
 		double retVal = 0;
+		boolean flagCgroup = false;
+		boolean flagNoCgroup = false;
 		synchronized(this) {
 			Iterator<IDuccProcess> iterator = this.values().iterator();
 			while(iterator.hasNext()) {
 				IDuccProcess process = iterator.next();
-				double swap = process.getSwapUsage();
-				retVal += swap/Constants.GB;
+				double value = process.getSwapUsage();
+				if(value == SpecialValue.Unknown.getlong()) {
+					// skip it
+				}
+				else {
+					if(value < 0) {
+						flagNoCgroup = true;
+					}
+					else {
+						flagCgroup = true;
+						retVal += value/Constants.GB;
+					}
+				}
 			}
 		}
+		if(flagCgroup && flagNoCgroup) {
+			if(retVal > 0){
+				retVal = -3;
+			}
+			else {
+				retVal = -2;
+			}
+		}
+		else if(flagNoCgroup) {
+			retVal = -1;
+		}
 		return retVal;
 	}
 	
+	/*
+	 * return actual count if all non-negative (all have cgroups)
+	 * return -1 if all -1 (none have cgroups)
+	 * return -2 if mixed (some do and some don't have cgroups) but retVal would have been == 0
+	 * return -3 if mixed (some do and some don't have cgroups) but retVal would have been > 0
+	 */
 	public double getSwapUsageGbMax() {
 		double retVal = 0;
-		synchronized(this) {
-			Iterator<IDuccProcess> iterator = this.values().iterator();
-			while(iterator.hasNext()) {
-				IDuccProcess process = iterator.next();
-				double swap = process.getSwapUsageMax();
-				retVal += swap/Constants.GB;
+		double swap = getSwapUsageGb();
+		if(swap < 0) {
+			retVal = swap;
+		}
+		else {
+			boolean flagCgroup = false;
+			boolean flagNoCgroup = false;
+			synchronized(this) {
+				Iterator<IDuccProcess> iterator = this.values().iterator();
+				while(iterator.hasNext()) {
+					IDuccProcess process = iterator.next();
+					double value = process.getSwapUsageMax();
+					if(value == SpecialValue.Unknown.getlong()) {
+						// skip it
+					}
+					else {
+						if(value < 0) {
+							flagNoCgroup = true;
+						}
+						else {
+							flagCgroup = true;
+							retVal += value/Constants.GB;
+						}
+					}
+				}
+			}
+			if(flagCgroup && flagNoCgroup) {
+				if(retVal > 0){
+					retVal = -3;
+				}
+				else {
+					retVal = -2;
+				}
+			}
+			else if(flagNoCgroup) {
+				retVal = -1;
 			}
 		}
 		return retVal;
diff --git a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccWorkJob.java b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccWorkJob.java
index e69bb41..86aec2f 100644
--- a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccWorkJob.java
+++ b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/common/DuccWorkJob.java
@@ -455,49 +455,86 @@
 		return (getAliveProcessCount() > 0);
 	}
 	
-	public long getPgInCount() {
+	// choose the smallest negative value, else return the sum
+	private long merge(long jd, long jp) {
 		long retVal = 0;
-		IDuccProcessMap map = getProcessMap();
-		if(map != null) {
-			retVal += map.getPgInCount();
+		if((jd >= 0) && (jp >= 0)) {
+			retVal = jd+jp;
 		}
-		DuccWorkPopDriver driver = getDriver();
-		if(driver != null) {
-			map = driver.getProcessMap();
-			retVal += map.getPgInCount();
+		else {
+			if(jd < jp) {
+				retVal = jd;
+			}
+			else {
+				retVal = jp;
+			}
 		}
 		return retVal;
 	}
 	
-	public double getSwapUsageGb() {
+	// choose the smallest negative value, else return the sum
+	private double merge(double jd, double jp) {
 		double retVal = 0;
+		if((jd >= 0) && (jp >= 0)) {
+			retVal = jd+jp;
+		}
+		else {
+			if(jd < jp) {
+				retVal = jd;
+			}
+			else {
+				retVal = jp;
+			}
+		}
+		return retVal;
+	}
+	
+	public long getPgInCount() {
+		long jp = 0;
+		long jd = 0;
 		IDuccProcessMap map = getProcessMap();
 		if(map != null) {
-			double swap = map.getSwapUsageGb();
-			retVal += swap;
+			jp = map.getPgInCount();
 		}
 		DuccWorkPopDriver driver = getDriver();
 		if(driver != null) {
 			map = driver.getProcessMap();
-			double swap = map.getSwapUsageGb();
-			retVal += swap;
+			 jd = map.getPgInCount();
 		}
+		long retVal = merge(jd, jp);
+		return retVal;
+	}
+	
+	public double getSwapUsageGb() {
+		double jp = 0;
+		double jd = 0;
+		IDuccProcessMap map = getProcessMap();
+		if(map != null) {
+			jp = map.getSwapUsageGb();
+		}
+		DuccWorkPopDriver driver = getDriver();
+		if(driver != null) {
+			map = driver.getProcessMap();
+			jp = map.getSwapUsageGb();
+		}
+		double retVal = merge(jd, jp);
 		return retVal;
 	}
 	
 	public double getSwapUsageGbMax() {
 		double retVal = 0;
 		IDuccProcessMap map = getProcessMap();
+		double jp = 0;
+		double jd = 0;
 		if(map != null) {
-			double swap = map.getSwapUsageGbMax();
-			retVal += swap;
+			jp = map.getSwapUsageGbMax();
 		}
 		DuccWorkPopDriver driver = getDriver();
 		if(driver != null) {
 			map = driver.getProcessMap();
-			double swap = map.getSwapUsageGbMax();
-			retVal += swap;
+			jd = map.getSwapUsageGbMax();
 		}
+		retVal = merge(jp, jd);
 		return retVal;
 	}
 
diff --git a/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/DuccAbstractProcessContainer.java b/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/DuccAbstractProcessContainer.java
index 6754088..c80ea22 100644
--- a/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/DuccAbstractProcessContainer.java
+++ b/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/DuccAbstractProcessContainer.java
@@ -110,6 +110,8 @@
  		Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
          try {
      		doDeploy();
+         } catch( Exception e) {
+        	 throw e;
          } finally {
  			Thread.currentThread().setContextClassLoader(savedCL);
  			//	Pin thread to its own CAS serializer instance
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamAuthenticate.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamAuthenticate.java
index 85ed2de..f05c61c 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamAuthenticate.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamAuthenticate.java
@@ -29,6 +29,9 @@
 		System.out.println(result.name()+" "+text);
 	}
 	
+	/*
+	 * See UserAuthentciate.
+	 */
 	protected void launch(String[] args, boolean verbose) {
 		try {
 			if(args == null) {
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/UserAuthenticate.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/UserAuthenticate.java
index 0d6fe6d..59049f3 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/UserAuthenticate.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/UserAuthenticate.java
@@ -28,6 +28,11 @@
 	
 	private String failure = "failure";
 	
+	/*
+	 * We employ ducc_ling to switch to the target userid.
+	 * As the target userid we invoke authenticate with target userid and pw.
+	 * Only the userid itself or "root" can succeed, hence the use of ducc_ling.
+	 */
 	public String launch(String[] args) {
 		String methodName = "launch";
 		String result = null;
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/sort/ServicesHelper.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/sort/ServicesHelper.java
index a61622b..8ad22d9 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/sort/ServicesHelper.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/sort/ServicesHelper.java
@@ -90,48 +90,126 @@
 		return retVal;
 	}
 	
+	/*
+	 * return actual count if all non-negative (all have cgroups)
+	 * return -1 if all -1 (none have cgroups)
+	 * return -2 if mixed (some do and some don't have cgroups) but retVal would have been == 0
+	 * return -3 if mixed (some do and some don't have cgroups) but retVal would have been > 0
+	 */
 	public long getPgIn(IServiceAdapter serviceAdapter) {
 		long retVal = 0;
+		boolean flagCgroup = false;
+		boolean flagNoCgroup = false;
 		List<DuccWorkJob> servicesList = getServicesList(serviceAdapter);
 		for(DuccWorkJob service : servicesList) {
 			IDuccProcessMap map = service.getProcessMap();
 			for(DuccId key : map.keySet()) {
 				IDuccProcess process = map.get(key);
 				if(process.isActive()) {
-					retVal += process.getMajorFaults();
+					long value = process.getMajorFaults();
+					if(value < 0) {
+						flagNoCgroup = true;
+					}
+					else {
+						flagCgroup = true;
+						retVal += value;
+					}
 				}
 			}
 		}
+		if(flagCgroup && flagNoCgroup) {
+			if(retVal > 0){
+				retVal = -3;
+			}
+			else {
+				retVal = -2;
+			}
+		}
+		else if(flagNoCgroup) {
+			retVal = -1;
+		}
 		return retVal;
 	}
 	
+	/*
+	 * return actual count if all non-negative (all have cgroups)
+	 * return -1 if all -1 (none have cgroups)
+	 * return -2 if mixed (some do and some don't have cgroups) but retVal would have been == 0
+	 * return -3 if mixed (some do and some don't have cgroups) but retVal would have been > 0
+	 */
 	public long getSwap(IServiceAdapter serviceAdapter) {
 		long retVal = 0;
+		boolean flagCgroup = false;
+		boolean flagNoCgroup = false;
 		List<DuccWorkJob> servicesList = getServicesList(serviceAdapter);
 		for(DuccWorkJob service : servicesList) {
 			IDuccProcessMap map = service.getProcessMap();
 			for(DuccId key : map.keySet()) {
 				IDuccProcess process = map.get(key);
 				if(process.isActive()) {
-					retVal += process.getSwapUsage();
+					long value = process.getSwapUsage();
+					if(value < 0) {
+						flagNoCgroup = true;
+					}
+					else {
+						flagCgroup = true;
+						retVal += value;
+					}
 				}
 			}
 		}
+		if(flagCgroup && flagNoCgroup) {
+			if(retVal > 0){
+				retVal = -3;
+			}
+			else {
+				retVal = -2;
+			}
+		}
+		else if(flagNoCgroup) {
+			retVal = -1;
+		}
 		return retVal;
 	}
 	
+	/*
+	 * return actual count if all non-negative (all have cgroups)
+	 * return -1 if all -1 (none have cgroups)
+	 * return -2 if mixed (some do and some don't have cgroups) but retVal would have been == 0
+	 * return -3 if mixed (some do and some don't have cgroups) but retVal would have been > 0
+	 */
 	public long getSwapMax(IServiceAdapter serviceAdapter) {
 		long retVal = 0;
+		boolean flagCgroup = false;
+		boolean flagNoCgroup = false;
 		List<DuccWorkJob> servicesList = getServicesList(serviceAdapter);
 		for(DuccWorkJob service : servicesList) {
 			IDuccProcessMap map = service.getProcessMap();
 			for(DuccId key : map.keySet()) {
 				IDuccProcess process = map.get(key);
 				if(process.isActive()) {
-					retVal += process.getSwapUsageMax();
+					long value = process.getSwapUsageMax();
+					if(value < 0) {
+						flagNoCgroup = true;
+					}
+					else {
+						flagCgroup = true;
+						retVal += value;
+					}
 				}
 			}
 		}
+		if(flagCgroup && flagNoCgroup) {
+			if(retVal > 0){
+				retVal = -3;
+			}
+			else {
+				retVal = -2;
+			}
+		}
+		else if(flagNoCgroup) {
+			retVal = -1;
+		}
 		return retVal;
 	}
 }
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccAbstractHandler.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccAbstractHandler.java
index 8f2ac3e..29dd023 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccAbstractHandler.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccAbstractHandler.java
@@ -75,6 +75,9 @@
 	
 	public static DuccWebAdministrators duccWebAdministrators = DuccWebAdministrators.getInstance();
 	public static DuccWebSessionManager duccWebSessionManager = DuccWebSessionManager.getInstance();
+
+	public final String notAvailable = "N/A";
+	public final String inc = "INC";
 	
 	public final String duccUimaInitializationReport		  = "uima-initialization-report.html";
 	
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java
index 29f849f..7573815 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java
@@ -144,9 +144,7 @@
 	private enum DetailsType { Job, Reservation, Service };
 	private enum AllocationType { JD, MR, SPC, SPU, UIMA };
 	private enum LogType { POP, UIMA };
-	
-	private String notAvailable = "N/A";
-	
+
 	private DuccAuthenticator duccAuthenticator = DuccAuthenticator.getInstance();
 	
 	private String duccVersion						= duccContext+"/version";
@@ -1612,20 +1610,26 @@
 	}
 	
 	private IDuccWorkJob findJob(String jobno) {
+		String methodName = "findJob";
 		IDuccWorkJob job = null;
-		IDuccWorkMap duccWorkMap = DuccData.getInstance().get();
-		if(duccWorkMap.getJobKeySet().size()> 0) {
-			Iterator<DuccId> iterator = null;
-			iterator = duccWorkMap.getJobKeySet().iterator();
-			while(iterator.hasNext()) {
-				DuccId jobId = iterator.next();
-				String fid = ""+jobId.getFriendly();
-				if(jobno.equals(fid)) {
-					job = (DuccWorkJob) duccWorkMap.findDuccWork(jobId);
-					break;
+		try {
+			IDuccWorkMap duccWorkMap = DuccData.getInstance().get();
+			if(duccWorkMap.getJobKeySet().size()> 0) {
+				Iterator<DuccId> iterator = null;
+				iterator = duccWorkMap.getJobKeySet().iterator();
+				while(iterator.hasNext()) {
+					DuccId jobId = iterator.next();
+					String fid = ""+jobId.getFriendly();
+					if(jobno.equals(fid)) {
+						job = (DuccWorkJob) duccWorkMap.findDuccWork(jobId);
+						break;
+					}
 				}
 			}
 		}
+		catch(Exception e) {
+			duccLogger.trace(methodName, null, "jobno="+jobno, e);
+		}
 		return job;
 	}
 	
@@ -3484,6 +3488,27 @@
 				heartbeat = "0";
 				heartmax = "0";
 				break;
+			case Broker:
+				boolean brokerAlive = brokerHelper.isAlive();
+				if(brokerAlive) {
+					status = "up";
+				}
+				else {
+					status = "down";
+				}
+				heartbeat = "0";
+				heartmax = "0";
+				break;
+			case Database:
+				if(databaseHelper.isAlive()) {
+					status = "up";
+				}
+				else {
+					status = "down";
+				}
+				heartbeat = "0";
+				heartmax = "0";
+				break;
 			default:
 				status = "unknown";
 				String hb = DuccDaemonsData.getInstance().getHeartbeat(daemonName);
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerClassic.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerClassic.java
index 67c2657..b6a84fe 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerClassic.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerClassic.java
@@ -53,7 +53,6 @@
 import org.apache.uima.ducc.common.utils.TimeStamp;
 import org.apache.uima.ducc.common.utils.id.DuccId;
 import org.apache.uima.ducc.orchestrator.jd.scheduler.JdReservation;
-import org.apache.uima.ducc.transport.Constants;
 import org.apache.uima.ducc.transport.event.common.DuccWorkJob;
 import org.apache.uima.ducc.transport.event.common.DuccWorkReservation;
 import org.apache.uima.ducc.transport.event.common.IDuccPerWorkItemStatistics;
@@ -306,14 +305,31 @@
 		}
 		catch(Exception e) {
 		}
-		double swapping = job.getSwapUsageGbMax();
-		if((swapping * faults) > 0) {
-			sb.append("<span class=\"health_red\""+">");
+		int ifaults = (int)faults;
+		switch(ifaults) {
+		case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+			sb.append("<span title=\"incomplete\" class=\"health_red\""+">");
+			sb.append(inc);
+			break;
+		case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+			sb.append("<span title=\"incomplete\" class=\"health_black\""+">");
+			sb.append(inc);
+			break;
+		case -1: // (none have cgroups)
+			sb.append("<span title=\"not available\" class=\"health_black\""+">");
+			sb.append(notAvailable);
+			break;
+		default: // (all have cgroups)
+			double swapping = job.getSwapUsageGbMax();
+			if((swapping * faults) > 0) {
+				sb.append("<span class=\"health_red\""+">");
+			}
+			else {
+				sb.append("<span class=\"health_black\""+">");
+			}
+			sb.append(faults);
+			break;
 		}
-		else {
-			sb.append("<span class=\"health_black\""+">");
-		}
-		sb.append(faults);
 		sb.append("</span>");
 		sb.append("</td>");
 		// Swap
@@ -321,18 +337,41 @@
 		String swapSizeDisplay = "";
 		String swapSizeHover = "";
 		title = "";
-		double swapBytes = 0;
-		swapBytes = DuccHandlerUtils.getSwapSizeBytes(job);
-		swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
-		swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
-		title = "title="+"\""+swapSizeHover+"\"";
-		if(swapBytes > 0) {
-			sb.append("<span "+title+" "+"class=\"health_red\""+">");
+		double swap = 0;
+		if(job.isCompleted()) {
+			swap = job.getSwapUsageGbMax();
 		}
 		else {
-			sb.append("<span "+title+" "+"class=\"health_black\""+">");
+			swap = job.getSwapUsageGb();
 		}
-		sb.append(swapSizeDisplay);
+		int iswap = (int)swap;
+		switch(iswap) {
+		case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+			sb.append("<span title=\"incomplete\" class=\"health_red\""+">");
+			sb.append(inc);
+			break;
+		case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+			sb.append("<span title=\"incomplete\" class=\"health_black\""+">");
+			sb.append(inc);
+			break;
+		case -1: // (none have cgroups)
+			sb.append("<span title=\"not available\" class=\"health_black\""+">");
+			sb.append(notAvailable);
+			break;
+		default: // (all have cgroups)
+			double swapBytes = swap*DuccHandlerUtils.GB;
+			swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
+			swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
+			title = "title="+"\""+swapSizeHover+"\"";
+			if(swapBytes > 0) {
+				sb.append("<span "+title+" "+"class=\"health_red\""+">");
+			}
+			else {
+				sb.append("<span "+title+" "+"class=\"health_black\""+">");
+			}
+			sb.append(swapSizeDisplay);
+			break;
+		}
 		sb.append("</span>");
 		sb.append("</td>");
 		// Memory
@@ -788,38 +827,78 @@
 			}
 			catch(Exception e) {
 			}
-			double swapping = job.getSwapUsageGbMax();
-			if((swapping * faults) > 0) {
-				sb.append("<span class=\"health_red\""+">");
+			int ifaults = (int)faults;
+			switch(ifaults) {
+			case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+				sb.append("<span title=\"incomplete\" class=\"health_red\""+">");
+				sb.append(inc);
+				break;
+			case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+				sb.append("<span title=\"incomplete\" class=\"health_black\""+">");
+				sb.append(inc);
+				break;
+			case -1: // (none have cgroups)
+				sb.append("<span title=\"not available\" class=\"health_black\""+">");
+				sb.append(notAvailable);
+				break;
+			default: // (all have cgroups)
+				double swapping = job.getSwapUsageGbMax();
+				if((swapping * faults) > 0) {
+					sb.append("<span class=\"health_red\""+">");
+				}
+				else {
+					sb.append("<span class=\"health_black\""+">");
+				}
+				sb.append(faults);
+				break;
 			}
-			else {
-				sb.append("<span class=\"health_black\""+">");
-			}
-			sb.append(faults);
 			sb.append("</span>");
 		}
 		sb.append("</td>");
 		// Swap
 		sb.append("<td align=\"right\">");
-		String swapSizeDisplay = "";
-		String swapSizeHover = "";
-		title = "";
-		double swapBytes = 0;
 		if(duccwork instanceof DuccWorkJob) {
 			DuccWorkJob job = (DuccWorkJob) duccwork;
-			swapBytes = DuccHandlerUtils.getSwapSizeBytes(job);
-			swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
-			swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
-			title = "title="+"\""+swapSizeHover+"\"";
+			String swapSizeDisplay = "";
+			String swapSizeHover = "";
+			title = "";
+			double swap = 0;
+			if(job.isCompleted()) {
+				swap = job.getSwapUsageGbMax();
+			}
+			else {
+				swap = job.getSwapUsageGb();
+			}
+			int iswap = (int)swap;
+			switch(iswap) {
+			case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+				sb.append("<span title=\"incomplete\" class=\"health_red\""+">");
+				sb.append(inc);
+				break;
+			case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+				sb.append("<span title=\"incomplete\" class=\"health_black\""+">");
+				sb.append(inc);
+				break;
+			case -1: // (none have cgroups)
+				sb.append("<span title=\"not available\" class=\"health_black\""+">");
+				sb.append(notAvailable);
+				break;
+			default: // (all have cgroups)
+				double swapBytes = swap*DuccHandlerUtils.GB;
+				swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
+				swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
+				title = "title="+"\""+swapSizeHover+"\"";
+				if(swapBytes > 0) {
+					sb.append("<span "+title+" "+"class=\"health_red\""+">");
+				}
+				else {
+					sb.append("<span "+title+" "+"class=\"health_black\""+">");
+				}
+				sb.append(swapSizeDisplay);
+				break;
+			}
+			sb.append("</span>");
 		}
-		if(swapBytes > 0) {
-			sb.append("<span "+title+" "+"class=\"health_red\""+">");
-		}
-		else {
-			sb.append("<span "+title+" "+"class=\"health_black\""+">");
-		}
-		sb.append(swapSizeDisplay);
-		sb.append("</span>");
 		sb.append("</td>");
 		// Memory
 		IDuccSchedulingInfo si;
@@ -1094,15 +1173,31 @@
 				}
 				catch(Exception e) {
 				}
-				double swapping = service.getSwap();
-				swapping = swapping/Constants.GB;
-				if((swapping * faults) > 0) {
-					sb.append("<span class=\"health_red\""+">");
+				int ifaults = (int)faults;
+				switch(ifaults) {
+				case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+					sb.append("<span title=\"incomplete\" class=\"health_red\""+">");
+					sb.append(inc);
+					break;
+				case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+					sb.append("<span title=\"incomplete\" class=\"health_black\""+">");
+					sb.append(inc);
+					break;
+				case -1: // (none have cgroups)
+					sb.append("<span title=\"not available\" class=\"health_black\""+">");
+					sb.append(notAvailable);
+					break;
+				default: // (all have cgroups)
+					double swapping = service.getSwap();
+					if((swapping * faults) > 0) {
+						sb.append("<span class=\"health_red\""+">");
+					}
+					else {
+						sb.append("<span class=\"health_black\""+">");
+					}
+					sb.append(faults);
+					break;
 				}
-				else {
-					sb.append("<span class=\"health_black\""+">");
-				}
-				sb.append(faults);
 				sb.append("</span>");
 				sb.append("</td>");
 				// Swap
@@ -1110,18 +1205,35 @@
 				String swapSizeDisplay = "";
 				String swapSizeHover = "";
 				String title = "";
-				double swapBytes = 0;
-				swapBytes = service.getSwap();
-				swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
-				swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
-				title = "title="+"\""+swapSizeHover+"\"";
-				if(swapBytes > 0) {
-					sb.append("<span "+title+" "+"class=\"health_red\""+">");
+				double swap = service.getSwap();
+				int iswap = (int)swap;
+				switch(iswap) {
+				case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+					sb.append("<span title=\"incomplete\" class=\"health_red\""+">");
+					sb.append(inc);
+					break;
+				case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+					sb.append("<span title=\"incomplete\" class=\"health_black\""+">");
+					sb.append(inc);
+					break;
+				case -1: // (none have cgroups)
+					sb.append("<span title=\"not available\" class=\"health_black\""+">");
+					sb.append(notAvailable);
+					break;
+				default: // (all have cgroups)
+					double swapBytes = swap;
+					swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
+					swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
+					title = "title="+"\""+swapSizeHover+"\"";
+					if(swapBytes > 0) {
+						sb.append("<span "+title+" "+"class=\"health_red\""+">");
+					}
+					else {
+						sb.append("<span "+title+" "+"class=\"health_black\""+">");
+					}
+					sb.append(swapSizeDisplay);
+					break;
 				}
-				else {
-					sb.append("<span "+title+" "+"class=\"health_black\""+">");
-				}
-				sb.append(swapSizeDisplay);
 				sb.append("</span>");
 				sb.append("</td>");
 				// Size
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerJsonFormat.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerJsonFormat.java
index e74138b..07e6a93 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerJsonFormat.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerJsonFormat.java
@@ -57,7 +57,6 @@
 import org.apache.uima.ducc.common.utils.TimeStamp;
 import org.apache.uima.ducc.common.utils.id.DuccId;
 import org.apache.uima.ducc.orchestrator.jd.scheduler.JdReservation;
-import org.apache.uima.ducc.transport.Constants;
 import org.apache.uima.ducc.transport.event.common.DuccWorkJob;
 import org.apache.uima.ducc.transport.event.common.DuccWorkReservation;
 import org.apache.uima.ducc.transport.event.common.IDuccPerWorkItemStatistics;
@@ -332,42 +331,86 @@
 		// Pgin
 		sb = new StringBuffer();
 		sb.append("<span>");
+		//
 		long faults = 0;
 		try {
 			faults = job.getPgInCount();
 		}
 		catch(Exception e) {
 		}
-		double swapping = job.getSwapUsageGbMax();
-		if((swapping * faults) > 0) {
-			sb.append("<span class=\"health_red\""+">");
+		int ifaults = (int)faults;
+		switch(ifaults) {
+		case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+			sb.append("<span title=\"incomplete\" class=\"health_red\""+">");
+			sb.append(inc);
+			break;
+		case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+			sb.append("<span title=\"incomplete\" class=\"health_black\""+">");
+			sb.append(inc);
+			break;
+		case -1: // (none have cgroups)
+			sb.append("<span title=\"not available\" class=\"health_black\""+">");
+			sb.append(notAvailable);
+			break;
+		default: // (all have cgroups)
+			double swapping = job.getSwapUsageGbMax();
+			if((swapping * faults) > 0) {
+				sb.append("<span class=\"health_red\""+">");
+			}
+			else {
+				sb.append("<span class=\"health_black\""+">");
+			}
+			sb.append(faults);
+			break;
 		}
-		else {
-			sb.append("<span class=\"health_black\""+">");
-		}
-		sb.append(faults);
 		sb.append("</span>");
+		//
 		sb.append("</span>");
 		row.add(new JsonPrimitive(sb.toString()));
 		// Swap
 		sb = new StringBuffer();
 		sb.append("<span>");
+		//
 		String swapSizeDisplay = "";
 		String swapSizeHover = "";
 		title = "";
-		double swapBytes = 0;
-		swapBytes = DuccHandlerUtils.getSwapSizeBytes(job);
-		swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
-		swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
-		title = "title="+"\""+swapSizeHover+"\"";
-		if(swapBytes > 0) {
-			sb.append("<span "+title+" "+"class=\"health_red\""+">");
+		double swap = 0;
+		if(job.isCompleted()) {
+			swap = job.getSwapUsageGbMax();
 		}
 		else {
-			sb.append("<span "+title+" "+"class=\"health_black\""+">");
+			swap = job.getSwapUsageGb();
 		}
-		sb.append(swapSizeDisplay);
+		int iswap = (int)swap;
+		switch(iswap) {
+		case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+			sb.append("<span title=\"incomplete\" class=\"health_red\""+">");
+			sb.append(inc);
+			break;
+		case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+			sb.append("<span title=\"incomplete\" class=\"health_black\""+">");
+			sb.append(inc);
+			break;
+		case -1: // (none have cgroups)
+			sb.append("<span title=\"not available\" class=\"health_black\""+">");
+			sb.append(notAvailable);
+			break;
+		default: // (all have cgroups)
+			double swapBytes = swap*DuccHandlerUtils.GB;
+			swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
+			swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
+			title = "title="+"\""+swapSizeHover+"\"";
+			if(swapBytes > 0) {
+				sb.append("<span "+title+" "+"class=\"health_red\""+">");
+			}
+			else {
+				sb.append("<span "+title+" "+"class=\"health_black\""+">");
+			}
+			sb.append(swapSizeDisplay);
+			break;
+		}
 		sb.append("</span>");
+		//
 		sb.append("</span>");
 		row.add(new JsonPrimitive(sb.toString()));
 		// Memory
@@ -878,6 +921,7 @@
 		// PgIn
 		sb = new StringBuffer();
 		sb.append("<span>");
+		//
 		if(duccwork instanceof DuccWorkJob) {
 			DuccWorkJob job = (DuccWorkJob) duccwork;
 			long faults = 0;
@@ -886,40 +930,83 @@
 			}
 			catch(Exception e) {
 			}
-			double swapping = job.getSwapUsageGbMax();
-			if((swapping * faults) > 0) {
-				sb.append("<span class=\"health_red\""+">");
+			int ifaults = (int)faults;
+			switch(ifaults) {
+			case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+				sb.append("<span title=\"incomplete\" class=\"health_red\""+">");
+				sb.append(inc);
+				break;
+			case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+				sb.append("<span title=\"incomplete\" class=\"health_black\""+">");
+				sb.append(inc);
+				break;
+			case -1: // (none have cgroups)
+				sb.append("<span title=\"not available\" class=\"health_black\""+">");
+				sb.append(notAvailable);
+				break;
+			default: // (all have cgroups)
+				double swapping = job.getSwapUsageGbMax();
+				if((swapping * faults) > 0) {
+					sb.append("<span class=\"health_red\""+">");
+				}
+				else {
+					sb.append("<span class=\"health_black\""+">");
+				}
+				sb.append(faults);
+				break;
 			}
-			else {
-				sb.append("<span class=\"health_black\""+">");
-			}
-			sb.append(faults);
 			sb.append("</span>");
 		}
+		//
 		sb.append("</span>");
 		row.add(new JsonPrimitive(sb.toString()));
 		// Swap
 		sb = new StringBuffer();
 		sb.append("<span>");
-		String swapSizeDisplay = "";
-		String swapSizeHover = "";
-		title = "";
-		double swapBytes = 0;
+		//
 		if(duccwork instanceof DuccWorkJob) {
 			DuccWorkJob job = (DuccWorkJob) duccwork;
-			swapBytes = DuccHandlerUtils.getSwapSizeBytes(job);
-			swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
-			swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
-			title = "title="+"\""+swapSizeHover+"\"";
+			String swapSizeDisplay = "";
+			String swapSizeHover = "";
+			title = "";
+			double swap = 0;
+			if(job.isCompleted()) {
+				swap = job.getSwapUsageGbMax();
+			}
+			else {
+				swap = job.getSwapUsageGb();
+			}
+			int iswap = (int)swap;
+			switch(iswap) {
+			case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+				sb.append("<span title=\"incomplete\" class=\"health_red\""+">");
+				sb.append(inc);
+				break;
+			case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+				sb.append("<span title=\"incomplete\" class=\"health_black\""+">");
+				sb.append(inc);
+				break;
+			case -1: // (none have cgroups)
+				sb.append("<span title=\"not available\" class=\"health_black\""+">");
+				sb.append(notAvailable);
+				break;
+			default: // (all have cgroups)
+				double swapBytes = swap*DuccHandlerUtils.GB;
+				swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
+				swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
+				title = "title="+"\""+swapSizeHover+"\"";
+				if(swapBytes > 0) {
+					sb.append("<span "+title+" "+"class=\"health_red\""+">");
+				}
+				else {
+					sb.append("<span "+title+" "+"class=\"health_black\""+">");
+				}
+				sb.append(swapSizeDisplay);
+				break;
+			}
+			sb.append("</span>");
 		}
-		if(swapBytes > 0) {
-			sb.append("<span "+title+" "+"class=\"health_red\""+">");
-		}
-		else {
-			sb.append("<span "+title+" "+"class=\"health_black\""+">");
-		}
-		sb.append(swapSizeDisplay);
-		sb.append("</span>");
+		//
 		sb.append("</span>");
 		row.add(new JsonPrimitive(sb.toString()));
 		// Memory
@@ -1236,42 +1323,80 @@
 				// Pgin
 				col = new StringBuffer();
 				col.append("<span>");
+				//
 				long faults = 0;
 				try {
 					faults = service.getPgIn();
 				}
 				catch(Exception e) {
 				}
-				double swapping = service.getSwap();
-				swapping = swapping/Constants.GB;
-				if((swapping * faults) > 0) {
-					col.append("<span class=\"health_red\""+">");
+				int ifaults = (int)faults;
+				switch(ifaults) {
+				case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+					col.append("<span title=\"incomplete\" class=\"health_red\""+">");
+					col.append(inc);
+					break;
+				case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+					col.append("<span title=\"incomplete\" class=\"health_black\""+">");
+					col.append(inc);
+					break;
+				case -1: // (none have cgroups)
+					col.append("<span title=\"not available\" class=\"health_black\""+">");
+					col.append(notAvailable);
+					break;
+				default: // (all have cgroups)
+					double swapping = service.getSwap();
+					if((swapping * faults) > 0) {
+						col.append("<span class=\"health_red\""+">");
+					}
+					else {
+						col.append("<span class=\"health_black\""+">");
+					}
+					col.append(faults);
+					break;
 				}
-				else {
-					col.append("<span class=\"health_black\""+">");
-				}
-				col.append(faults);
+				col.append("</span>");
+				//
 				col.append("</span>");
 				row.add(new JsonPrimitive(col.toString()));
 				// Swap
 				col = new StringBuffer();
 				col.append("<span>");
+				//
 				String swapSizeDisplay = "";
 				String swapSizeHover = "";
 				String title = "";
-				double swapBytes = 0;
-				swapBytes = service.getSwap();
-				swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
-				swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
-				title = "title="+"\""+swapSizeHover+"\"";
-				if(swapBytes > 0) {
-					col.append("<span "+title+" "+"class=\"health_red\""+">");
+				double swap = service.getSwap();
+				int iswap = (int)swap;
+				switch(iswap) {
+				case -3: // (some do and some don't have cgroups) but retVal would have been > 0
+					col.append("<span title=\"incomplete\" class=\"health_red\""+">");
+					col.append(inc);
+					break;
+				case -2: // (some do and some don't have cgroups) but retVal would have been == 0
+					col.append("<span title=\"incomplete\" class=\"health_black\""+">");
+					col.append(inc);
+					break;
+				case -1: // (none have cgroups)
+					col.append("<span title=\"not available\" class=\"health_black\""+">");
+					col.append(notAvailable);
+					break;
+				default: // (all have cgroups)
+					double swapBytes = swap;
+					swapSizeDisplay = DuccHandlerUtils.getSwapSizeDisplay(swapBytes);
+					swapSizeHover = DuccHandlerUtils.getSwapSizeHover(swapBytes);
+					title = "title="+"\""+swapSizeHover+"\"";
+					if(swapBytes > 0) {
+						col.append("<span "+title+" "+"class=\"health_red\""+">");
+					}
+					else {
+						col.append("<span "+title+" "+"class=\"health_black\""+">");
+					}
+					col.append(swapSizeDisplay);
+					break;
 				}
-				else {
-					col.append("<span "+title+" "+"class=\"health_black\""+">");
-				}
-				col.append(swapSizeDisplay);
 				col.append("</span>");
+				//
 				col.append("</span>");
 				row.add(new JsonPrimitive(col.toString()));
 				// Size
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUtils.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUtils.java
index 2d25b88..880a445 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUtils.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUtils.java
@@ -20,9 +20,6 @@
 
 import java.text.DecimalFormat;
 
-import org.apache.uima.ducc.transport.event.common.IDuccWorkJob;
-
-
 public class DuccHandlerUtils {
 
 	public static String warn(String text) {
@@ -75,14 +72,6 @@
 	
 	// *****
 	
-	public static double getSwapSizeBytes(IDuccWorkJob job) {
-		double swapBytes = job.getSwapUsageGb()*GB;
-		if(job.isCompleted()) {
-			swapBytes = job.getSwapUsageGbMax()*GB;
-		}
-		return swapBytes;
-	}
-	
 	private static DecimalFormat formatter = new DecimalFormat("###0.0");
 	
 	public static String getSwapSizeDisplay(double swapBytes) {
@@ -90,9 +79,9 @@
 		return retVal;
 	}
 	
-	private static double GB = Math.pow(10,9);
-	private static double MB = Math.pow(10,6);
-	private static double KB = Math.pow(10,3);
+	public static double GB = Math.pow(10,9);
+	public static double MB = Math.pow(10,6);
+	public static double KB = Math.pow(10,3);
 
 	public static String getSwapSizeHover(double swapBytes) {
 		String retVal = null;