Merge branch 'develop' into 2.3-yj: this picks up SLIDER-82, Anti-Affinity

# Conflicts:
#	app-packages/hbase/appConfig-default.json
#	slider-core/src/main/java/org/apache/slider/client/SliderClient.java
#	slider-core/src/main/java/org/apache/slider/client/SliderClientAPI.java
#	slider-core/src/main/java/org/apache/slider/common/params/ClientArgs.java
#	slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
#	slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AgentWebPagesIT.groovy
diff --git a/NOTICE b/NOTICE
index 64e2234..aa37418 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,5 @@
 Apache Slider
-Copyright 2015 The Apache Software Foundation
+Copyright 2014-2015 The Apache Software Foundation
 
 This product includes software developed at The Apache Software
 Foundation (http://www.apache.org/).
diff --git a/app-packages/accumulo/pom.xml b/app-packages/accumulo/pom.xml
index 11d04b7..8744741 100644
--- a/app-packages/accumulo/pom.xml
+++ b/app-packages/accumulo/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.apache.slider.packages</groupId>
     <artifactId>slider-app-packages</artifactId>
-    <version>0.81.0-incubating-SNAPSHOT</version>
+    <version>0.90.0-incubating-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
diff --git a/app-packages/accumulo/src/license/THIRD-PARTY.properties b/app-packages/accumulo/src/license/THIRD-PARTY.properties
index 9322b8f..fb20f7e 100644
--- a/app-packages/accumulo/src/license/THIRD-PARTY.properties
+++ b/app-packages/accumulo/src/license/THIRD-PARTY.properties
@@ -2,10 +2,6 @@
 #-------------------------------------------------------------------------------
 # Already used licenses in project :
 # - Apache License
-# - Apache License 2.0
-# - Apache License Version 2
-# - Apache License, Version 2.0
-# - Apache Software License - Version 2.0
 # - BSD
 # - CDDL + GPLv2 with classpath exception
 # - CDDL 1.1
@@ -13,10 +9,10 @@
 # - Common Public License Version 1.0
 # - Eclipse Public License - Version 1.0
 # - GNU Lesser General Public License (LGPL), Version 2.1
+# - GNU Lesser General Public License, Version 2.1
 # - GPL2 w/ CPE
 # - MIT License
 # - New BSD License
-# - New BSD license
 # - Public Domain
 # - Revised BSD
 # - The Apache Software License, Version 2.0
@@ -26,8 +22,7 @@
 # Please fill the missing licenses for dependencies :
 #
 #
-#Mon Jan 26 16:00:07 GMT 2015
-asm--asm--3.1=The BSD 3-Clause License
+#Thu Oct 15 16:45:03 EDT 2015
 commons-beanutils--commons-beanutils--1.7.0=The Apache Software License, Version 2.0
 javax.servlet--servlet-api--2.5=CDDL License
 javax.servlet.jsp--jsp-api--2.1=CDDL License
diff --git a/app-packages/command-logger/application-pkg/pom.xml b/app-packages/command-logger/application-pkg/pom.xml
index 23d355c..82a4c81 100644
--- a/app-packages/command-logger/application-pkg/pom.xml
+++ b/app-packages/command-logger/application-pkg/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.apache.slider</groupId>
     <artifactId>slider</artifactId>
-    <version>0.81.0-incubating-SNAPSHOT</version>
+    <version>0.90.0-incubating-SNAPSHOT</version>
     <relativePath>../../../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
diff --git a/app-packages/command-logger/slider-pkg/pom.xml b/app-packages/command-logger/slider-pkg/pom.xml
index ea66881..0699a80 100644
--- a/app-packages/command-logger/slider-pkg/pom.xml
+++ b/app-packages/command-logger/slider-pkg/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.slider</groupId>
     <artifactId>slider</artifactId>
-    <version>0.81.0-incubating-SNAPSHOT</version>
+    <version>0.90.0-incubating-SNAPSHOT</version>
     <relativePath>../../../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
diff --git a/app-packages/hbase-win/pom.xml b/app-packages/hbase-win/pom.xml
index e641006..424b2c2 100644
--- a/app-packages/hbase-win/pom.xml
+++ b/app-packages/hbase-win/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.slider.packages</groupId>
     <artifactId>slider-app-packages</artifactId>
-    <version>0.81.0-incubating-SNAPSHOT</version>
+    <version>0.90.0-incubating-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
diff --git a/app-packages/hbase/pom.xml b/app-packages/hbase/pom.xml
index 3188d60..4d1cea0 100644
--- a/app-packages/hbase/pom.xml
+++ b/app-packages/hbase/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.slider.packages</groupId>
     <artifactId>slider-app-packages</artifactId>
-    <version>0.81.0-incubating-SNAPSHOT</version>
+    <version>0.90.0-incubating-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
diff --git a/app-packages/pom.xml b/app-packages/pom.xml
index 6f9d0d1..f32e71c 100644
--- a/app-packages/pom.xml
+++ b/app-packages/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.slider</groupId>
     <artifactId>slider</artifactId>
-    <version>0.81.0-incubating-SNAPSHOT</version>
+    <version>0.90.0-incubating-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
diff --git a/app-packages/storm-win/pom.xml b/app-packages/storm-win/pom.xml
index b6e97c2..d8219db 100644
--- a/app-packages/storm-win/pom.xml
+++ b/app-packages/storm-win/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.slider.packages</groupId>
     <artifactId>slider-app-packages</artifactId>
-    <version>0.81.0-incubating-SNAPSHOT</version>
+    <version>0.90.0-incubating-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
diff --git a/app-packages/storm/package/scripts/params.py b/app-packages/storm/package/scripts/params.py
index b701698..bd293e3 100644
--- a/app-packages/storm/package/scripts/params.py
+++ b/app-packages/storm/package/scripts/params.py
@@ -38,7 +38,7 @@
 nimbus_port = config['configurations']['storm-site']['nimbus.thrift.port']
 rest_api_conf_file = format("{conf_dir}/config.yaml")
 rest_lib_dir = format("{app_root}/external/storm-rest")
-storm_bin = format("{app_root}/bin/storm.py")
+storm_bin = format("{app_root}/bin/storm")
 storm_env_sh_template = config['configurations']['storm-env']['content']
 
 metric_collector_host = default('/configurations/global/metric_collector_host', '')
diff --git a/app-packages/storm/pom.xml b/app-packages/storm/pom.xml
index 6bc95ac..75e918a 100644
--- a/app-packages/storm/pom.xml
+++ b/app-packages/storm/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.slider.packages</groupId>
     <artifactId>slider-app-packages</artifactId>
-    <version>0.81.0-incubating-SNAPSHOT</version>
+    <version>0.90.0-incubating-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
diff --git a/pom.xml b/pom.xml
index 1287daf..93e9540 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
   <groupId>org.apache.slider</groupId>
   <artifactId>slider</artifactId>
   <name>Slider</name>
-  <version>0.81.0-incubating-SNAPSHOT</version>
+  <version>0.90.0-incubating-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <description>
@@ -113,7 +113,7 @@
     -->
     <project.java.src.version>1.7</project.java.src.version>
     <enforced.java.version>${project.java.src.version}</enforced.java.version>
-    <groovy.version>2.4.0</groovy.version>
+    <groovy.version>2.4.5</groovy.version>
     
     <!-- 
     test options
@@ -234,17 +234,21 @@
     <github.site.plugin.version>0.8</github.site.plugin.version>
     <maven-site-plugin.skipDeploy>true</maven-site-plugin.skipDeploy>
     <github.downloads.plugin.version>0.6</github.downloads.plugin.version>
+    
+    <!-- override point for ASF staging/snapshot repos -->
+    <asf.staging>https://repository.apache.org/content/groups/staging/</asf.staging>
+    <asf.snapshots>https://repository.apache.org/content/repositories/snapshots/</asf.snapshots>
   </properties>
 
 
   <repositories>
     <repository>
       <id>ASF Staging</id>
-      <url>https://repository.apache.org/content/groups/staging/</url>
+      <url>${asf.staging}</url>
     </repository>
     <repository>
       <id>ASF Snapshots</id>
-      <url>https://repository.apache.org/content/repositories/snapshots/</url>
+      <url>${asf.snapshots}</url>
       <snapshots>
         <enabled>true</enabled>
       </snapshots>
@@ -517,6 +521,13 @@
       </dependency>
 
       <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-all</artifactId>
+        <classifier>indy</classifier>
+        <version>${groovy.version}</version>
+      </dependency>
+
+      <dependency>
         <groupId>com.beust</groupId>
         <artifactId>jcommander</artifactId>
         <version>${jcommander.version}</version>
@@ -530,7 +541,7 @@
 
       <!-- hadoop-client includes the following jars, so they do not need to be
         included separately:
-        hadoop-common, hadoop-hdfs, hadoop-mapreduce-client-app,
+        hadoop-common, hadoop-hdfs (client?), hadoop-mapreduce-client-app,
         hadoop-yarn-api, hadoop-mapreduce-client-core,
         hadoop-mapreduce-client-jobclient, and hadoop-annotations
       -->
@@ -558,6 +569,34 @@
         </exclusions>
       </dependency>
 
+      <!--
+        Hadoop HDFS is pulled in to guarantee that any split to hadoop-hdfs-client doesn't
+        break the build.
+      -->
+      <dependency>
+        <groupId>org.apache.hadoop</groupId>
+        <artifactId>hadoop-hdfs</artifactId>
+        <version>${hadoop.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-core-asl</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+
       <!-- hadoop-minicluster includes the following test-jars, so they do not
         need to be included separately:
         hadoop-common, hadoop-hdfs, hadoop-yarn-server-tests,
@@ -596,7 +635,7 @@
         <artifactId>hadoop-yarn-registry</artifactId>
         <version>${hadoop.version}</version>
       </dependency>
-      
+
       <dependency>
         <groupId>org.apache.hadoop</groupId>
         <artifactId>hadoop-yarn-server-web-proxy</artifactId>
@@ -1147,6 +1186,12 @@
       </dependency>
 
       <dependency>
+        <groupId>org.apache.curator</groupId>
+        <artifactId>curator-recipes</artifactId>
+        <version>${curator.version}</version>
+      </dependency>
+
+      <dependency>
         <groupId>com.google.guava</groupId>
         <artifactId>guava</artifactId>
         <version>${guava.version}</version>
@@ -1394,6 +1439,12 @@
         <version>1.5</version>
       </dependency>
 
+      <dependency>
+        <groupId>asm</groupId>
+        <artifactId>asm</artifactId>
+        <version>3.3.1</version>
+      </dependency>
+
     </dependencies>
     
   </dependencyManagement>
@@ -1464,6 +1515,7 @@
                 <exclude>DISCLAIMER</exclude>
                 <exclude>app-packages/hbase/target/**</exclude>
                 <exclude>target/*</exclude>
+                <exclude>DEPENDENCIES</exclude>
               </excludes>
             </configuration>
           </plugin>
@@ -1627,25 +1679,51 @@
 
     <profile>
       <!-- 2.7.0 -->
-      <id>release-2.7</id>
+      <id>release-2.7.0</id>
       <properties>
         <hadoop.version>2.7.0</hadoop.version>
+        <curator.version>2.7.1</curator.version>
+        <zookeeper.version>3.4.6</zookeeper.version>
       </properties>
     </profile>
 
     <profile>
-      <!-- hadoop branch-2.7 builds  -->
-      <id>branch-2.7</id>
+      <!-- hadoop 2.7.1 -->
+      <id>release-2.7.1</id>
       <properties>
-        <hadoop.version>2.7.1-SNAPSHOT</hadoop.version>
+        <hadoop.version>2.7.1</hadoop.version>
+        <curator.version>2.7.1</curator.version>
+        <zookeeper.version>3.4.6</zookeeper.version>
+      </properties>
+    </profile>
+
+    <profile>
+      <!-- hadoop 2.7.1 -->
+      <id>release-2.7</id>
+      <properties>
+        <hadoop.version>2.7.1</hadoop.version>
+        <curator.version>2.7.1</curator.version>
+        <zookeeper.version>3.4.6</zookeeper.version>
       </properties>
     </profile>
 
     <profile>
       <!-- hadoop branch-2 builds  -->
-      <id>branch-2</id>
+      <id>branch-2.8</id>
       <properties>
         <hadoop.version>2.8.0-SNAPSHOT</hadoop.version>
+        <curator.version>2.7.1</curator.version>
+        <zookeeper.version>3.4.6</zookeeper.version>
+      </properties>
+    </profile>
+    
+    <profile>
+      <!-- hadoop branch-2 builds  -->
+      <id>branch-2</id>
+      <properties>
+        <hadoop.version>2.9.0-SNAPSHOT</hadoop.version>
+        <curator.version>2.7.1</curator.version>
+        <zookeeper.version>3.4.6</zookeeper.version>
       </properties>
     </profile>
     
@@ -1654,6 +1732,8 @@
       <id>trunk</id>
       <properties>
         <hadoop.version>3.0.0-SNAPSHOT</hadoop.version>
+        <curator.version>2.7.1</curator.version>
+        <zookeeper.version>3.4.6</zookeeper.version>
       </properties>
     </profile>
 
diff --git a/slider-agent/pom.xml b/slider-agent/pom.xml
index c494b77..009a864 100644
--- a/slider-agent/pom.xml
+++ b/slider-agent/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.apache.slider</groupId>
     <artifactId>slider</artifactId>
-    <version>0.81.0-incubating-SNAPSHOT</version>
+    <version>0.90.0-incubating-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <artifactId>slider-agent</artifactId>
diff --git a/slider-assembly/pom.xml b/slider-assembly/pom.xml
index 24f8bf4..0f7340f 100644
--- a/slider-assembly/pom.xml
+++ b/slider-assembly/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.slider</groupId>
     <artifactId>slider</artifactId>
-    <version>0.81.0-incubating-SNAPSHOT</version>
+    <version>0.90.0-incubating-SNAPSHOT</version>
   </parent>
 
 
diff --git a/slider-assembly/src/conf/slider-client.xml b/slider-assembly/src/conf/slider-client.xml
index 3a42bee..9c2e76d 100644
--- a/slider-assembly/src/conf/slider-client.xml
+++ b/slider-assembly/src/conf/slider-client.xml
@@ -22,14 +22,6 @@
 -->
 <configuration>
 
-  <!--
-     The recommended approach is to configure slider-env.sh and set HADOOP_CONF_DIR.
-     Otherwise, appropriate configurations from hdfs-site, yarn-site, can be dropped in this file
-     for Slider client to work. The following list is not an exhaustive list but the minimal config
-     needed to interact with a non-secure cluster.
-  -->
-
-  <!--
     <property>
       <name>slider.client.resource.origin</name>
       <value>conf/slider-client.xml</value>
@@ -37,14 +29,41 @@
     </property>
 
     <property>
-      <name>yarn.log-aggregation-enable</name>
-      <value>true</value>
+      <name>slider.security.protocol.acl</name>
+      <value>*</value>
+      <description>When security is enabled, set appropriate acl. Default value means allow everyone.</description>
     </property>
 
     <property>
-        <name>slider.security.protocol.acl</name>
-      <value>*</value>
-      <description>When security is enabled, set appropriate acl. Default value means allow everyone.</description>
+      <name>slider.yarn.queue</name>
+      <value/>
+      <description>the name of the YARN queue to use.</description>
+    </property>
+
+    <property>
+      <name>slider.yarn.queue.priority</name>
+      <value>1</value>
+      <description>the priority of the application.</description>
+    </property>
+
+    <property>
+      <name>slider.am.login.keytab.required</name>
+      <value>false</value>
+      <description>Declare that a keytab must be provided.</description>
+    </property>
+
+  <!--
+   The recommended approach is to configure slider-env.sh and set HADOOP_CONF_DIR.
+   Otherwise, appropriate configurations from hdfs-site, yarn-site, can be dropped in this file
+   for Slider client to work. The following list is not an exhaustive list but the minimal config
+   needed to interact with a non-secure cluster.
+  -->
+
+  <!--
+
+    <property>
+      <name>yarn.log-aggregation-enable</name>
+      <value>true</value>
     </property>
 
     <property>
diff --git a/slider-core/pom.xml b/slider-core/pom.xml
index bea32e4..c7e8933 100644
--- a/slider-core/pom.xml
+++ b/slider-core/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.slider</groupId>
     <artifactId>slider</artifactId>
-    <version>0.81.0-incubating-SNAPSHOT</version>
+    <version>0.90.0-incubating-SNAPSHOT</version>
   </parent>
 
   <build>
@@ -225,6 +225,7 @@
     <dependency>
       <groupId>org.codehaus.groovy</groupId>
       <artifactId>groovy-all</artifactId>
+      <classifier>indy</classifier>
       <scope>test</scope>
     </dependency>
 
@@ -258,6 +259,19 @@
       <scope>compile</scope>
     </dependency>
 
+<!-- if the move to hadoop-hdfs-client JAR causes problems insert this
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-hdfs</artifactId>
+      <scope>compile</scope>
+    </dependency>
+-->
+
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-hdfs</artifactId>
+    </dependency>
+
     <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-yarn-client</artifactId>
@@ -369,6 +383,14 @@
       <artifactId>curator-framework</artifactId>
     </dependency>
 
+    <!-- not directly needed by the registry, but inserted to
+        retain control over which version is on the classpath.
+        Otherwise, slider-core gets the version Hadoop-common depends on -->
+    <dependency>
+      <groupId>org.apache.curator</groupId>
+      <artifactId>curator-recipes</artifactId>
+    </dependency>
+
     <dependency>
       <groupId>org.apache.zookeeper</groupId>
       <artifactId>zookeeper</artifactId>
@@ -506,7 +528,6 @@
     <dependency>
       <groupId>asm</groupId>
       <artifactId>asm</artifactId>
-      <version>3.3.1</version>
     </dependency>
 
   </dependencies>
diff --git a/slider-core/src/license/THIRD-PARTY.properties b/slider-core/src/license/THIRD-PARTY.properties
index 662fde5..1abd56e 100644
--- a/slider-core/src/license/THIRD-PARTY.properties
+++ b/slider-core/src/license/THIRD-PARTY.properties
@@ -10,6 +10,7 @@
 # - Common Public License Version 1.0
 # - Eclipse Public License - Version 1.0
 # - GNU Lesser General Public License (LGPL), Version 2.1
+# - GNU Lesser General Public License, Version 2.1
 # - GPL2 w/ CPE
 # - MIT License
 # - MPL 1.1
@@ -24,8 +25,7 @@
 # Please fill the missing licenses for dependencies :
 #
 #
-#Mon Jan 26 15:27:00 GMT 2015
-asm--asm--3.1=The BSD 3-Clause License
+#Thu Oct 15 16:45:02 EDT 2015
 commons-beanutils--commons-beanutils--1.7.0=The Apache Software License, Version 2.0
 javax.servlet--servlet-api--2.5=CDDL License
 javax.servlet.jsp--jsp-api--2.1=CDDL License
diff --git a/slider-core/src/main/java/org/apache/slider/api/ClusterDescription.java b/slider-core/src/main/java/org/apache/slider/api/ClusterDescription.java
index 025bd32..8358491 100644
--- a/slider-core/src/main/java/org/apache/slider/api/ClusterDescription.java
+++ b/slider-core/src/main/java/org/apache/slider/api/ClusterDescription.java
@@ -65,6 +65,12 @@
  * As a wire format it is less efficient in both xfer and ser/deser than 
  * a binary format, but by having one unified format for wire and persistence,
  * the code paths are simplified.
+ *
+ * This was the original single-file specification/model used in the Hoya
+ * precursor to Slider. Its now retained primarily as a way to publish
+ * the current state of the application, or at least a fraction thereof ...
+ * the larger set of information from the REST API is beyond the scope of
+ * this structure.
  */
 @JsonIgnoreProperties(ignoreUnknown = true)
 @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@@ -165,41 +171,35 @@
    * cluster-specific options -to control both
    * the Slider AM and the application that it deploys
    */
-  public Map<String, String> options =
-    new HashMap<String, String>();
+  public Map<String, String> options = new HashMap<>();
 
   /**
    * cluster information
    * This is only valid when querying the cluster status.
    */
-  public Map<String, String> info =
-    new HashMap<String, String>();
+  public Map<String, String> info = new HashMap<>();
 
   /**
    * Statistics. This is only relevant when querying the cluster status
    */
-  public Map<String, Map<String, Integer>> statistics =
-    new HashMap<String, Map<String, Integer>>();
+  public Map<String, Map<String, Integer>> statistics = new HashMap<>();
 
   /**
    * Instances: role->count
    */
-  public Map<String, List<String>> instances =
-    new HashMap<String, List<String>>();
+  public Map<String, List<String>> instances = new HashMap<>();
 
   /**
    * Role options, 
    * role -> option -> value
    */
-  public Map<String, Map<String, String>> roles =
-    new HashMap<String, Map<String, String>>();
+  public Map<String, Map<String, String>> roles = new HashMap<>();
 
 
   /**
    * List of key-value pairs to add to a client config to set up the client
    */
-  public Map<String, String> clientProperties =
-    new HashMap<String, String>();
+  public Map<String, String> clientProperties = new HashMap<>();
 
   /**
    * Status information
@@ -218,7 +218,6 @@
   public ClusterDescription() {
   }
 
-
   @Override
   public String toString() {
     try {
@@ -284,8 +283,8 @@
    * @param dataOutputStream an outout stream that will always be closed
    * @throws IOException any failure
    */
-  private void writeJsonAsBytes(DataOutputStream dataOutputStream) throws
-                                                                   IOException {
+  private void writeJsonAsBytes(DataOutputStream dataOutputStream)
+      throws IOException {
     try {
       String json = toJsonString();
       byte[] b = json.getBytes(UTF_8);
@@ -303,7 +302,7 @@
    * @throws IOException IO problems
    */
   public static ClusterDescription load(FileSystem fs, Path path)
-    throws IOException, JsonParseException, JsonMappingException {
+      throws IOException, JsonParseException, JsonMappingException {
     FileStatus status = fs.getFileStatus(path);
     byte[] b = new byte[(int) status.getLen()];
     FSDataInputStream dataInputStream = fs.open(path);
@@ -389,7 +388,7 @@
     try {
       return mapper.readValue(jsonFile, ClusterDescription.class);
     } catch (IOException e) {
-      log.error("Exception while parsing json file {}: {}" , jsonFile, e);
+      log.error("Exception while parsing json file {}" , jsonFile, e);
       throw e;
     }
   }
@@ -528,20 +527,20 @@
     }
     String val = roleopts.get(option);
     if (val == null) {
-      throw new BadConfigException("Missing option '%s' in role %s ", option,
-                                   role);
+      throw new BadConfigException("Missing option '%s' in role %s ", option, role);
     }
     return val;
   }
-    /**
+
+  /**
    * Get a mandatory integer role option
    * @param role role to get from
    * @param option option name
    * @return resolved value
    * @throws BadConfigException if the option is not defined
    */
-  public int getMandatoryRoleOptInt(String role, String option) throws
-                                                                BadConfigException {
+  public int getMandatoryRoleOptInt(String role, String option)
+      throws BadConfigException {
     getMandatoryRoleOpt(role, option);
     return getRoleOptInt(role, option, 0);
   }
@@ -564,7 +563,7 @@
   public Map<String, String> getOrAddRole(String role) {
     Map<String, String> map = getRole(role);
     if (map == null) {
-      map = new HashMap<String, String>();
+      map = new HashMap<>();
     }
     roles.put(role, map);
     return map;
@@ -575,7 +574,7 @@
    */
   @JsonIgnore
   public Set<String> getRoleNames() {
-    return new HashSet<String>(roles.keySet());
+    return new HashSet<>(roles.keySet());
   }
 
   /**
diff --git a/slider-core/src/main/java/org/apache/slider/api/ClusterDescriptionOperations.java b/slider-core/src/main/java/org/apache/slider/api/ClusterDescriptionOperations.java
index 21ece2b..5b95414 100644
--- a/slider-core/src/main/java/org/apache/slider/api/ClusterDescriptionOperations.java
+++ b/slider-core/src/main/java/org/apache/slider/api/ClusterDescriptionOperations.java
@@ -80,8 +80,7 @@
   }
 
   private static void mergeInComponentMap(ClusterDescription cd,
-                                          ConfTree confTree
-                                          ) {
+                                          ConfTree confTree) {
 
     Map<String, Map<String, String>> components = confTree.components;
     for (Map.Entry<String, Map<String, String>> compEntry : components.entrySet()) {
diff --git a/slider-core/src/main/java/org/apache/slider/api/ClusterNode.java b/slider-core/src/main/java/org/apache/slider/api/ClusterNode.java
index 2608cd7..d255db0 100644
--- a/slider-core/src/main/java/org/apache/slider/api/ClusterNode.java
+++ b/slider-core/src/main/java/org/apache/slider/api/ClusterNode.java
@@ -38,11 +38,11 @@
 @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL )
 public final class ClusterNode implements Cloneable {
   protected static final Logger
-    LOG = LoggerFactory.getLogger(ClusterDescription.class);
+    LOG = LoggerFactory.getLogger(ClusterNode.class);
   
   @JsonIgnore
   public ContainerId containerId;
-  
+
   /**
    * server name
    */
@@ -67,8 +67,7 @@
   public boolean released;
   public String host;
   public String hostUrl;
-  
-  
+
   /**
    * state from {@link ClusterDescription}
    */
@@ -165,7 +164,7 @@
     try {
       return mapper.readValue(json, ClusterNode.class);
     } catch (IOException e) {
-      LOG.error("Exception while parsing json : " + e + "\n" + json, e);
+      LOG.error("Exception while parsing json : {}\n{}", e , json, e);
       throw e;
     }
   }
diff --git a/slider-core/src/main/java/org/apache/slider/api/ResourceKeys.java b/slider-core/src/main/java/org/apache/slider/api/ResourceKeys.java
index f481c6a..f92a58d 100644
--- a/slider-core/src/main/java/org/apache/slider/api/ResourceKeys.java
+++ b/slider-core/src/main/java/org/apache/slider/api/ResourceKeys.java
@@ -167,4 +167,16 @@
    */
   String YARN_LOG_INCLUDE_PATTERNS = "yarn.log.include.patterns";
   String YARN_LOG_EXCLUDE_PATTERNS = "yarn.log.exclude.patterns";
+
+  /**
+   * Window of time where application master's failure count
+   * can be reset to 0.
+   */
+  String YARN_RESOURCEMANAGER_AM_RETRY_COUNT_WINDOW_MS  =
+      "yarn.resourcemanager.am.retry-count-window-ms";
+
+  /**
+   * The default window for Slider.
+   */
+  long DEFAULT_AM_RETRY_COUNT_WINDOW_MS = 300000;
 }
diff --git a/slider-core/src/main/java/org/apache/slider/api/RoleKeys.java b/slider-core/src/main/java/org/apache/slider/api/RoleKeys.java
index 4512354..eda01ad 100644
--- a/slider-core/src/main/java/org/apache/slider/api/RoleKeys.java
+++ b/slider-core/src/main/java/org/apache/slider/api/RoleKeys.java
@@ -65,6 +65,11 @@
   String ROLE_PREEMPTED_INSTANCES = "role.failed.preempted.instances";
 
   /**
+   * Number of pending anti-affine instances: {@value}
+   */
+  String ROLE_PENDING_AA_INSTANCES = "role.pending.aa.instances";
+
+  /**
    * Status report: number currently being released: {@value} 
    */
   String ROLE_FAILED_STARTING_INSTANCES = "role.failed.starting.instances";
@@ -98,19 +103,4 @@
    */
   String ENV_PREFIX = "env.";
 
-
-  /**
-   * Default no. of cores in the AM {@value}
-   */
-  int DEFAULT_AM_V_CORES = 1;
-  
-  /**
-   * The default memory of the AM:  {@value}
-   */
-  int DEFAULT_AM_MEMORY = 1024;
-
-  /**
-   * The default heap of the AM:  {@value}
-   */
-  String DEFAULT_AM_HEAP = "512M";
 }
diff --git a/slider-core/src/main/java/org/apache/slider/api/SliderApplicationApi.java b/slider-core/src/main/java/org/apache/slider/api/SliderApplicationApi.java
index 7de1915..d21785f 100644
--- a/slider-core/src/main/java/org/apache/slider/api/SliderApplicationApi.java
+++ b/slider-core/src/main/java/org/apache/slider/api/SliderApplicationApi.java
@@ -21,6 +21,8 @@
 import org.apache.slider.api.types.ApplicationLivenessInformation;
 import org.apache.slider.api.types.ComponentInformation;
 import org.apache.slider.api.types.ContainerInformation;
+import org.apache.slider.api.types.NodeInformation;
+import org.apache.slider.api.types.NodeInformationList;
 import org.apache.slider.api.types.PingInformation;
 import org.apache.slider.core.conf.AggregateConf;
 import org.apache.slider.core.conf.ConfTree;
@@ -36,7 +38,7 @@
   /**
    * Get the aggregate desired model
    * @return the aggregate configuration of what was asked for
-   * —before resolution has taken place
+   * -before resolution has taken place
    * @throws IOException on any failure
    */
   AggregateConf getDesiredModel() throws IOException;
@@ -44,7 +46,7 @@
   /**
    * Get the desired application configuration
    * @return the application configuration asked for
-   * —before resolution has taken place
+   * -before resolution has taken place
    * @throws IOException on any failure
    */
   ConfTreeOperations getDesiredAppconf() throws IOException;
@@ -52,7 +54,7 @@
   /**
    * Get the desired YARN resources
    * @return the resources asked for
-   * —before resolution has taken place
+   * -before resolution has taken place
    * @throws IOException on any failure
    */
   ConfTreeOperations getDesiredResources() throws IOException;
@@ -68,7 +70,7 @@
   /**
    * Get the aggregate resolved model
    * @return the aggregate configuration of what was asked for
-   * —after resolution has taken place
+   * -after resolution has taken place
    * @throws IOException on any failure
    */
   AggregateConf getResolvedModel() throws IOException;
@@ -76,7 +78,7 @@
   /**
    * Get the resolved application configuration
    * @return the application configuration asked for
-   * —after resolution has taken place
+   * -after resolution has taken place
    * @throws IOException on any failure
    */
   ConfTreeOperations getResolvedAppconf() throws IOException;
@@ -84,7 +86,7 @@
   /**
    * Get the resolved YARN resources
    * @return the resources asked for
-   * —after resolution has taken place
+   * -after resolution has taken place
    * @throws IOException on any failure
    */
   ConfTreeOperations getResolvedResources() throws IOException;
@@ -101,8 +103,7 @@
    * @return a possibly empty list of serialized containers
    * @throws IOException on any failure
    */
-  Map<String, ContainerInformation> enumContainers() throws
-      IOException;
+  Map<String, ContainerInformation> enumContainers() throws IOException;
 
   /**
    * Get a container from the container Id
@@ -110,16 +111,14 @@
    * @return the container information
    * @throws IOException on any failure
    */
-  ContainerInformation getContainer(String containerId) throws
-      IOException;
+  ContainerInformation getContainer(String containerId) throws IOException;
 
   /**
    * List all components into a map of [name:info]
    * @return a possibly empty map of components
    * @throws IOException on any failure
    */
-  Map<String, ComponentInformation> enumComponents() throws
-      IOException;
+  Map<String, ComponentInformation> enumComponents() throws IOException;
 
   /**
    * Get information about a component
@@ -127,8 +126,22 @@
    * @return the component details
    * @throws IOException on any failure
    */
-  ComponentInformation getComponent(String componentName) throws
-      IOException;
+  ComponentInformation getComponent(String componentName) throws IOException;
+
+  /**
+   * List all nodes into a map of [name:info]
+   * @return a possibly empty list of nodes
+   * @throws IOException on any failure
+   */
+  NodeInformationList getLiveNodes() throws IOException;
+
+  /**
+   * Get information about a node
+   * @param hostname name of the node
+   * @return the node details
+   * @throws IOException on any failure
+   */
+  NodeInformation getLiveNode(String hostname) throws IOException;
 
   /**
    * Ping as a GET
diff --git a/slider-core/src/main/java/org/apache/slider/api/SliderClusterProtocol.java b/slider-core/src/main/java/org/apache/slider/api/SliderClusterProtocol.java
index 910521e..33fce22 100644
--- a/slider-core/src/main/java/org/apache/slider/api/SliderClusterProtocol.java
+++ b/slider-core/src/main/java/org/apache/slider/api/SliderClusterProtocol.java
@@ -30,8 +30,7 @@
  * Cluster protocol. This can currently act as a versioned IPC
  * endpoint or be relayed via protobuf
  */
-@KerberosInfo(
-  serverPrincipal = SliderXmlConfKeys.KEY_KERBEROS_PRINCIPAL)
+@KerberosInfo(serverPrincipal = SliderXmlConfKeys.KEY_KERBEROS_PRINCIPAL)
 public interface SliderClusterProtocol extends VersionedProtocol {
   long versionID = 0x01;
 
@@ -39,10 +38,8 @@
    * Stop the cluster
    */
 
-  
   Messages.StopClusterResponseProto stopCluster(Messages.StopClusterRequestProto request) throws
                                                                                           IOException, YarnException;
-
   /**
    * Upgrade the application containers
    * 
@@ -155,20 +152,26 @@
       Messages.GetLiveComponentRequestProto request
   ) throws IOException;
 
-  
+  Messages.GetLiveNodesResponseProto getLiveNodes(
+      Messages.GetLiveNodesRequestProto request
+  ) throws IOException;
+
+  Messages.NodeInformationProto getLiveNode(
+      Messages.GetLiveNodeRequestProto request
+  ) throws IOException;
+
   Messages.WrappedJsonProto getModelDesired(Messages.EmptyPayloadProto request) throws IOException;
 
-  
   Messages.WrappedJsonProto getModelDesiredAppconf(Messages.EmptyPayloadProto request) throws IOException;
-    
+
   Messages.WrappedJsonProto getModelDesiredResources(Messages.EmptyPayloadProto request) throws IOException;
-   
+
   Messages.WrappedJsonProto getModelResolved(Messages.EmptyPayloadProto request) throws IOException;
-  
+
   Messages.WrappedJsonProto getModelResolvedAppconf(Messages.EmptyPayloadProto request) throws IOException;
-  
+
   Messages.WrappedJsonProto getModelResolvedResources(Messages.EmptyPayloadProto request) throws IOException;
-   
+
   Messages.WrappedJsonProto getLiveResources(Messages.EmptyPayloadProto request) throws IOException;
 
   Messages.GetCertificateStoreResponseProto getClientCertificateStore(Messages.GetCertificateStoreRequestProto request)
diff --git a/slider-core/src/main/java/org/apache/slider/api/StatusKeys.java b/slider-core/src/main/java/org/apache/slider/api/StatusKeys.java
index 6a0a2fa..8a2c4bb 100644
--- a/slider-core/src/main/java/org/apache/slider/api/StatusKeys.java
+++ b/slider-core/src/main/java/org/apache/slider/api/StatusKeys.java
@@ -32,6 +32,7 @@
   String STATISTICS_CONTAINERS_PREEMPTED = "containers.failed.preempted";
   String STATISTICS_CONTAINERS_LIVE = "containers.live";
   String STATISTICS_CONTAINERS_REQUESTED = "containers.requested";
+  String STATISTICS_CONTAINERS_ANTI_AFFINE_PENDING = "containers.anti-affine.pending";
   String STATISTICS_CONTAINERS_STARTED = "containers.start.started";
   String STATISTICS_CONTAINERS_START_FAILED =
       "containers.start.failed";
diff --git a/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java b/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java
index 6c92f46..373d64d 100644
--- a/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java
+++ b/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java
@@ -15100,6 +15100,26 @@
      * <code>optional int32 preempted = 17;</code>
      */
     int getPreempted();
+
+    // optional int32 pendingAntiAffineRequestCount = 18;
+    /**
+     * <code>optional int32 pendingAntiAffineRequestCount = 18;</code>
+     */
+    boolean hasPendingAntiAffineRequestCount();
+    /**
+     * <code>optional int32 pendingAntiAffineRequestCount = 18;</code>
+     */
+    int getPendingAntiAffineRequestCount();
+
+    // optional bool isAARequestOutstanding = 19;
+    /**
+     * <code>optional bool isAARequestOutstanding = 19;</code>
+     */
+    boolean hasIsAARequestOutstanding();
+    /**
+     * <code>optional bool isAARequestOutstanding = 19;</code>
+     */
+    boolean getIsAARequestOutstanding();
   }
   /**
    * Protobuf type {@code org.apache.slider.api.ComponentInformationProto}
@@ -15245,6 +15265,16 @@
               preempted_ = input.readInt32();
               break;
             }
+            case 144: {
+              bitField0_ |= 0x00010000;
+              pendingAntiAffineRequestCount_ = input.readInt32();
+              break;
+            }
+            case 152: {
+              bitField0_ |= 0x00020000;
+              isAARequestOutstanding_ = input.readBool();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -15628,6 +15658,38 @@
       return preempted_;
     }
 
+    // optional int32 pendingAntiAffineRequestCount = 18;
+    public static final int PENDINGANTIAFFINEREQUESTCOUNT_FIELD_NUMBER = 18;
+    private int pendingAntiAffineRequestCount_;
+    /**
+     * <code>optional int32 pendingAntiAffineRequestCount = 18;</code>
+     */
+    public boolean hasPendingAntiAffineRequestCount() {
+      return ((bitField0_ & 0x00010000) == 0x00010000);
+    }
+    /**
+     * <code>optional int32 pendingAntiAffineRequestCount = 18;</code>
+     */
+    public int getPendingAntiAffineRequestCount() {
+      return pendingAntiAffineRequestCount_;
+    }
+
+    // optional bool isAARequestOutstanding = 19;
+    public static final int ISAAREQUESTOUTSTANDING_FIELD_NUMBER = 19;
+    private boolean isAARequestOutstanding_;
+    /**
+     * <code>optional bool isAARequestOutstanding = 19;</code>
+     */
+    public boolean hasIsAARequestOutstanding() {
+      return ((bitField0_ & 0x00020000) == 0x00020000);
+    }
+    /**
+     * <code>optional bool isAARequestOutstanding = 19;</code>
+     */
+    public boolean getIsAARequestOutstanding() {
+      return isAARequestOutstanding_;
+    }
+
     private void initFields() {
       name_ = "";
       priority_ = 0;
@@ -15646,6 +15708,8 @@
       failedRecently_ = 0;
       nodeFailed_ = 0;
       preempted_ = 0;
+      pendingAntiAffineRequestCount_ = 0;
+      isAARequestOutstanding_ = false;
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -15710,6 +15774,12 @@
       if (((bitField0_ & 0x00008000) == 0x00008000)) {
         output.writeInt32(17, preempted_);
       }
+      if (((bitField0_ & 0x00010000) == 0x00010000)) {
+        output.writeInt32(18, pendingAntiAffineRequestCount_);
+      }
+      if (((bitField0_ & 0x00020000) == 0x00020000)) {
+        output.writeBool(19, isAARequestOutstanding_);
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -15792,6 +15862,14 @@
         size += com.google.protobuf.CodedOutputStream
           .computeInt32Size(17, preempted_);
       }
+      if (((bitField0_ & 0x00010000) == 0x00010000)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(18, pendingAntiAffineRequestCount_);
+      }
+      if (((bitField0_ & 0x00020000) == 0x00020000)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(19, isAARequestOutstanding_);
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -15897,6 +15975,16 @@
         result = result && (getPreempted()
             == other.getPreempted());
       }
+      result = result && (hasPendingAntiAffineRequestCount() == other.hasPendingAntiAffineRequestCount());
+      if (hasPendingAntiAffineRequestCount()) {
+        result = result && (getPendingAntiAffineRequestCount()
+            == other.getPendingAntiAffineRequestCount());
+      }
+      result = result && (hasIsAARequestOutstanding() == other.hasIsAARequestOutstanding());
+      if (hasIsAARequestOutstanding()) {
+        result = result && (getIsAARequestOutstanding()
+            == other.getIsAARequestOutstanding());
+      }
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -15978,6 +16066,14 @@
         hash = (37 * hash) + PREEMPTED_FIELD_NUMBER;
         hash = (53 * hash) + getPreempted();
       }
+      if (hasPendingAntiAffineRequestCount()) {
+        hash = (37 * hash) + PENDINGANTIAFFINEREQUESTCOUNT_FIELD_NUMBER;
+        hash = (53 * hash) + getPendingAntiAffineRequestCount();
+      }
+      if (hasIsAARequestOutstanding()) {
+        hash = (37 * hash) + ISAAREQUESTOUTSTANDING_FIELD_NUMBER;
+        hash = (53 * hash) + hashBoolean(getIsAARequestOutstanding());
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -16126,6 +16222,10 @@
         bitField0_ = (bitField0_ & ~0x00008000);
         preempted_ = 0;
         bitField0_ = (bitField0_ & ~0x00010000);
+        pendingAntiAffineRequestCount_ = 0;
+        bitField0_ = (bitField0_ & ~0x00020000);
+        isAARequestOutstanding_ = false;
+        bitField0_ = (bitField0_ & ~0x00040000);
         return this;
       }
 
@@ -16224,6 +16324,14 @@
           to_bitField0_ |= 0x00008000;
         }
         result.preempted_ = preempted_;
+        if (((from_bitField0_ & 0x00020000) == 0x00020000)) {
+          to_bitField0_ |= 0x00010000;
+        }
+        result.pendingAntiAffineRequestCount_ = pendingAntiAffineRequestCount_;
+        if (((from_bitField0_ & 0x00040000) == 0x00040000)) {
+          to_bitField0_ |= 0x00020000;
+        }
+        result.isAARequestOutstanding_ = isAARequestOutstanding_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -16302,6 +16410,12 @@
         if (other.hasPreempted()) {
           setPreempted(other.getPreempted());
         }
+        if (other.hasPendingAntiAffineRequestCount()) {
+          setPendingAntiAffineRequestCount(other.getPendingAntiAffineRequestCount());
+        }
+        if (other.hasIsAARequestOutstanding()) {
+          setIsAARequestOutstanding(other.getIsAARequestOutstanding());
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -17032,6 +17146,72 @@
         return this;
       }
 
+      // optional int32 pendingAntiAffineRequestCount = 18;
+      private int pendingAntiAffineRequestCount_ ;
+      /**
+       * <code>optional int32 pendingAntiAffineRequestCount = 18;</code>
+       */
+      public boolean hasPendingAntiAffineRequestCount() {
+        return ((bitField0_ & 0x00020000) == 0x00020000);
+      }
+      /**
+       * <code>optional int32 pendingAntiAffineRequestCount = 18;</code>
+       */
+      public int getPendingAntiAffineRequestCount() {
+        return pendingAntiAffineRequestCount_;
+      }
+      /**
+       * <code>optional int32 pendingAntiAffineRequestCount = 18;</code>
+       */
+      public Builder setPendingAntiAffineRequestCount(int value) {
+        bitField0_ |= 0x00020000;
+        pendingAntiAffineRequestCount_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int32 pendingAntiAffineRequestCount = 18;</code>
+       */
+      public Builder clearPendingAntiAffineRequestCount() {
+        bitField0_ = (bitField0_ & ~0x00020000);
+        pendingAntiAffineRequestCount_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // optional bool isAARequestOutstanding = 19;
+      private boolean isAARequestOutstanding_ ;
+      /**
+       * <code>optional bool isAARequestOutstanding = 19;</code>
+       */
+      public boolean hasIsAARequestOutstanding() {
+        return ((bitField0_ & 0x00040000) == 0x00040000);
+      }
+      /**
+       * <code>optional bool isAARequestOutstanding = 19;</code>
+       */
+      public boolean getIsAARequestOutstanding() {
+        return isAARequestOutstanding_;
+      }
+      /**
+       * <code>optional bool isAARequestOutstanding = 19;</code>
+       */
+      public Builder setIsAARequestOutstanding(boolean value) {
+        bitField0_ |= 0x00040000;
+        isAARequestOutstanding_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool isAARequestOutstanding = 19;</code>
+       */
+      public Builder clearIsAARequestOutstanding() {
+        bitField0_ = (bitField0_ & ~0x00040000);
+        isAARequestOutstanding_ = false;
+        onChanged();
+        return this;
+      }
+
       // @@protoc_insertion_point(builder_scope:org.apache.slider.api.ComponentInformationProto)
     }
 
@@ -20132,6 +20312,3363 @@
     // @@protoc_insertion_point(class_scope:org.apache.slider.api.PingInformationProto)
   }
 
+  public interface NodeEntryInformationProtoOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required int32 priority = 1;
+    /**
+     * <code>required int32 priority = 1;</code>
+     */
+    boolean hasPriority();
+    /**
+     * <code>required int32 priority = 1;</code>
+     */
+    int getPriority();
+
+    // required int32 requested = 2;
+    /**
+     * <code>required int32 requested = 2;</code>
+     */
+    boolean hasRequested();
+    /**
+     * <code>required int32 requested = 2;</code>
+     */
+    int getRequested();
+
+    // required int32 starting = 3;
+    /**
+     * <code>required int32 starting = 3;</code>
+     */
+    boolean hasStarting();
+    /**
+     * <code>required int32 starting = 3;</code>
+     */
+    int getStarting();
+
+    // required int32 startFailed = 4;
+    /**
+     * <code>required int32 startFailed = 4;</code>
+     */
+    boolean hasStartFailed();
+    /**
+     * <code>required int32 startFailed = 4;</code>
+     */
+    int getStartFailed();
+
+    // required int32 failed = 5;
+    /**
+     * <code>required int32 failed = 5;</code>
+     */
+    boolean hasFailed();
+    /**
+     * <code>required int32 failed = 5;</code>
+     */
+    int getFailed();
+
+    // required int32 failedRecently = 6;
+    /**
+     * <code>required int32 failedRecently = 6;</code>
+     */
+    boolean hasFailedRecently();
+    /**
+     * <code>required int32 failedRecently = 6;</code>
+     */
+    int getFailedRecently();
+
+    // required int32 preempted = 7;
+    /**
+     * <code>required int32 preempted = 7;</code>
+     */
+    boolean hasPreempted();
+    /**
+     * <code>required int32 preempted = 7;</code>
+     */
+    int getPreempted();
+
+    // required int32 live = 8;
+    /**
+     * <code>required int32 live = 8;</code>
+     */
+    boolean hasLive();
+    /**
+     * <code>required int32 live = 8;</code>
+     */
+    int getLive();
+
+    // required int32 releasing = 9;
+    /**
+     * <code>required int32 releasing = 9;</code>
+     */
+    boolean hasReleasing();
+    /**
+     * <code>required int32 releasing = 9;</code>
+     */
+    int getReleasing();
+
+    // required int64 lastUsed = 10;
+    /**
+     * <code>required int64 lastUsed = 10;</code>
+     */
+    boolean hasLastUsed();
+    /**
+     * <code>required int64 lastUsed = 10;</code>
+     */
+    long getLastUsed();
+
+    // required string name = 11;
+    /**
+     * <code>required string name = 11;</code>
+     */
+    boolean hasName();
+    /**
+     * <code>required string name = 11;</code>
+     */
+    java.lang.String getName();
+    /**
+     * <code>required string name = 11;</code>
+     */
+    com.google.protobuf.ByteString
+        getNameBytes();
+  }
+  /**
+   * Protobuf type {@code org.apache.slider.api.NodeEntryInformationProto}
+   */
+  public static final class NodeEntryInformationProto extends
+      com.google.protobuf.GeneratedMessage
+      implements NodeEntryInformationProtoOrBuilder {
+    // Use NodeEntryInformationProto.newBuilder() to construct.
+    private NodeEntryInformationProto(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private NodeEntryInformationProto(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final NodeEntryInformationProto defaultInstance;
+    public static NodeEntryInformationProto getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public NodeEntryInformationProto getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private NodeEntryInformationProto(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              priority_ = input.readInt32();
+              break;
+            }
+            case 16: {
+              bitField0_ |= 0x00000002;
+              requested_ = input.readInt32();
+              break;
+            }
+            case 24: {
+              bitField0_ |= 0x00000004;
+              starting_ = input.readInt32();
+              break;
+            }
+            case 32: {
+              bitField0_ |= 0x00000008;
+              startFailed_ = input.readInt32();
+              break;
+            }
+            case 40: {
+              bitField0_ |= 0x00000010;
+              failed_ = input.readInt32();
+              break;
+            }
+            case 48: {
+              bitField0_ |= 0x00000020;
+              failedRecently_ = input.readInt32();
+              break;
+            }
+            case 56: {
+              bitField0_ |= 0x00000040;
+              preempted_ = input.readInt32();
+              break;
+            }
+            case 64: {
+              bitField0_ |= 0x00000080;
+              live_ = input.readInt32();
+              break;
+            }
+            case 72: {
+              bitField0_ |= 0x00000100;
+              releasing_ = input.readInt32();
+              break;
+            }
+            case 80: {
+              bitField0_ |= 0x00000200;
+              lastUsed_ = input.readInt64();
+              break;
+            }
+            case 90: {
+              bitField0_ |= 0x00000400;
+              name_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_NodeEntryInformationProto_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_NodeEntryInformationProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.slider.api.proto.Messages.NodeEntryInformationProto.class, org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<NodeEntryInformationProto> PARSER =
+        new com.google.protobuf.AbstractParser<NodeEntryInformationProto>() {
+      public NodeEntryInformationProto parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new NodeEntryInformationProto(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<NodeEntryInformationProto> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required int32 priority = 1;
+    public static final int PRIORITY_FIELD_NUMBER = 1;
+    private int priority_;
+    /**
+     * <code>required int32 priority = 1;</code>
+     */
+    public boolean hasPriority() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required int32 priority = 1;</code>
+     */
+    public int getPriority() {
+      return priority_;
+    }
+
+    // required int32 requested = 2;
+    public static final int REQUESTED_FIELD_NUMBER = 2;
+    private int requested_;
+    /**
+     * <code>required int32 requested = 2;</code>
+     */
+    public boolean hasRequested() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required int32 requested = 2;</code>
+     */
+    public int getRequested() {
+      return requested_;
+    }
+
+    // required int32 starting = 3;
+    public static final int STARTING_FIELD_NUMBER = 3;
+    private int starting_;
+    /**
+     * <code>required int32 starting = 3;</code>
+     */
+    public boolean hasStarting() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>required int32 starting = 3;</code>
+     */
+    public int getStarting() {
+      return starting_;
+    }
+
+    // required int32 startFailed = 4;
+    public static final int STARTFAILED_FIELD_NUMBER = 4;
+    private int startFailed_;
+    /**
+     * <code>required int32 startFailed = 4;</code>
+     */
+    public boolean hasStartFailed() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>required int32 startFailed = 4;</code>
+     */
+    public int getStartFailed() {
+      return startFailed_;
+    }
+
+    // required int32 failed = 5;
+    public static final int FAILED_FIELD_NUMBER = 5;
+    private int failed_;
+    /**
+     * <code>required int32 failed = 5;</code>
+     */
+    public boolean hasFailed() {
+      return ((bitField0_ & 0x00000010) == 0x00000010);
+    }
+    /**
+     * <code>required int32 failed = 5;</code>
+     */
+    public int getFailed() {
+      return failed_;
+    }
+
+    // required int32 failedRecently = 6;
+    public static final int FAILEDRECENTLY_FIELD_NUMBER = 6;
+    private int failedRecently_;
+    /**
+     * <code>required int32 failedRecently = 6;</code>
+     */
+    public boolean hasFailedRecently() {
+      return ((bitField0_ & 0x00000020) == 0x00000020);
+    }
+    /**
+     * <code>required int32 failedRecently = 6;</code>
+     */
+    public int getFailedRecently() {
+      return failedRecently_;
+    }
+
+    // required int32 preempted = 7;
+    public static final int PREEMPTED_FIELD_NUMBER = 7;
+    private int preempted_;
+    /**
+     * <code>required int32 preempted = 7;</code>
+     */
+    public boolean hasPreempted() {
+      return ((bitField0_ & 0x00000040) == 0x00000040);
+    }
+    /**
+     * <code>required int32 preempted = 7;</code>
+     */
+    public int getPreempted() {
+      return preempted_;
+    }
+
+    // required int32 live = 8;
+    public static final int LIVE_FIELD_NUMBER = 8;
+    private int live_;
+    /**
+     * <code>required int32 live = 8;</code>
+     */
+    public boolean hasLive() {
+      return ((bitField0_ & 0x00000080) == 0x00000080);
+    }
+    /**
+     * <code>required int32 live = 8;</code>
+     */
+    public int getLive() {
+      return live_;
+    }
+
+    // required int32 releasing = 9;
+    public static final int RELEASING_FIELD_NUMBER = 9;
+    private int releasing_;
+    /**
+     * <code>required int32 releasing = 9;</code>
+     */
+    public boolean hasReleasing() {
+      return ((bitField0_ & 0x00000100) == 0x00000100);
+    }
+    /**
+     * <code>required int32 releasing = 9;</code>
+     */
+    public int getReleasing() {
+      return releasing_;
+    }
+
+    // required int64 lastUsed = 10;
+    public static final int LASTUSED_FIELD_NUMBER = 10;
+    private long lastUsed_;
+    /**
+     * <code>required int64 lastUsed = 10;</code>
+     */
+    public boolean hasLastUsed() {
+      return ((bitField0_ & 0x00000200) == 0x00000200);
+    }
+    /**
+     * <code>required int64 lastUsed = 10;</code>
+     */
+    public long getLastUsed() {
+      return lastUsed_;
+    }
+
+    // required string name = 11;
+    public static final int NAME_FIELD_NUMBER = 11;
+    private java.lang.Object name_;
+    /**
+     * <code>required string name = 11;</code>
+     */
+    public boolean hasName() {
+      return ((bitField0_ & 0x00000400) == 0x00000400);
+    }
+    /**
+     * <code>required string name = 11;</code>
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          name_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string name = 11;</code>
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      priority_ = 0;
+      requested_ = 0;
+      starting_ = 0;
+      startFailed_ = 0;
+      failed_ = 0;
+      failedRecently_ = 0;
+      preempted_ = 0;
+      live_ = 0;
+      releasing_ = 0;
+      lastUsed_ = 0L;
+      name_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasPriority()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasRequested()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasStarting()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasStartFailed()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasFailed()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasFailedRecently()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasPreempted()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasLive()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasReleasing()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasLastUsed()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasName()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeInt32(1, priority_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeInt32(2, requested_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeInt32(3, starting_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeInt32(4, startFailed_);
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        output.writeInt32(5, failed_);
+      }
+      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        output.writeInt32(6, failedRecently_);
+      }
+      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+        output.writeInt32(7, preempted_);
+      }
+      if (((bitField0_ & 0x00000080) == 0x00000080)) {
+        output.writeInt32(8, live_);
+      }
+      if (((bitField0_ & 0x00000100) == 0x00000100)) {
+        output.writeInt32(9, releasing_);
+      }
+      if (((bitField0_ & 0x00000200) == 0x00000200)) {
+        output.writeInt64(10, lastUsed_);
+      }
+      if (((bitField0_ & 0x00000400) == 0x00000400)) {
+        output.writeBytes(11, getNameBytes());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(1, priority_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(2, requested_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(3, starting_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(4, startFailed_);
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(5, failed_);
+      }
+      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(6, failedRecently_);
+      }
+      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(7, preempted_);
+      }
+      if (((bitField0_ & 0x00000080) == 0x00000080)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(8, live_);
+      }
+      if (((bitField0_ & 0x00000100) == 0x00000100)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(9, releasing_);
+      }
+      if (((bitField0_ & 0x00000200) == 0x00000200)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(10, lastUsed_);
+      }
+      if (((bitField0_ & 0x00000400) == 0x00000400)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(11, getNameBytes());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.slider.api.proto.Messages.NodeEntryInformationProto)) {
+        return super.equals(obj);
+      }
+      org.apache.slider.api.proto.Messages.NodeEntryInformationProto other = (org.apache.slider.api.proto.Messages.NodeEntryInformationProto) obj;
+
+      boolean result = true;
+      result = result && (hasPriority() == other.hasPriority());
+      if (hasPriority()) {
+        result = result && (getPriority()
+            == other.getPriority());
+      }
+      result = result && (hasRequested() == other.hasRequested());
+      if (hasRequested()) {
+        result = result && (getRequested()
+            == other.getRequested());
+      }
+      result = result && (hasStarting() == other.hasStarting());
+      if (hasStarting()) {
+        result = result && (getStarting()
+            == other.getStarting());
+      }
+      result = result && (hasStartFailed() == other.hasStartFailed());
+      if (hasStartFailed()) {
+        result = result && (getStartFailed()
+            == other.getStartFailed());
+      }
+      result = result && (hasFailed() == other.hasFailed());
+      if (hasFailed()) {
+        result = result && (getFailed()
+            == other.getFailed());
+      }
+      result = result && (hasFailedRecently() == other.hasFailedRecently());
+      if (hasFailedRecently()) {
+        result = result && (getFailedRecently()
+            == other.getFailedRecently());
+      }
+      result = result && (hasPreempted() == other.hasPreempted());
+      if (hasPreempted()) {
+        result = result && (getPreempted()
+            == other.getPreempted());
+      }
+      result = result && (hasLive() == other.hasLive());
+      if (hasLive()) {
+        result = result && (getLive()
+            == other.getLive());
+      }
+      result = result && (hasReleasing() == other.hasReleasing());
+      if (hasReleasing()) {
+        result = result && (getReleasing()
+            == other.getReleasing());
+      }
+      result = result && (hasLastUsed() == other.hasLastUsed());
+      if (hasLastUsed()) {
+        result = result && (getLastUsed()
+            == other.getLastUsed());
+      }
+      result = result && (hasName() == other.hasName());
+      if (hasName()) {
+        result = result && getName()
+            .equals(other.getName());
+      }
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (hasPriority()) {
+        hash = (37 * hash) + PRIORITY_FIELD_NUMBER;
+        hash = (53 * hash) + getPriority();
+      }
+      if (hasRequested()) {
+        hash = (37 * hash) + REQUESTED_FIELD_NUMBER;
+        hash = (53 * hash) + getRequested();
+      }
+      if (hasStarting()) {
+        hash = (37 * hash) + STARTING_FIELD_NUMBER;
+        hash = (53 * hash) + getStarting();
+      }
+      if (hasStartFailed()) {
+        hash = (37 * hash) + STARTFAILED_FIELD_NUMBER;
+        hash = (53 * hash) + getStartFailed();
+      }
+      if (hasFailed()) {
+        hash = (37 * hash) + FAILED_FIELD_NUMBER;
+        hash = (53 * hash) + getFailed();
+      }
+      if (hasFailedRecently()) {
+        hash = (37 * hash) + FAILEDRECENTLY_FIELD_NUMBER;
+        hash = (53 * hash) + getFailedRecently();
+      }
+      if (hasPreempted()) {
+        hash = (37 * hash) + PREEMPTED_FIELD_NUMBER;
+        hash = (53 * hash) + getPreempted();
+      }
+      if (hasLive()) {
+        hash = (37 * hash) + LIVE_FIELD_NUMBER;
+        hash = (53 * hash) + getLive();
+      }
+      if (hasReleasing()) {
+        hash = (37 * hash) + RELEASING_FIELD_NUMBER;
+        hash = (53 * hash) + getReleasing();
+      }
+      if (hasLastUsed()) {
+        hash = (37 * hash) + LASTUSED_FIELD_NUMBER;
+        hash = (53 * hash) + hashLong(getLastUsed());
+      }
+      if (hasName()) {
+        hash = (37 * hash) + NAME_FIELD_NUMBER;
+        hash = (53 * hash) + getName().hashCode();
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.slider.api.proto.Messages.NodeEntryInformationProto parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeEntryInformationProto parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeEntryInformationProto parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeEntryInformationProto parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeEntryInformationProto parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeEntryInformationProto parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeEntryInformationProto parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeEntryInformationProto parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeEntryInformationProto parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeEntryInformationProto parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.slider.api.proto.Messages.NodeEntryInformationProto prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.apache.slider.api.NodeEntryInformationProto}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.slider.api.proto.Messages.NodeEntryInformationProtoOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_NodeEntryInformationProto_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_NodeEntryInformationProto_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.slider.api.proto.Messages.NodeEntryInformationProto.class, org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder.class);
+      }
+
+      // Construct using org.apache.slider.api.proto.Messages.NodeEntryInformationProto.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        priority_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        requested_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        starting_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        startFailed_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000008);
+        failed_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000010);
+        failedRecently_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000020);
+        preempted_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000040);
+        live_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000080);
+        releasing_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000100);
+        lastUsed_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000200);
+        name_ = "";
+        bitField0_ = (bitField0_ & ~0x00000400);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_NodeEntryInformationProto_descriptor;
+      }
+
+      public org.apache.slider.api.proto.Messages.NodeEntryInformationProto getDefaultInstanceForType() {
+        return org.apache.slider.api.proto.Messages.NodeEntryInformationProto.getDefaultInstance();
+      }
+
+      public org.apache.slider.api.proto.Messages.NodeEntryInformationProto build() {
+        org.apache.slider.api.proto.Messages.NodeEntryInformationProto result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.slider.api.proto.Messages.NodeEntryInformationProto buildPartial() {
+        org.apache.slider.api.proto.Messages.NodeEntryInformationProto result = new org.apache.slider.api.proto.Messages.NodeEntryInformationProto(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.priority_ = priority_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.requested_ = requested_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.starting_ = starting_;
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.startFailed_ = startFailed_;
+        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+          to_bitField0_ |= 0x00000010;
+        }
+        result.failed_ = failed_;
+        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+          to_bitField0_ |= 0x00000020;
+        }
+        result.failedRecently_ = failedRecently_;
+        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
+          to_bitField0_ |= 0x00000040;
+        }
+        result.preempted_ = preempted_;
+        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
+          to_bitField0_ |= 0x00000080;
+        }
+        result.live_ = live_;
+        if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
+          to_bitField0_ |= 0x00000100;
+        }
+        result.releasing_ = releasing_;
+        if (((from_bitField0_ & 0x00000200) == 0x00000200)) {
+          to_bitField0_ |= 0x00000200;
+        }
+        result.lastUsed_ = lastUsed_;
+        if (((from_bitField0_ & 0x00000400) == 0x00000400)) {
+          to_bitField0_ |= 0x00000400;
+        }
+        result.name_ = name_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.slider.api.proto.Messages.NodeEntryInformationProto) {
+          return mergeFrom((org.apache.slider.api.proto.Messages.NodeEntryInformationProto)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.slider.api.proto.Messages.NodeEntryInformationProto other) {
+        if (other == org.apache.slider.api.proto.Messages.NodeEntryInformationProto.getDefaultInstance()) return this;
+        if (other.hasPriority()) {
+          setPriority(other.getPriority());
+        }
+        if (other.hasRequested()) {
+          setRequested(other.getRequested());
+        }
+        if (other.hasStarting()) {
+          setStarting(other.getStarting());
+        }
+        if (other.hasStartFailed()) {
+          setStartFailed(other.getStartFailed());
+        }
+        if (other.hasFailed()) {
+          setFailed(other.getFailed());
+        }
+        if (other.hasFailedRecently()) {
+          setFailedRecently(other.getFailedRecently());
+        }
+        if (other.hasPreempted()) {
+          setPreempted(other.getPreempted());
+        }
+        if (other.hasLive()) {
+          setLive(other.getLive());
+        }
+        if (other.hasReleasing()) {
+          setReleasing(other.getReleasing());
+        }
+        if (other.hasLastUsed()) {
+          setLastUsed(other.getLastUsed());
+        }
+        if (other.hasName()) {
+          bitField0_ |= 0x00000400;
+          name_ = other.name_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasPriority()) {
+          
+          return false;
+        }
+        if (!hasRequested()) {
+          
+          return false;
+        }
+        if (!hasStarting()) {
+          
+          return false;
+        }
+        if (!hasStartFailed()) {
+          
+          return false;
+        }
+        if (!hasFailed()) {
+          
+          return false;
+        }
+        if (!hasFailedRecently()) {
+          
+          return false;
+        }
+        if (!hasPreempted()) {
+          
+          return false;
+        }
+        if (!hasLive()) {
+          
+          return false;
+        }
+        if (!hasReleasing()) {
+          
+          return false;
+        }
+        if (!hasLastUsed()) {
+          
+          return false;
+        }
+        if (!hasName()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.slider.api.proto.Messages.NodeEntryInformationProto parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.slider.api.proto.Messages.NodeEntryInformationProto) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required int32 priority = 1;
+      private int priority_ ;
+      /**
+       * <code>required int32 priority = 1;</code>
+       */
+      public boolean hasPriority() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required int32 priority = 1;</code>
+       */
+      public int getPriority() {
+        return priority_;
+      }
+      /**
+       * <code>required int32 priority = 1;</code>
+       */
+      public Builder setPriority(int value) {
+        bitField0_ |= 0x00000001;
+        priority_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 priority = 1;</code>
+       */
+      public Builder clearPriority() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        priority_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int32 requested = 2;
+      private int requested_ ;
+      /**
+       * <code>required int32 requested = 2;</code>
+       */
+      public boolean hasRequested() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required int32 requested = 2;</code>
+       */
+      public int getRequested() {
+        return requested_;
+      }
+      /**
+       * <code>required int32 requested = 2;</code>
+       */
+      public Builder setRequested(int value) {
+        bitField0_ |= 0x00000002;
+        requested_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 requested = 2;</code>
+       */
+      public Builder clearRequested() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        requested_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int32 starting = 3;
+      private int starting_ ;
+      /**
+       * <code>required int32 starting = 3;</code>
+       */
+      public boolean hasStarting() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required int32 starting = 3;</code>
+       */
+      public int getStarting() {
+        return starting_;
+      }
+      /**
+       * <code>required int32 starting = 3;</code>
+       */
+      public Builder setStarting(int value) {
+        bitField0_ |= 0x00000004;
+        starting_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 starting = 3;</code>
+       */
+      public Builder clearStarting() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        starting_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int32 startFailed = 4;
+      private int startFailed_ ;
+      /**
+       * <code>required int32 startFailed = 4;</code>
+       */
+      public boolean hasStartFailed() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>required int32 startFailed = 4;</code>
+       */
+      public int getStartFailed() {
+        return startFailed_;
+      }
+      /**
+       * <code>required int32 startFailed = 4;</code>
+       */
+      public Builder setStartFailed(int value) {
+        bitField0_ |= 0x00000008;
+        startFailed_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 startFailed = 4;</code>
+       */
+      public Builder clearStartFailed() {
+        bitField0_ = (bitField0_ & ~0x00000008);
+        startFailed_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int32 failed = 5;
+      private int failed_ ;
+      /**
+       * <code>required int32 failed = 5;</code>
+       */
+      public boolean hasFailed() {
+        return ((bitField0_ & 0x00000010) == 0x00000010);
+      }
+      /**
+       * <code>required int32 failed = 5;</code>
+       */
+      public int getFailed() {
+        return failed_;
+      }
+      /**
+       * <code>required int32 failed = 5;</code>
+       */
+      public Builder setFailed(int value) {
+        bitField0_ |= 0x00000010;
+        failed_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 failed = 5;</code>
+       */
+      public Builder clearFailed() {
+        bitField0_ = (bitField0_ & ~0x00000010);
+        failed_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int32 failedRecently = 6;
+      private int failedRecently_ ;
+      /**
+       * <code>required int32 failedRecently = 6;</code>
+       */
+      public boolean hasFailedRecently() {
+        return ((bitField0_ & 0x00000020) == 0x00000020);
+      }
+      /**
+       * <code>required int32 failedRecently = 6;</code>
+       */
+      public int getFailedRecently() {
+        return failedRecently_;
+      }
+      /**
+       * <code>required int32 failedRecently = 6;</code>
+       */
+      public Builder setFailedRecently(int value) {
+        bitField0_ |= 0x00000020;
+        failedRecently_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 failedRecently = 6;</code>
+       */
+      public Builder clearFailedRecently() {
+        bitField0_ = (bitField0_ & ~0x00000020);
+        failedRecently_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int32 preempted = 7;
+      private int preempted_ ;
+      /**
+       * <code>required int32 preempted = 7;</code>
+       */
+      public boolean hasPreempted() {
+        return ((bitField0_ & 0x00000040) == 0x00000040);
+      }
+      /**
+       * <code>required int32 preempted = 7;</code>
+       */
+      public int getPreempted() {
+        return preempted_;
+      }
+      /**
+       * <code>required int32 preempted = 7;</code>
+       */
+      public Builder setPreempted(int value) {
+        bitField0_ |= 0x00000040;
+        preempted_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 preempted = 7;</code>
+       */
+      public Builder clearPreempted() {
+        bitField0_ = (bitField0_ & ~0x00000040);
+        preempted_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int32 live = 8;
+      private int live_ ;
+      /**
+       * <code>required int32 live = 8;</code>
+       */
+      public boolean hasLive() {
+        return ((bitField0_ & 0x00000080) == 0x00000080);
+      }
+      /**
+       * <code>required int32 live = 8;</code>
+       */
+      public int getLive() {
+        return live_;
+      }
+      /**
+       * <code>required int32 live = 8;</code>
+       */
+      public Builder setLive(int value) {
+        bitField0_ |= 0x00000080;
+        live_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 live = 8;</code>
+       */
+      public Builder clearLive() {
+        bitField0_ = (bitField0_ & ~0x00000080);
+        live_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int32 releasing = 9;
+      private int releasing_ ;
+      /**
+       * <code>required int32 releasing = 9;</code>
+       */
+      public boolean hasReleasing() {
+        return ((bitField0_ & 0x00000100) == 0x00000100);
+      }
+      /**
+       * <code>required int32 releasing = 9;</code>
+       */
+      public int getReleasing() {
+        return releasing_;
+      }
+      /**
+       * <code>required int32 releasing = 9;</code>
+       */
+      public Builder setReleasing(int value) {
+        bitField0_ |= 0x00000100;
+        releasing_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 releasing = 9;</code>
+       */
+      public Builder clearReleasing() {
+        bitField0_ = (bitField0_ & ~0x00000100);
+        releasing_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int64 lastUsed = 10;
+      private long lastUsed_ ;
+      /**
+       * <code>required int64 lastUsed = 10;</code>
+       */
+      public boolean hasLastUsed() {
+        return ((bitField0_ & 0x00000200) == 0x00000200);
+      }
+      /**
+       * <code>required int64 lastUsed = 10;</code>
+       */
+      public long getLastUsed() {
+        return lastUsed_;
+      }
+      /**
+       * <code>required int64 lastUsed = 10;</code>
+       */
+      public Builder setLastUsed(long value) {
+        bitField0_ |= 0x00000200;
+        lastUsed_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int64 lastUsed = 10;</code>
+       */
+      public Builder clearLastUsed() {
+        bitField0_ = (bitField0_ & ~0x00000200);
+        lastUsed_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // required string name = 11;
+      private java.lang.Object name_ = "";
+      /**
+       * <code>required string name = 11;</code>
+       */
+      public boolean hasName() {
+        return ((bitField0_ & 0x00000400) == 0x00000400);
+      }
+      /**
+       * <code>required string name = 11;</code>
+       */
+      public java.lang.String getName() {
+        java.lang.Object ref = name_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          name_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string name = 11;</code>
+       */
+      public com.google.protobuf.ByteString
+          getNameBytes() {
+        java.lang.Object ref = name_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          name_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string name = 11;</code>
+       */
+      public Builder setName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000400;
+        name_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string name = 11;</code>
+       */
+      public Builder clearName() {
+        bitField0_ = (bitField0_ & ~0x00000400);
+        name_ = getDefaultInstance().getName();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string name = 11;</code>
+       */
+      public Builder setNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000400;
+        name_ = value;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.apache.slider.api.NodeEntryInformationProto)
+    }
+
+    static {
+      defaultInstance = new NodeEntryInformationProto(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.apache.slider.api.NodeEntryInformationProto)
+  }
+
+  public interface NodeInformationProtoOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string hostname = 1;
+    /**
+     * <code>required string hostname = 1;</code>
+     */
+    boolean hasHostname();
+    /**
+     * <code>required string hostname = 1;</code>
+     */
+    java.lang.String getHostname();
+    /**
+     * <code>required string hostname = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getHostnameBytes();
+
+    // required string state = 2;
+    /**
+     * <code>required string state = 2;</code>
+     */
+    boolean hasState();
+    /**
+     * <code>required string state = 2;</code>
+     */
+    java.lang.String getState();
+    /**
+     * <code>required string state = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getStateBytes();
+
+    // required string httpAddress = 3;
+    /**
+     * <code>required string httpAddress = 3;</code>
+     */
+    boolean hasHttpAddress();
+    /**
+     * <code>required string httpAddress = 3;</code>
+     */
+    java.lang.String getHttpAddress();
+    /**
+     * <code>required string httpAddress = 3;</code>
+     */
+    com.google.protobuf.ByteString
+        getHttpAddressBytes();
+
+    // required string rackName = 4;
+    /**
+     * <code>required string rackName = 4;</code>
+     */
+    boolean hasRackName();
+    /**
+     * <code>required string rackName = 4;</code>
+     */
+    java.lang.String getRackName();
+    /**
+     * <code>required string rackName = 4;</code>
+     */
+    com.google.protobuf.ByteString
+        getRackNameBytes();
+
+    // required string labels = 5;
+    /**
+     * <code>required string labels = 5;</code>
+     */
+    boolean hasLabels();
+    /**
+     * <code>required string labels = 5;</code>
+     */
+    java.lang.String getLabels();
+    /**
+     * <code>required string labels = 5;</code>
+     */
+    com.google.protobuf.ByteString
+        getLabelsBytes();
+
+    // required string healthReport = 6;
+    /**
+     * <code>required string healthReport = 6;</code>
+     */
+    boolean hasHealthReport();
+    /**
+     * <code>required string healthReport = 6;</code>
+     */
+    java.lang.String getHealthReport();
+    /**
+     * <code>required string healthReport = 6;</code>
+     */
+    com.google.protobuf.ByteString
+        getHealthReportBytes();
+
+    // required int64 lastUpdated = 7;
+    /**
+     * <code>required int64 lastUpdated = 7;</code>
+     */
+    boolean hasLastUpdated();
+    /**
+     * <code>required int64 lastUpdated = 7;</code>
+     */
+    long getLastUpdated();
+
+    // repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;
+    /**
+     * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+     */
+    java.util.List<org.apache.slider.api.proto.Messages.NodeEntryInformationProto> 
+        getEntriesList();
+    /**
+     * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+     */
+    org.apache.slider.api.proto.Messages.NodeEntryInformationProto getEntries(int index);
+    /**
+     * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+     */
+    int getEntriesCount();
+    /**
+     * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+     */
+    java.util.List<? extends org.apache.slider.api.proto.Messages.NodeEntryInformationProtoOrBuilder> 
+        getEntriesOrBuilderList();
+    /**
+     * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+     */
+    org.apache.slider.api.proto.Messages.NodeEntryInformationProtoOrBuilder getEntriesOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code org.apache.slider.api.NodeInformationProto}
+   */
+  public static final class NodeInformationProto extends
+      com.google.protobuf.GeneratedMessage
+      implements NodeInformationProtoOrBuilder {
+    // Use NodeInformationProto.newBuilder() to construct.
+    private NodeInformationProto(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private NodeInformationProto(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final NodeInformationProto defaultInstance;
+    public static NodeInformationProto getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public NodeInformationProto getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private NodeInformationProto(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              hostname_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              state_ = input.readBytes();
+              break;
+            }
+            case 26: {
+              bitField0_ |= 0x00000004;
+              httpAddress_ = input.readBytes();
+              break;
+            }
+            case 34: {
+              bitField0_ |= 0x00000008;
+              rackName_ = input.readBytes();
+              break;
+            }
+            case 42: {
+              bitField0_ |= 0x00000010;
+              labels_ = input.readBytes();
+              break;
+            }
+            case 50: {
+              bitField0_ |= 0x00000020;
+              healthReport_ = input.readBytes();
+              break;
+            }
+            case 56: {
+              bitField0_ |= 0x00000040;
+              lastUpdated_ = input.readInt64();
+              break;
+            }
+            case 66: {
+              if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
+                entries_ = new java.util.ArrayList<org.apache.slider.api.proto.Messages.NodeEntryInformationProto>();
+                mutable_bitField0_ |= 0x00000080;
+              }
+              entries_.add(input.readMessage(org.apache.slider.api.proto.Messages.NodeEntryInformationProto.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
+          entries_ = java.util.Collections.unmodifiableList(entries_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_NodeInformationProto_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_NodeInformationProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.slider.api.proto.Messages.NodeInformationProto.class, org.apache.slider.api.proto.Messages.NodeInformationProto.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<NodeInformationProto> PARSER =
+        new com.google.protobuf.AbstractParser<NodeInformationProto>() {
+      public NodeInformationProto parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new NodeInformationProto(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<NodeInformationProto> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string hostname = 1;
+    public static final int HOSTNAME_FIELD_NUMBER = 1;
+    private java.lang.Object hostname_;
+    /**
+     * <code>required string hostname = 1;</code>
+     */
+    public boolean hasHostname() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string hostname = 1;</code>
+     */
+    public java.lang.String getHostname() {
+      java.lang.Object ref = hostname_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          hostname_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string hostname = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getHostnameBytes() {
+      java.lang.Object ref = hostname_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        hostname_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required string state = 2;
+    public static final int STATE_FIELD_NUMBER = 2;
+    private java.lang.Object state_;
+    /**
+     * <code>required string state = 2;</code>
+     */
+    public boolean hasState() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required string state = 2;</code>
+     */
+    public java.lang.String getState() {
+      java.lang.Object ref = state_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          state_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string state = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getStateBytes() {
+      java.lang.Object ref = state_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        state_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required string httpAddress = 3;
+    public static final int HTTPADDRESS_FIELD_NUMBER = 3;
+    private java.lang.Object httpAddress_;
+    /**
+     * <code>required string httpAddress = 3;</code>
+     */
+    public boolean hasHttpAddress() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>required string httpAddress = 3;</code>
+     */
+    public java.lang.String getHttpAddress() {
+      java.lang.Object ref = httpAddress_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          httpAddress_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string httpAddress = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getHttpAddressBytes() {
+      java.lang.Object ref = httpAddress_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        httpAddress_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required string rackName = 4;
+    public static final int RACKNAME_FIELD_NUMBER = 4;
+    private java.lang.Object rackName_;
+    /**
+     * <code>required string rackName = 4;</code>
+     */
+    public boolean hasRackName() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>required string rackName = 4;</code>
+     */
+    public java.lang.String getRackName() {
+      java.lang.Object ref = rackName_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          rackName_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string rackName = 4;</code>
+     */
+    public com.google.protobuf.ByteString
+        getRackNameBytes() {
+      java.lang.Object ref = rackName_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        rackName_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required string labels = 5;
+    public static final int LABELS_FIELD_NUMBER = 5;
+    private java.lang.Object labels_;
+    /**
+     * <code>required string labels = 5;</code>
+     */
+    public boolean hasLabels() {
+      return ((bitField0_ & 0x00000010) == 0x00000010);
+    }
+    /**
+     * <code>required string labels = 5;</code>
+     */
+    public java.lang.String getLabels() {
+      java.lang.Object ref = labels_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          labels_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string labels = 5;</code>
+     */
+    public com.google.protobuf.ByteString
+        getLabelsBytes() {
+      java.lang.Object ref = labels_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        labels_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required string healthReport = 6;
+    public static final int HEALTHREPORT_FIELD_NUMBER = 6;
+    private java.lang.Object healthReport_;
+    /**
+     * <code>required string healthReport = 6;</code>
+     */
+    public boolean hasHealthReport() {
+      return ((bitField0_ & 0x00000020) == 0x00000020);
+    }
+    /**
+     * <code>required string healthReport = 6;</code>
+     */
+    public java.lang.String getHealthReport() {
+      java.lang.Object ref = healthReport_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          healthReport_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string healthReport = 6;</code>
+     */
+    public com.google.protobuf.ByteString
+        getHealthReportBytes() {
+      java.lang.Object ref = healthReport_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        healthReport_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required int64 lastUpdated = 7;
+    public static final int LASTUPDATED_FIELD_NUMBER = 7;
+    private long lastUpdated_;
+    /**
+     * <code>required int64 lastUpdated = 7;</code>
+     */
+    public boolean hasLastUpdated() {
+      return ((bitField0_ & 0x00000040) == 0x00000040);
+    }
+    /**
+     * <code>required int64 lastUpdated = 7;</code>
+     */
+    public long getLastUpdated() {
+      return lastUpdated_;
+    }
+
+    // repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;
+    public static final int ENTRIES_FIELD_NUMBER = 8;
+    private java.util.List<org.apache.slider.api.proto.Messages.NodeEntryInformationProto> entries_;
+    /**
+     * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+     */
+    public java.util.List<org.apache.slider.api.proto.Messages.NodeEntryInformationProto> getEntriesList() {
+      return entries_;
+    }
+    /**
+     * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+     */
+    public java.util.List<? extends org.apache.slider.api.proto.Messages.NodeEntryInformationProtoOrBuilder> 
+        getEntriesOrBuilderList() {
+      return entries_;
+    }
+    /**
+     * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+     */
+    public int getEntriesCount() {
+      return entries_.size();
+    }
+    /**
+     * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+     */
+    public org.apache.slider.api.proto.Messages.NodeEntryInformationProto getEntries(int index) {
+      return entries_.get(index);
+    }
+    /**
+     * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+     */
+    public org.apache.slider.api.proto.Messages.NodeEntryInformationProtoOrBuilder getEntriesOrBuilder(
+        int index) {
+      return entries_.get(index);
+    }
+
+    private void initFields() {
+      hostname_ = "";
+      state_ = "";
+      httpAddress_ = "";
+      rackName_ = "";
+      labels_ = "";
+      healthReport_ = "";
+      lastUpdated_ = 0L;
+      entries_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasHostname()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasState()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasHttpAddress()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasRackName()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasLabels()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasHealthReport()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasLastUpdated()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      for (int i = 0; i < getEntriesCount(); i++) {
+        if (!getEntries(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getHostnameBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getStateBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeBytes(3, getHttpAddressBytes());
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeBytes(4, getRackNameBytes());
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        output.writeBytes(5, getLabelsBytes());
+      }
+      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        output.writeBytes(6, getHealthReportBytes());
+      }
+      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+        output.writeInt64(7, lastUpdated_);
+      }
+      for (int i = 0; i < entries_.size(); i++) {
+        output.writeMessage(8, entries_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getHostnameBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, getStateBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(3, getHttpAddressBytes());
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(4, getRackNameBytes());
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(5, getLabelsBytes());
+      }
+      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(6, getHealthReportBytes());
+      }
+      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(7, lastUpdated_);
+      }
+      for (int i = 0; i < entries_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(8, entries_.get(i));
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.slider.api.proto.Messages.NodeInformationProto)) {
+        return super.equals(obj);
+      }
+      org.apache.slider.api.proto.Messages.NodeInformationProto other = (org.apache.slider.api.proto.Messages.NodeInformationProto) obj;
+
+      boolean result = true;
+      result = result && (hasHostname() == other.hasHostname());
+      if (hasHostname()) {
+        result = result && getHostname()
+            .equals(other.getHostname());
+      }
+      result = result && (hasState() == other.hasState());
+      if (hasState()) {
+        result = result && getState()
+            .equals(other.getState());
+      }
+      result = result && (hasHttpAddress() == other.hasHttpAddress());
+      if (hasHttpAddress()) {
+        result = result && getHttpAddress()
+            .equals(other.getHttpAddress());
+      }
+      result = result && (hasRackName() == other.hasRackName());
+      if (hasRackName()) {
+        result = result && getRackName()
+            .equals(other.getRackName());
+      }
+      result = result && (hasLabels() == other.hasLabels());
+      if (hasLabels()) {
+        result = result && getLabels()
+            .equals(other.getLabels());
+      }
+      result = result && (hasHealthReport() == other.hasHealthReport());
+      if (hasHealthReport()) {
+        result = result && getHealthReport()
+            .equals(other.getHealthReport());
+      }
+      result = result && (hasLastUpdated() == other.hasLastUpdated());
+      if (hasLastUpdated()) {
+        result = result && (getLastUpdated()
+            == other.getLastUpdated());
+      }
+      result = result && getEntriesList()
+          .equals(other.getEntriesList());
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (hasHostname()) {
+        hash = (37 * hash) + HOSTNAME_FIELD_NUMBER;
+        hash = (53 * hash) + getHostname().hashCode();
+      }
+      if (hasState()) {
+        hash = (37 * hash) + STATE_FIELD_NUMBER;
+        hash = (53 * hash) + getState().hashCode();
+      }
+      if (hasHttpAddress()) {
+        hash = (37 * hash) + HTTPADDRESS_FIELD_NUMBER;
+        hash = (53 * hash) + getHttpAddress().hashCode();
+      }
+      if (hasRackName()) {
+        hash = (37 * hash) + RACKNAME_FIELD_NUMBER;
+        hash = (53 * hash) + getRackName().hashCode();
+      }
+      if (hasLabels()) {
+        hash = (37 * hash) + LABELS_FIELD_NUMBER;
+        hash = (53 * hash) + getLabels().hashCode();
+      }
+      if (hasHealthReport()) {
+        hash = (37 * hash) + HEALTHREPORT_FIELD_NUMBER;
+        hash = (53 * hash) + getHealthReport().hashCode();
+      }
+      if (hasLastUpdated()) {
+        hash = (37 * hash) + LASTUPDATED_FIELD_NUMBER;
+        hash = (53 * hash) + hashLong(getLastUpdated());
+      }
+      if (getEntriesCount() > 0) {
+        hash = (37 * hash) + ENTRIES_FIELD_NUMBER;
+        hash = (53 * hash) + getEntriesList().hashCode();
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.slider.api.proto.Messages.NodeInformationProto parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeInformationProto parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeInformationProto parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeInformationProto parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeInformationProto parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeInformationProto parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeInformationProto parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeInformationProto parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeInformationProto parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.NodeInformationProto parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.slider.api.proto.Messages.NodeInformationProto prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.apache.slider.api.NodeInformationProto}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.slider.api.proto.Messages.NodeInformationProtoOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_NodeInformationProto_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_NodeInformationProto_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.slider.api.proto.Messages.NodeInformationProto.class, org.apache.slider.api.proto.Messages.NodeInformationProto.Builder.class);
+      }
+
+      // Construct using org.apache.slider.api.proto.Messages.NodeInformationProto.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getEntriesFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        hostname_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        state_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        httpAddress_ = "";
+        bitField0_ = (bitField0_ & ~0x00000004);
+        rackName_ = "";
+        bitField0_ = (bitField0_ & ~0x00000008);
+        labels_ = "";
+        bitField0_ = (bitField0_ & ~0x00000010);
+        healthReport_ = "";
+        bitField0_ = (bitField0_ & ~0x00000020);
+        lastUpdated_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000040);
+        if (entriesBuilder_ == null) {
+          entries_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000080);
+        } else {
+          entriesBuilder_.clear();
+        }
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_NodeInformationProto_descriptor;
+      }
+
+      public org.apache.slider.api.proto.Messages.NodeInformationProto getDefaultInstanceForType() {
+        return org.apache.slider.api.proto.Messages.NodeInformationProto.getDefaultInstance();
+      }
+
+      public org.apache.slider.api.proto.Messages.NodeInformationProto build() {
+        org.apache.slider.api.proto.Messages.NodeInformationProto result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.slider.api.proto.Messages.NodeInformationProto buildPartial() {
+        org.apache.slider.api.proto.Messages.NodeInformationProto result = new org.apache.slider.api.proto.Messages.NodeInformationProto(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.hostname_ = hostname_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.state_ = state_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.httpAddress_ = httpAddress_;
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.rackName_ = rackName_;
+        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+          to_bitField0_ |= 0x00000010;
+        }
+        result.labels_ = labels_;
+        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+          to_bitField0_ |= 0x00000020;
+        }
+        result.healthReport_ = healthReport_;
+        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
+          to_bitField0_ |= 0x00000040;
+        }
+        result.lastUpdated_ = lastUpdated_;
+        if (entriesBuilder_ == null) {
+          if (((bitField0_ & 0x00000080) == 0x00000080)) {
+            entries_ = java.util.Collections.unmodifiableList(entries_);
+            bitField0_ = (bitField0_ & ~0x00000080);
+          }
+          result.entries_ = entries_;
+        } else {
+          result.entries_ = entriesBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.slider.api.proto.Messages.NodeInformationProto) {
+          return mergeFrom((org.apache.slider.api.proto.Messages.NodeInformationProto)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.slider.api.proto.Messages.NodeInformationProto other) {
+        if (other == org.apache.slider.api.proto.Messages.NodeInformationProto.getDefaultInstance()) return this;
+        if (other.hasHostname()) {
+          bitField0_ |= 0x00000001;
+          hostname_ = other.hostname_;
+          onChanged();
+        }
+        if (other.hasState()) {
+          bitField0_ |= 0x00000002;
+          state_ = other.state_;
+          onChanged();
+        }
+        if (other.hasHttpAddress()) {
+          bitField0_ |= 0x00000004;
+          httpAddress_ = other.httpAddress_;
+          onChanged();
+        }
+        if (other.hasRackName()) {
+          bitField0_ |= 0x00000008;
+          rackName_ = other.rackName_;
+          onChanged();
+        }
+        if (other.hasLabels()) {
+          bitField0_ |= 0x00000010;
+          labels_ = other.labels_;
+          onChanged();
+        }
+        if (other.hasHealthReport()) {
+          bitField0_ |= 0x00000020;
+          healthReport_ = other.healthReport_;
+          onChanged();
+        }
+        if (other.hasLastUpdated()) {
+          setLastUpdated(other.getLastUpdated());
+        }
+        if (entriesBuilder_ == null) {
+          if (!other.entries_.isEmpty()) {
+            if (entries_.isEmpty()) {
+              entries_ = other.entries_;
+              bitField0_ = (bitField0_ & ~0x00000080);
+            } else {
+              ensureEntriesIsMutable();
+              entries_.addAll(other.entries_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.entries_.isEmpty()) {
+            if (entriesBuilder_.isEmpty()) {
+              entriesBuilder_.dispose();
+              entriesBuilder_ = null;
+              entries_ = other.entries_;
+              bitField0_ = (bitField0_ & ~0x00000080);
+              entriesBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getEntriesFieldBuilder() : null;
+            } else {
+              entriesBuilder_.addAllMessages(other.entries_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasHostname()) {
+          
+          return false;
+        }
+        if (!hasState()) {
+          
+          return false;
+        }
+        if (!hasHttpAddress()) {
+          
+          return false;
+        }
+        if (!hasRackName()) {
+          
+          return false;
+        }
+        if (!hasLabels()) {
+          
+          return false;
+        }
+        if (!hasHealthReport()) {
+          
+          return false;
+        }
+        if (!hasLastUpdated()) {
+          
+          return false;
+        }
+        for (int i = 0; i < getEntriesCount(); i++) {
+          if (!getEntries(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.slider.api.proto.Messages.NodeInformationProto parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.slider.api.proto.Messages.NodeInformationProto) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string hostname = 1;
+      private java.lang.Object hostname_ = "";
+      /**
+       * <code>required string hostname = 1;</code>
+       */
+      public boolean hasHostname() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string hostname = 1;</code>
+       */
+      public java.lang.String getHostname() {
+        java.lang.Object ref = hostname_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          hostname_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string hostname = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getHostnameBytes() {
+        java.lang.Object ref = hostname_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          hostname_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string hostname = 1;</code>
+       */
+      public Builder setHostname(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        hostname_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string hostname = 1;</code>
+       */
+      public Builder clearHostname() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        hostname_ = getDefaultInstance().getHostname();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string hostname = 1;</code>
+       */
+      public Builder setHostnameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        hostname_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required string state = 2;
+      private java.lang.Object state_ = "";
+      /**
+       * <code>required string state = 2;</code>
+       */
+      public boolean hasState() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required string state = 2;</code>
+       */
+      public java.lang.String getState() {
+        java.lang.Object ref = state_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          state_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string state = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getStateBytes() {
+        java.lang.Object ref = state_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          state_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string state = 2;</code>
+       */
+      public Builder setState(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        state_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string state = 2;</code>
+       */
+      public Builder clearState() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        state_ = getDefaultInstance().getState();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string state = 2;</code>
+       */
+      public Builder setStateBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        state_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required string httpAddress = 3;
+      private java.lang.Object httpAddress_ = "";
+      /**
+       * <code>required string httpAddress = 3;</code>
+       */
+      public boolean hasHttpAddress() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required string httpAddress = 3;</code>
+       */
+      public java.lang.String getHttpAddress() {
+        java.lang.Object ref = httpAddress_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          httpAddress_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string httpAddress = 3;</code>
+       */
+      public com.google.protobuf.ByteString
+          getHttpAddressBytes() {
+        java.lang.Object ref = httpAddress_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          httpAddress_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string httpAddress = 3;</code>
+       */
+      public Builder setHttpAddress(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        httpAddress_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string httpAddress = 3;</code>
+       */
+      public Builder clearHttpAddress() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        httpAddress_ = getDefaultInstance().getHttpAddress();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string httpAddress = 3;</code>
+       */
+      public Builder setHttpAddressBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        httpAddress_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required string rackName = 4;
+      private java.lang.Object rackName_ = "";
+      /**
+       * <code>required string rackName = 4;</code>
+       */
+      public boolean hasRackName() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>required string rackName = 4;</code>
+       */
+      public java.lang.String getRackName() {
+        java.lang.Object ref = rackName_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          rackName_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string rackName = 4;</code>
+       */
+      public com.google.protobuf.ByteString
+          getRackNameBytes() {
+        java.lang.Object ref = rackName_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          rackName_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string rackName = 4;</code>
+       */
+      public Builder setRackName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000008;
+        rackName_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string rackName = 4;</code>
+       */
+      public Builder clearRackName() {
+        bitField0_ = (bitField0_ & ~0x00000008);
+        rackName_ = getDefaultInstance().getRackName();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string rackName = 4;</code>
+       */
+      public Builder setRackNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000008;
+        rackName_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required string labels = 5;
+      private java.lang.Object labels_ = "";
+      /**
+       * <code>required string labels = 5;</code>
+       */
+      public boolean hasLabels() {
+        return ((bitField0_ & 0x00000010) == 0x00000010);
+      }
+      /**
+       * <code>required string labels = 5;</code>
+       */
+      public java.lang.String getLabels() {
+        java.lang.Object ref = labels_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          labels_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string labels = 5;</code>
+       */
+      public com.google.protobuf.ByteString
+          getLabelsBytes() {
+        java.lang.Object ref = labels_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          labels_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string labels = 5;</code>
+       */
+      public Builder setLabels(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000010;
+        labels_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string labels = 5;</code>
+       */
+      public Builder clearLabels() {
+        bitField0_ = (bitField0_ & ~0x00000010);
+        labels_ = getDefaultInstance().getLabels();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string labels = 5;</code>
+       */
+      public Builder setLabelsBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000010;
+        labels_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required string healthReport = 6;
+      private java.lang.Object healthReport_ = "";
+      /**
+       * <code>required string healthReport = 6;</code>
+       */
+      public boolean hasHealthReport() {
+        return ((bitField0_ & 0x00000020) == 0x00000020);
+      }
+      /**
+       * <code>required string healthReport = 6;</code>
+       */
+      public java.lang.String getHealthReport() {
+        java.lang.Object ref = healthReport_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          healthReport_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string healthReport = 6;</code>
+       */
+      public com.google.protobuf.ByteString
+          getHealthReportBytes() {
+        java.lang.Object ref = healthReport_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          healthReport_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string healthReport = 6;</code>
+       */
+      public Builder setHealthReport(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000020;
+        healthReport_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string healthReport = 6;</code>
+       */
+      public Builder clearHealthReport() {
+        bitField0_ = (bitField0_ & ~0x00000020);
+        healthReport_ = getDefaultInstance().getHealthReport();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string healthReport = 6;</code>
+       */
+      public Builder setHealthReportBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000020;
+        healthReport_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required int64 lastUpdated = 7;
+      private long lastUpdated_ ;
+      /**
+       * <code>required int64 lastUpdated = 7;</code>
+       */
+      public boolean hasLastUpdated() {
+        return ((bitField0_ & 0x00000040) == 0x00000040);
+      }
+      /**
+       * <code>required int64 lastUpdated = 7;</code>
+       */
+      public long getLastUpdated() {
+        return lastUpdated_;
+      }
+      /**
+       * <code>required int64 lastUpdated = 7;</code>
+       */
+      public Builder setLastUpdated(long value) {
+        bitField0_ |= 0x00000040;
+        lastUpdated_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int64 lastUpdated = 7;</code>
+       */
+      public Builder clearLastUpdated() {
+        bitField0_ = (bitField0_ & ~0x00000040);
+        lastUpdated_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;
+      private java.util.List<org.apache.slider.api.proto.Messages.NodeEntryInformationProto> entries_ =
+        java.util.Collections.emptyList();
+      private void ensureEntriesIsMutable() {
+        if (!((bitField0_ & 0x00000080) == 0x00000080)) {
+          entries_ = new java.util.ArrayList<org.apache.slider.api.proto.Messages.NodeEntryInformationProto>(entries_);
+          bitField0_ |= 0x00000080;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.slider.api.proto.Messages.NodeEntryInformationProto, org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder, org.apache.slider.api.proto.Messages.NodeEntryInformationProtoOrBuilder> entriesBuilder_;
+
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public java.util.List<org.apache.slider.api.proto.Messages.NodeEntryInformationProto> getEntriesList() {
+        if (entriesBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(entries_);
+        } else {
+          return entriesBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public int getEntriesCount() {
+        if (entriesBuilder_ == null) {
+          return entries_.size();
+        } else {
+          return entriesBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public org.apache.slider.api.proto.Messages.NodeEntryInformationProto getEntries(int index) {
+        if (entriesBuilder_ == null) {
+          return entries_.get(index);
+        } else {
+          return entriesBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public Builder setEntries(
+          int index, org.apache.slider.api.proto.Messages.NodeEntryInformationProto value) {
+        if (entriesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureEntriesIsMutable();
+          entries_.set(index, value);
+          onChanged();
+        } else {
+          entriesBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public Builder setEntries(
+          int index, org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder builderForValue) {
+        if (entriesBuilder_ == null) {
+          ensureEntriesIsMutable();
+          entries_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          entriesBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public Builder addEntries(org.apache.slider.api.proto.Messages.NodeEntryInformationProto value) {
+        if (entriesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureEntriesIsMutable();
+          entries_.add(value);
+          onChanged();
+        } else {
+          entriesBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public Builder addEntries(
+          int index, org.apache.slider.api.proto.Messages.NodeEntryInformationProto value) {
+        if (entriesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureEntriesIsMutable();
+          entries_.add(index, value);
+          onChanged();
+        } else {
+          entriesBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public Builder addEntries(
+          org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder builderForValue) {
+        if (entriesBuilder_ == null) {
+          ensureEntriesIsMutable();
+          entries_.add(builderForValue.build());
+          onChanged();
+        } else {
+          entriesBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public Builder addEntries(
+          int index, org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder builderForValue) {
+        if (entriesBuilder_ == null) {
+          ensureEntriesIsMutable();
+          entries_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          entriesBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public Builder addAllEntries(
+          java.lang.Iterable<? extends org.apache.slider.api.proto.Messages.NodeEntryInformationProto> values) {
+        if (entriesBuilder_ == null) {
+          ensureEntriesIsMutable();
+          super.addAll(values, entries_);
+          onChanged();
+        } else {
+          entriesBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public Builder clearEntries() {
+        if (entriesBuilder_ == null) {
+          entries_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000080);
+          onChanged();
+        } else {
+          entriesBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public Builder removeEntries(int index) {
+        if (entriesBuilder_ == null) {
+          ensureEntriesIsMutable();
+          entries_.remove(index);
+          onChanged();
+        } else {
+          entriesBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder getEntriesBuilder(
+          int index) {
+        return getEntriesFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public org.apache.slider.api.proto.Messages.NodeEntryInformationProtoOrBuilder getEntriesOrBuilder(
+          int index) {
+        if (entriesBuilder_ == null) {
+          return entries_.get(index);  } else {
+          return entriesBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public java.util.List<? extends org.apache.slider.api.proto.Messages.NodeEntryInformationProtoOrBuilder> 
+           getEntriesOrBuilderList() {
+        if (entriesBuilder_ != null) {
+          return entriesBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(entries_);
+        }
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder addEntriesBuilder() {
+        return getEntriesFieldBuilder().addBuilder(
+            org.apache.slider.api.proto.Messages.NodeEntryInformationProto.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder addEntriesBuilder(
+          int index) {
+        return getEntriesFieldBuilder().addBuilder(
+            index, org.apache.slider.api.proto.Messages.NodeEntryInformationProto.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeEntryInformationProto entries = 8;</code>
+       */
+      public java.util.List<org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder> 
+           getEntriesBuilderList() {
+        return getEntriesFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.slider.api.proto.Messages.NodeEntryInformationProto, org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder, org.apache.slider.api.proto.Messages.NodeEntryInformationProtoOrBuilder> 
+          getEntriesFieldBuilder() {
+        if (entriesBuilder_ == null) {
+          entriesBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.apache.slider.api.proto.Messages.NodeEntryInformationProto, org.apache.slider.api.proto.Messages.NodeEntryInformationProto.Builder, org.apache.slider.api.proto.Messages.NodeEntryInformationProtoOrBuilder>(
+                  entries_,
+                  ((bitField0_ & 0x00000080) == 0x00000080),
+                  getParentForChildren(),
+                  isClean());
+          entries_ = null;
+        }
+        return entriesBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.apache.slider.api.NodeInformationProto)
+    }
+
+    static {
+      defaultInstance = new NodeInformationProto(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.apache.slider.api.NodeInformationProto)
+  }
+
   public interface GetModelRequestProtoOrBuilder
       extends com.google.protobuf.MessageOrBuilder {
   }
@@ -28684,6 +32221,1582 @@
     // @@protoc_insertion_point(class_scope:org.apache.slider.api.GetCertificateStoreResponseProto)
   }
 
+  public interface GetLiveNodesRequestProtoOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code org.apache.slider.api.GetLiveNodesRequestProto}
+   */
+  public static final class GetLiveNodesRequestProto extends
+      com.google.protobuf.GeneratedMessage
+      implements GetLiveNodesRequestProtoOrBuilder {
+    // Use GetLiveNodesRequestProto.newBuilder() to construct.
+    private GetLiveNodesRequestProto(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private GetLiveNodesRequestProto(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final GetLiveNodesRequestProto defaultInstance;
+    public static GetLiveNodesRequestProto getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public GetLiveNodesRequestProto getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private GetLiveNodesRequestProto(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodesRequestProto_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodesRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto.class, org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<GetLiveNodesRequestProto> PARSER =
+        new com.google.protobuf.AbstractParser<GetLiveNodesRequestProto>() {
+      public GetLiveNodesRequestProto parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new GetLiveNodesRequestProto(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<GetLiveNodesRequestProto> getParserForType() {
+      return PARSER;
+    }
+
+    private void initFields() {
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto)) {
+        return super.equals(obj);
+      }
+      org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto other = (org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto) obj;
+
+      boolean result = true;
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.apache.slider.api.GetLiveNodesRequestProto}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.slider.api.proto.Messages.GetLiveNodesRequestProtoOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodesRequestProto_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodesRequestProto_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto.class, org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto.Builder.class);
+      }
+
+      // Construct using org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodesRequestProto_descriptor;
+      }
+
+      public org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto getDefaultInstanceForType() {
+        return org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto.getDefaultInstance();
+      }
+
+      public org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto build() {
+        org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto buildPartial() {
+        org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto result = new org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto) {
+          return mergeFrom((org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto other) {
+        if (other == org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.apache.slider.api.GetLiveNodesRequestProto)
+    }
+
+    static {
+      defaultInstance = new GetLiveNodesRequestProto(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.apache.slider.api.GetLiveNodesRequestProto)
+  }
+
+  public interface GetLiveNodesResponseProtoOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated .org.apache.slider.api.NodeInformationProto nodes = 1;
+    /**
+     * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+     */
+    java.util.List<org.apache.slider.api.proto.Messages.NodeInformationProto> 
+        getNodesList();
+    /**
+     * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+     */
+    org.apache.slider.api.proto.Messages.NodeInformationProto getNodes(int index);
+    /**
+     * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+     */
+    int getNodesCount();
+    /**
+     * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+     */
+    java.util.List<? extends org.apache.slider.api.proto.Messages.NodeInformationProtoOrBuilder> 
+        getNodesOrBuilderList();
+    /**
+     * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+     */
+    org.apache.slider.api.proto.Messages.NodeInformationProtoOrBuilder getNodesOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code org.apache.slider.api.GetLiveNodesResponseProto}
+   */
+  public static final class GetLiveNodesResponseProto extends
+      com.google.protobuf.GeneratedMessage
+      implements GetLiveNodesResponseProtoOrBuilder {
+    // Use GetLiveNodesResponseProto.newBuilder() to construct.
+    private GetLiveNodesResponseProto(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private GetLiveNodesResponseProto(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final GetLiveNodesResponseProto defaultInstance;
+    public static GetLiveNodesResponseProto getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public GetLiveNodesResponseProto getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private GetLiveNodesResponseProto(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                nodes_ = new java.util.ArrayList<org.apache.slider.api.proto.Messages.NodeInformationProto>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              nodes_.add(input.readMessage(org.apache.slider.api.proto.Messages.NodeInformationProto.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          nodes_ = java.util.Collections.unmodifiableList(nodes_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodesResponseProto_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodesResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.class, org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<GetLiveNodesResponseProto> PARSER =
+        new com.google.protobuf.AbstractParser<GetLiveNodesResponseProto>() {
+      public GetLiveNodesResponseProto parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new GetLiveNodesResponseProto(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<GetLiveNodesResponseProto> getParserForType() {
+      return PARSER;
+    }
+
+    // repeated .org.apache.slider.api.NodeInformationProto nodes = 1;
+    public static final int NODES_FIELD_NUMBER = 1;
+    private java.util.List<org.apache.slider.api.proto.Messages.NodeInformationProto> nodes_;
+    /**
+     * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+     */
+    public java.util.List<org.apache.slider.api.proto.Messages.NodeInformationProto> getNodesList() {
+      return nodes_;
+    }
+    /**
+     * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+     */
+    public java.util.List<? extends org.apache.slider.api.proto.Messages.NodeInformationProtoOrBuilder> 
+        getNodesOrBuilderList() {
+      return nodes_;
+    }
+    /**
+     * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+     */
+    public int getNodesCount() {
+      return nodes_.size();
+    }
+    /**
+     * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+     */
+    public org.apache.slider.api.proto.Messages.NodeInformationProto getNodes(int index) {
+      return nodes_.get(index);
+    }
+    /**
+     * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+     */
+    public org.apache.slider.api.proto.Messages.NodeInformationProtoOrBuilder getNodesOrBuilder(
+        int index) {
+      return nodes_.get(index);
+    }
+
+    private void initFields() {
+      nodes_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      for (int i = 0; i < getNodesCount(); i++) {
+        if (!getNodes(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < nodes_.size(); i++) {
+        output.writeMessage(1, nodes_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < nodes_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, nodes_.get(i));
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto)) {
+        return super.equals(obj);
+      }
+      org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto other = (org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto) obj;
+
+      boolean result = true;
+      result = result && getNodesList()
+          .equals(other.getNodesList());
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (getNodesCount() > 0) {
+        hash = (37 * hash) + NODES_FIELD_NUMBER;
+        hash = (53 * hash) + getNodesList().hashCode();
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.apache.slider.api.GetLiveNodesResponseProto}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.slider.api.proto.Messages.GetLiveNodesResponseProtoOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodesResponseProto_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodesResponseProto_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.class, org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.Builder.class);
+      }
+
+      // Construct using org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getNodesFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (nodesBuilder_ == null) {
+          nodes_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          nodesBuilder_.clear();
+        }
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodesResponseProto_descriptor;
+      }
+
+      public org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto getDefaultInstanceForType() {
+        return org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.getDefaultInstance();
+      }
+
+      public org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto build() {
+        org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto buildPartial() {
+        org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto result = new org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto(this);
+        int from_bitField0_ = bitField0_;
+        if (nodesBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            nodes_ = java.util.Collections.unmodifiableList(nodes_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.nodes_ = nodes_;
+        } else {
+          result.nodes_ = nodesBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto) {
+          return mergeFrom((org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto other) {
+        if (other == org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.getDefaultInstance()) return this;
+        if (nodesBuilder_ == null) {
+          if (!other.nodes_.isEmpty()) {
+            if (nodes_.isEmpty()) {
+              nodes_ = other.nodes_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureNodesIsMutable();
+              nodes_.addAll(other.nodes_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.nodes_.isEmpty()) {
+            if (nodesBuilder_.isEmpty()) {
+              nodesBuilder_.dispose();
+              nodesBuilder_ = null;
+              nodes_ = other.nodes_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              nodesBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getNodesFieldBuilder() : null;
+            } else {
+              nodesBuilder_.addAllMessages(other.nodes_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        for (int i = 0; i < getNodesCount(); i++) {
+          if (!getNodes(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated .org.apache.slider.api.NodeInformationProto nodes = 1;
+      private java.util.List<org.apache.slider.api.proto.Messages.NodeInformationProto> nodes_ =
+        java.util.Collections.emptyList();
+      private void ensureNodesIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          nodes_ = new java.util.ArrayList<org.apache.slider.api.proto.Messages.NodeInformationProto>(nodes_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.slider.api.proto.Messages.NodeInformationProto, org.apache.slider.api.proto.Messages.NodeInformationProto.Builder, org.apache.slider.api.proto.Messages.NodeInformationProtoOrBuilder> nodesBuilder_;
+
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public java.util.List<org.apache.slider.api.proto.Messages.NodeInformationProto> getNodesList() {
+        if (nodesBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(nodes_);
+        } else {
+          return nodesBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public int getNodesCount() {
+        if (nodesBuilder_ == null) {
+          return nodes_.size();
+        } else {
+          return nodesBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public org.apache.slider.api.proto.Messages.NodeInformationProto getNodes(int index) {
+        if (nodesBuilder_ == null) {
+          return nodes_.get(index);
+        } else {
+          return nodesBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public Builder setNodes(
+          int index, org.apache.slider.api.proto.Messages.NodeInformationProto value) {
+        if (nodesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureNodesIsMutable();
+          nodes_.set(index, value);
+          onChanged();
+        } else {
+          nodesBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public Builder setNodes(
+          int index, org.apache.slider.api.proto.Messages.NodeInformationProto.Builder builderForValue) {
+        if (nodesBuilder_ == null) {
+          ensureNodesIsMutable();
+          nodes_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          nodesBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public Builder addNodes(org.apache.slider.api.proto.Messages.NodeInformationProto value) {
+        if (nodesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureNodesIsMutable();
+          nodes_.add(value);
+          onChanged();
+        } else {
+          nodesBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public Builder addNodes(
+          int index, org.apache.slider.api.proto.Messages.NodeInformationProto value) {
+        if (nodesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureNodesIsMutable();
+          nodes_.add(index, value);
+          onChanged();
+        } else {
+          nodesBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public Builder addNodes(
+          org.apache.slider.api.proto.Messages.NodeInformationProto.Builder builderForValue) {
+        if (nodesBuilder_ == null) {
+          ensureNodesIsMutable();
+          nodes_.add(builderForValue.build());
+          onChanged();
+        } else {
+          nodesBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public Builder addNodes(
+          int index, org.apache.slider.api.proto.Messages.NodeInformationProto.Builder builderForValue) {
+        if (nodesBuilder_ == null) {
+          ensureNodesIsMutable();
+          nodes_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          nodesBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public Builder addAllNodes(
+          java.lang.Iterable<? extends org.apache.slider.api.proto.Messages.NodeInformationProto> values) {
+        if (nodesBuilder_ == null) {
+          ensureNodesIsMutable();
+          super.addAll(values, nodes_);
+          onChanged();
+        } else {
+          nodesBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public Builder clearNodes() {
+        if (nodesBuilder_ == null) {
+          nodes_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          nodesBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public Builder removeNodes(int index) {
+        if (nodesBuilder_ == null) {
+          ensureNodesIsMutable();
+          nodes_.remove(index);
+          onChanged();
+        } else {
+          nodesBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public org.apache.slider.api.proto.Messages.NodeInformationProto.Builder getNodesBuilder(
+          int index) {
+        return getNodesFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public org.apache.slider.api.proto.Messages.NodeInformationProtoOrBuilder getNodesOrBuilder(
+          int index) {
+        if (nodesBuilder_ == null) {
+          return nodes_.get(index);  } else {
+          return nodesBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public java.util.List<? extends org.apache.slider.api.proto.Messages.NodeInformationProtoOrBuilder> 
+           getNodesOrBuilderList() {
+        if (nodesBuilder_ != null) {
+          return nodesBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(nodes_);
+        }
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public org.apache.slider.api.proto.Messages.NodeInformationProto.Builder addNodesBuilder() {
+        return getNodesFieldBuilder().addBuilder(
+            org.apache.slider.api.proto.Messages.NodeInformationProto.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public org.apache.slider.api.proto.Messages.NodeInformationProto.Builder addNodesBuilder(
+          int index) {
+        return getNodesFieldBuilder().addBuilder(
+            index, org.apache.slider.api.proto.Messages.NodeInformationProto.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .org.apache.slider.api.NodeInformationProto nodes = 1;</code>
+       */
+      public java.util.List<org.apache.slider.api.proto.Messages.NodeInformationProto.Builder> 
+           getNodesBuilderList() {
+        return getNodesFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.slider.api.proto.Messages.NodeInformationProto, org.apache.slider.api.proto.Messages.NodeInformationProto.Builder, org.apache.slider.api.proto.Messages.NodeInformationProtoOrBuilder> 
+          getNodesFieldBuilder() {
+        if (nodesBuilder_ == null) {
+          nodesBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.apache.slider.api.proto.Messages.NodeInformationProto, org.apache.slider.api.proto.Messages.NodeInformationProto.Builder, org.apache.slider.api.proto.Messages.NodeInformationProtoOrBuilder>(
+                  nodes_,
+                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  getParentForChildren(),
+                  isClean());
+          nodes_ = null;
+        }
+        return nodesBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.apache.slider.api.GetLiveNodesResponseProto)
+    }
+
+    static {
+      defaultInstance = new GetLiveNodesResponseProto(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.apache.slider.api.GetLiveNodesResponseProto)
+  }
+
+  public interface GetLiveNodeRequestProtoOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string name = 1;
+    /**
+     * <code>required string name = 1;</code>
+     */
+    boolean hasName();
+    /**
+     * <code>required string name = 1;</code>
+     */
+    java.lang.String getName();
+    /**
+     * <code>required string name = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getNameBytes();
+  }
+  /**
+   * Protobuf type {@code org.apache.slider.api.GetLiveNodeRequestProto}
+   */
+  public static final class GetLiveNodeRequestProto extends
+      com.google.protobuf.GeneratedMessage
+      implements GetLiveNodeRequestProtoOrBuilder {
+    // Use GetLiveNodeRequestProto.newBuilder() to construct.
+    private GetLiveNodeRequestProto(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private GetLiveNodeRequestProto(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final GetLiveNodeRequestProto defaultInstance;
+    public static GetLiveNodeRequestProto getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public GetLiveNodeRequestProto getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private GetLiveNodeRequestProto(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              name_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodeRequestProto_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodeRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto.class, org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<GetLiveNodeRequestProto> PARSER =
+        new com.google.protobuf.AbstractParser<GetLiveNodeRequestProto>() {
+      public GetLiveNodeRequestProto parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new GetLiveNodeRequestProto(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<GetLiveNodeRequestProto> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string name = 1;
+    public static final int NAME_FIELD_NUMBER = 1;
+    private java.lang.Object name_;
+    /**
+     * <code>required string name = 1;</code>
+     */
+    public boolean hasName() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string name = 1;</code>
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          name_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string name = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      name_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasName()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getNameBytes());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getNameBytes());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto)) {
+        return super.equals(obj);
+      }
+      org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto other = (org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto) obj;
+
+      boolean result = true;
+      result = result && (hasName() == other.hasName());
+      if (hasName()) {
+        result = result && getName()
+            .equals(other.getName());
+      }
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (hasName()) {
+        hash = (37 * hash) + NAME_FIELD_NUMBER;
+        hash = (53 * hash) + getName().hashCode();
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code org.apache.slider.api.GetLiveNodeRequestProto}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.slider.api.proto.Messages.GetLiveNodeRequestProtoOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodeRequestProto_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodeRequestProto_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto.class, org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto.Builder.class);
+      }
+
+      // Construct using org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        name_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.slider.api.proto.Messages.internal_static_org_apache_slider_api_GetLiveNodeRequestProto_descriptor;
+      }
+
+      public org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto getDefaultInstanceForType() {
+        return org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto.getDefaultInstance();
+      }
+
+      public org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto build() {
+        org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto buildPartial() {
+        org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto result = new org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.name_ = name_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto) {
+          return mergeFrom((org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto other) {
+        if (other == org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto.getDefaultInstance()) return this;
+        if (other.hasName()) {
+          bitField0_ |= 0x00000001;
+          name_ = other.name_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasName()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string name = 1;
+      private java.lang.Object name_ = "";
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public boolean hasName() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public java.lang.String getName() {
+        java.lang.Object ref = name_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          name_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getNameBytes() {
+        java.lang.Object ref = name_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          name_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public Builder setName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        name_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public Builder clearName() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        name_ = getDefaultInstance().getName();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string name = 1;</code>
+       */
+      public Builder setNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        name_ = value;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.apache.slider.api.GetLiveNodeRequestProto)
+    }
+
+    static {
+      defaultInstance = new GetLiveNodeRequestProto(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.apache.slider.api.GetLiveNodeRequestProto)
+  }
+
   private static com.google.protobuf.Descriptors.Descriptor
     internal_static_org_apache_slider_api_RoleInstanceState_descriptor;
   private static
@@ -28820,6 +33933,16 @@
     com.google.protobuf.GeneratedMessage.FieldAccessorTable
       internal_static_org_apache_slider_api_PingInformationProto_fieldAccessorTable;
   private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_apache_slider_api_NodeEntryInformationProto_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_apache_slider_api_NodeEntryInformationProto_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_apache_slider_api_NodeInformationProto_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_apache_slider_api_NodeInformationProto_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
     internal_static_org_apache_slider_api_GetModelRequestProto_descriptor;
   private static
     com.google.protobuf.GeneratedMessage.FieldAccessorTable
@@ -28909,6 +34032,21 @@
   private static
     com.google.protobuf.GeneratedMessage.FieldAccessorTable
       internal_static_org_apache_slider_api_GetCertificateStoreResponseProto_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_apache_slider_api_GetLiveNodesRequestProto_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_apache_slider_api_GetLiveNodesRequestProto_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_apache_slider_api_GetLiveNodesResponseProto_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_apache_slider_api_GetLiveNodesResponseProto_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_apache_slider_api_GetLiveNodeRequestProto_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_org_apache_slider_api_GetLiveNodeRequestProto_fieldAccessorTable;
 
   public static com.google.protobuf.Descriptors.FileDescriptor
       getDescriptor() {
@@ -28957,7 +34095,7 @@
       " \002(\t\022\023\n\013application\030\003 \002(\t\"`\n#Application" +
       "LivenessInformationProto\022\034\n\024allRequestsS" +
       "atisfied\030\001 \001(\010\022\033\n\023requestsOutstanding\030\002 " +
-      "\001(\005\"\347\002\n\031ComponentInformationProto\022\014\n\004nam",
+      "\001(\005\"\256\003\n\031ComponentInformationProto\022\014\n\004nam",
       "e\030\001 \001(\t\022\020\n\010priority\030\002 \001(\005\022\017\n\007desired\030\003 \001" +
       "(\005\022\016\n\006actual\030\004 \001(\005\022\021\n\treleasing\030\005 \001(\005\022\021\n" +
       "\trequested\030\006 \001(\005\022\016\n\006failed\030\007 \001(\005\022\017\n\007star" +
@@ -28966,39 +34104,56 @@
       "lureMessage\030\014 \001(\t\022\027\n\017placementPolicy\030\r \001" +
       "(\005\022\022\n\ncontainers\030\016 \003(\t\022\026\n\016failedRecently" +
       "\030\017 \001(\005\022\022\n\nnodeFailed\030\020 \001(\005\022\021\n\tpreempted\030" +
-      "\021 \001(\005\"\210\002\n\031ContainerInformationProto\022\023\n\013c" +
-      "ontainerId\030\001 \001(\t\022\021\n\tcomponent\030\002 \001(\t\022\020\n\010r",
-      "eleased\030\003 \001(\010\022\r\n\005state\030\004 \001(\005\022\020\n\010exitCode" +
-      "\030\005 \001(\005\022\023\n\013diagnostics\030\006 \001(\t\022\022\n\ncreateTim" +
-      "e\030\007 \001(\003\022\021\n\tstartTime\030\010 \001(\003\022\016\n\006output\030\t \003" +
-      "(\t\022\014\n\004host\030\n \001(\t\022\017\n\007hostURL\030\013 \001(\t\022\021\n\tpla" +
-      "cement\030\014 \001(\t\022\022\n\nappVersion\030\r \001(\t\"N\n\024Ping" +
-      "InformationProto\022\014\n\004text\030\001 \001(\t\022\014\n\004verb\030\002" +
-      " \001(\t\022\014\n\004body\030\003 \001(\t\022\014\n\004time\030\004 \001(\003\"\026\n\024GetM" +
-      "odelRequestProto\"\035\n\033GetModelDesiredReque" +
-      "stProto\"$\n\"GetModelDesiredAppconfRequest" +
-      "Proto\"&\n$GetModelDesiredResourcesRequest",
-      "Proto\"%\n#GetModelResolvedAppconfRequestP" +
-      "roto\"\'\n%GetModelResolvedResourcesRequest" +
-      "Proto\"#\n!GetModelLiveResourcesRequestPro" +
-      "to\"\037\n\035GetLiveContainersRequestProto\"u\n\036G" +
-      "etLiveContainersResponseProto\022\r\n\005names\030\001" +
-      " \003(\t\022D\n\ncontainers\030\002 \003(\01320.org.apache.sl" +
-      "ider.api.ContainerInformationProto\"3\n\034Ge" +
-      "tLiveContainerRequestProto\022\023\n\013containerI" +
-      "d\030\001 \002(\t\"\037\n\035GetLiveComponentsRequestProto" +
-      "\"u\n\036GetLiveComponentsResponseProto\022\r\n\005na",
-      "mes\030\001 \003(\t\022D\n\ncomponents\030\002 \003(\01320.org.apac" +
-      "he.slider.api.ComponentInformationProto\"" +
-      ",\n\034GetLiveComponentRequestProto\022\014\n\004name\030" +
-      "\001 \002(\t\"$\n\"GetApplicationLivenessRequestPr" +
-      "oto\"\023\n\021EmptyPayloadProto\" \n\020WrappedJsonP" +
-      "roto\022\014\n\004json\030\001 \002(\t\"h\n\037GetCertificateStor" +
-      "eRequestProto\022\020\n\010hostname\030\001 \001(\t\022\023\n\013reque" +
-      "sterId\030\002 \002(\t\022\020\n\010password\030\003 \002(\t\022\014\n\004type\030\004" +
-      " \002(\t\"1\n GetCertificateStoreResponseProto" +
-      "\022\r\n\005store\030\001 \002(\014B-\n\033org.apache.slider.api",
-      ".protoB\010Messages\210\001\001\240\001\001"
+      "\021 \001(\005\022%\n\035pendingAntiAffineRequestCount\030\022" +
+      " \001(\005\022\036\n\026isAARequestOutstanding\030\023 \001(\010\"\210\002\n",
+      "\031ContainerInformationProto\022\023\n\013containerI" +
+      "d\030\001 \001(\t\022\021\n\tcomponent\030\002 \001(\t\022\020\n\010released\030\003" +
+      " \001(\010\022\r\n\005state\030\004 \001(\005\022\020\n\010exitCode\030\005 \001(\005\022\023\n" +
+      "\013diagnostics\030\006 \001(\t\022\022\n\ncreateTime\030\007 \001(\003\022\021" +
+      "\n\tstartTime\030\010 \001(\003\022\016\n\006output\030\t \003(\t\022\014\n\004hos" +
+      "t\030\n \001(\t\022\017\n\007hostURL\030\013 \001(\t\022\021\n\tplacement\030\014 " +
+      "\001(\t\022\022\n\nappVersion\030\r \001(\t\"N\n\024PingInformati" +
+      "onProto\022\014\n\004text\030\001 \001(\t\022\014\n\004verb\030\002 \001(\t\022\014\n\004b" +
+      "ody\030\003 \001(\t\022\014\n\004time\030\004 \001(\003\"\343\001\n\031NodeEntryInf" +
+      "ormationProto\022\020\n\010priority\030\001 \002(\005\022\021\n\treque",
+      "sted\030\002 \002(\005\022\020\n\010starting\030\003 \002(\005\022\023\n\013startFai" +
+      "led\030\004 \002(\005\022\016\n\006failed\030\005 \002(\005\022\026\n\016failedRecen" +
+      "tly\030\006 \002(\005\022\021\n\tpreempted\030\007 \002(\005\022\014\n\004live\030\010 \002" +
+      "(\005\022\021\n\treleasing\030\t \002(\005\022\020\n\010lastUsed\030\n \002(\003\022" +
+      "\014\n\004name\030\013 \002(\t\"\334\001\n\024NodeInformationProto\022\020" +
+      "\n\010hostname\030\001 \002(\t\022\r\n\005state\030\002 \002(\t\022\023\n\013httpA" +
+      "ddress\030\003 \002(\t\022\020\n\010rackName\030\004 \002(\t\022\016\n\006labels" +
+      "\030\005 \002(\t\022\024\n\014healthReport\030\006 \002(\t\022\023\n\013lastUpda" +
+      "ted\030\007 \002(\003\022A\n\007entries\030\010 \003(\01320.org.apache." +
+      "slider.api.NodeEntryInformationProto\"\026\n\024",
+      "GetModelRequestProto\"\035\n\033GetModelDesiredR" +
+      "equestProto\"$\n\"GetModelDesiredAppconfReq" +
+      "uestProto\"&\n$GetModelDesiredResourcesReq" +
+      "uestProto\"%\n#GetModelResolvedAppconfRequ" +
+      "estProto\"\'\n%GetModelResolvedResourcesReq" +
+      "uestProto\"#\n!GetModelLiveResourcesReques" +
+      "tProto\"\037\n\035GetLiveContainersRequestProto\"" +
+      "u\n\036GetLiveContainersResponseProto\022\r\n\005nam" +
+      "es\030\001 \003(\t\022D\n\ncontainers\030\002 \003(\01320.org.apach" +
+      "e.slider.api.ContainerInformationProto\"3",
+      "\n\034GetLiveContainerRequestProto\022\023\n\013contai" +
+      "nerId\030\001 \002(\t\"\037\n\035GetLiveComponentsRequestP" +
+      "roto\"u\n\036GetLiveComponentsResponseProto\022\r" +
+      "\n\005names\030\001 \003(\t\022D\n\ncomponents\030\002 \003(\01320.org." +
+      "apache.slider.api.ComponentInformationPr" +
+      "oto\",\n\034GetLiveComponentRequestProto\022\014\n\004n" +
+      "ame\030\001 \002(\t\"$\n\"GetApplicationLivenessReque" +
+      "stProto\"\023\n\021EmptyPayloadProto\" \n\020WrappedJ" +
+      "sonProto\022\014\n\004json\030\001 \002(\t\"h\n\037GetCertificate" +
+      "StoreRequestProto\022\020\n\010hostname\030\001 \001(\t\022\023\n\013r",
+      "equesterId\030\002 \002(\t\022\020\n\010password\030\003 \002(\t\022\014\n\004ty" +
+      "pe\030\004 \002(\t\"1\n GetCertificateStoreResponseP" +
+      "roto\022\r\n\005store\030\001 \002(\014\"\032\n\030GetLiveNodesReque" +
+      "stProto\"W\n\031GetLiveNodesResponseProto\022:\n\005" +
+      "nodes\030\001 \003(\0132+.org.apache.slider.api.Node" +
+      "InformationProto\"\'\n\027GetLiveNodeRequestPr" +
+      "oto\022\014\n\004name\030\001 \002(\tB-\n\033org.apache.slider.a" +
+      "pi.protoB\010Messages\210\001\001\240\001\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -29154,7 +34309,7 @@
           internal_static_org_apache_slider_api_ComponentInformationProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_ComponentInformationProto_descriptor,
-              new java.lang.String[] { "Name", "Priority", "Desired", "Actual", "Releasing", "Requested", "Failed", "Started", "StartFailed", "Completed", "TotalRequested", "FailureMessage", "PlacementPolicy", "Containers", "FailedRecently", "NodeFailed", "Preempted", });
+              new java.lang.String[] { "Name", "Priority", "Desired", "Actual", "Releasing", "Requested", "Failed", "Started", "StartFailed", "Completed", "TotalRequested", "FailureMessage", "PlacementPolicy", "Containers", "FailedRecently", "NodeFailed", "Preempted", "PendingAntiAffineRequestCount", "IsAARequestOutstanding", });
           internal_static_org_apache_slider_api_ContainerInformationProto_descriptor =
             getDescriptor().getMessageTypes().get(25);
           internal_static_org_apache_slider_api_ContainerInformationProto_fieldAccessorTable = new
@@ -29167,114 +34322,144 @@
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_PingInformationProto_descriptor,
               new java.lang.String[] { "Text", "Verb", "Body", "Time", });
-          internal_static_org_apache_slider_api_GetModelRequestProto_descriptor =
+          internal_static_org_apache_slider_api_NodeEntryInformationProto_descriptor =
             getDescriptor().getMessageTypes().get(27);
+          internal_static_org_apache_slider_api_NodeEntryInformationProto_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_apache_slider_api_NodeEntryInformationProto_descriptor,
+              new java.lang.String[] { "Priority", "Requested", "Starting", "StartFailed", "Failed", "FailedRecently", "Preempted", "Live", "Releasing", "LastUsed", "Name", });
+          internal_static_org_apache_slider_api_NodeInformationProto_descriptor =
+            getDescriptor().getMessageTypes().get(28);
+          internal_static_org_apache_slider_api_NodeInformationProto_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_apache_slider_api_NodeInformationProto_descriptor,
+              new java.lang.String[] { "Hostname", "State", "HttpAddress", "RackName", "Labels", "HealthReport", "LastUpdated", "Entries", });
+          internal_static_org_apache_slider_api_GetModelRequestProto_descriptor =
+            getDescriptor().getMessageTypes().get(29);
           internal_static_org_apache_slider_api_GetModelRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetModelRequestProto_descriptor,
               new java.lang.String[] { });
           internal_static_org_apache_slider_api_GetModelDesiredRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(28);
+            getDescriptor().getMessageTypes().get(30);
           internal_static_org_apache_slider_api_GetModelDesiredRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetModelDesiredRequestProto_descriptor,
               new java.lang.String[] { });
           internal_static_org_apache_slider_api_GetModelDesiredAppconfRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(29);
+            getDescriptor().getMessageTypes().get(31);
           internal_static_org_apache_slider_api_GetModelDesiredAppconfRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetModelDesiredAppconfRequestProto_descriptor,
               new java.lang.String[] { });
           internal_static_org_apache_slider_api_GetModelDesiredResourcesRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(30);
+            getDescriptor().getMessageTypes().get(32);
           internal_static_org_apache_slider_api_GetModelDesiredResourcesRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetModelDesiredResourcesRequestProto_descriptor,
               new java.lang.String[] { });
           internal_static_org_apache_slider_api_GetModelResolvedAppconfRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(31);
+            getDescriptor().getMessageTypes().get(33);
           internal_static_org_apache_slider_api_GetModelResolvedAppconfRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetModelResolvedAppconfRequestProto_descriptor,
               new java.lang.String[] { });
           internal_static_org_apache_slider_api_GetModelResolvedResourcesRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(32);
+            getDescriptor().getMessageTypes().get(34);
           internal_static_org_apache_slider_api_GetModelResolvedResourcesRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetModelResolvedResourcesRequestProto_descriptor,
               new java.lang.String[] { });
           internal_static_org_apache_slider_api_GetModelLiveResourcesRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(33);
+            getDescriptor().getMessageTypes().get(35);
           internal_static_org_apache_slider_api_GetModelLiveResourcesRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetModelLiveResourcesRequestProto_descriptor,
               new java.lang.String[] { });
           internal_static_org_apache_slider_api_GetLiveContainersRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(34);
+            getDescriptor().getMessageTypes().get(36);
           internal_static_org_apache_slider_api_GetLiveContainersRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetLiveContainersRequestProto_descriptor,
               new java.lang.String[] { });
           internal_static_org_apache_slider_api_GetLiveContainersResponseProto_descriptor =
-            getDescriptor().getMessageTypes().get(35);
+            getDescriptor().getMessageTypes().get(37);
           internal_static_org_apache_slider_api_GetLiveContainersResponseProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetLiveContainersResponseProto_descriptor,
               new java.lang.String[] { "Names", "Containers", });
           internal_static_org_apache_slider_api_GetLiveContainerRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(36);
+            getDescriptor().getMessageTypes().get(38);
           internal_static_org_apache_slider_api_GetLiveContainerRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetLiveContainerRequestProto_descriptor,
               new java.lang.String[] { "ContainerId", });
           internal_static_org_apache_slider_api_GetLiveComponentsRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(37);
+            getDescriptor().getMessageTypes().get(39);
           internal_static_org_apache_slider_api_GetLiveComponentsRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetLiveComponentsRequestProto_descriptor,
               new java.lang.String[] { });
           internal_static_org_apache_slider_api_GetLiveComponentsResponseProto_descriptor =
-            getDescriptor().getMessageTypes().get(38);
+            getDescriptor().getMessageTypes().get(40);
           internal_static_org_apache_slider_api_GetLiveComponentsResponseProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetLiveComponentsResponseProto_descriptor,
               new java.lang.String[] { "Names", "Components", });
           internal_static_org_apache_slider_api_GetLiveComponentRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(39);
+            getDescriptor().getMessageTypes().get(41);
           internal_static_org_apache_slider_api_GetLiveComponentRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetLiveComponentRequestProto_descriptor,
               new java.lang.String[] { "Name", });
           internal_static_org_apache_slider_api_GetApplicationLivenessRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(40);
+            getDescriptor().getMessageTypes().get(42);
           internal_static_org_apache_slider_api_GetApplicationLivenessRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetApplicationLivenessRequestProto_descriptor,
               new java.lang.String[] { });
           internal_static_org_apache_slider_api_EmptyPayloadProto_descriptor =
-            getDescriptor().getMessageTypes().get(41);
+            getDescriptor().getMessageTypes().get(43);
           internal_static_org_apache_slider_api_EmptyPayloadProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_EmptyPayloadProto_descriptor,
               new java.lang.String[] { });
           internal_static_org_apache_slider_api_WrappedJsonProto_descriptor =
-            getDescriptor().getMessageTypes().get(42);
+            getDescriptor().getMessageTypes().get(44);
           internal_static_org_apache_slider_api_WrappedJsonProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_WrappedJsonProto_descriptor,
               new java.lang.String[] { "Json", });
           internal_static_org_apache_slider_api_GetCertificateStoreRequestProto_descriptor =
-            getDescriptor().getMessageTypes().get(43);
+            getDescriptor().getMessageTypes().get(45);
           internal_static_org_apache_slider_api_GetCertificateStoreRequestProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetCertificateStoreRequestProto_descriptor,
               new java.lang.String[] { "Hostname", "RequesterId", "Password", "Type", });
           internal_static_org_apache_slider_api_GetCertificateStoreResponseProto_descriptor =
-            getDescriptor().getMessageTypes().get(44);
+            getDescriptor().getMessageTypes().get(46);
           internal_static_org_apache_slider_api_GetCertificateStoreResponseProto_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_org_apache_slider_api_GetCertificateStoreResponseProto_descriptor,
               new java.lang.String[] { "Store", });
+          internal_static_org_apache_slider_api_GetLiveNodesRequestProto_descriptor =
+            getDescriptor().getMessageTypes().get(47);
+          internal_static_org_apache_slider_api_GetLiveNodesRequestProto_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_apache_slider_api_GetLiveNodesRequestProto_descriptor,
+              new java.lang.String[] { });
+          internal_static_org_apache_slider_api_GetLiveNodesResponseProto_descriptor =
+            getDescriptor().getMessageTypes().get(48);
+          internal_static_org_apache_slider_api_GetLiveNodesResponseProto_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_apache_slider_api_GetLiveNodesResponseProto_descriptor,
+              new java.lang.String[] { "Nodes", });
+          internal_static_org_apache_slider_api_GetLiveNodeRequestProto_descriptor =
+            getDescriptor().getMessageTypes().get(49);
+          internal_static_org_apache_slider_api_GetLiveNodeRequestProto_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_org_apache_slider_api_GetLiveNodeRequestProto_descriptor,
+              new java.lang.String[] { "Name", });
           return null;
         }
       };
diff --git a/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java b/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java
index c408ed2..feebe1d 100644
--- a/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java
+++ b/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java
@@ -23,6 +23,8 @@
 import org.apache.slider.api.types.ApplicationLivenessInformation;
 import org.apache.slider.api.types.ComponentInformation;
 import org.apache.slider.api.types.ContainerInformation;
+import org.apache.slider.api.types.NodeEntryInformation;
+import org.apache.slider.api.types.NodeInformation;
 import org.apache.slider.core.conf.AggregateConf;
 import org.apache.slider.core.conf.ConfTree;
 import org.apache.slider.core.conf.ConfTreeOperations;
@@ -36,7 +38,10 @@
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Class to handle marshalling of REST
@@ -82,7 +87,12 @@
     if (wire.hasFailureMessage()) {
       info.failureMessage = wire.getFailureMessage();
     }
-
+    if (wire.hasPendingAntiAffineRequestCount()) {
+      info.pendingAntiAffineRequestCount = wire.getPendingAntiAffineRequestCount();
+    }
+    if (wire.hasIsAARequestOutstanding()) {
+      info.isAARequestOutstanding = wire.getIsAARequestOutstanding();
+    }
     return info;
   }
 
@@ -132,11 +142,77 @@
     if (info.containers != null) {
       builder.addAllContainers(info.containers);
     }
+    builder.setPendingAntiAffineRequestCount(info.pendingAntiAffineRequestCount);
+    builder.setIsAARequestOutstanding(info.isAARequestOutstanding);
     return builder.build();
   }
 
-  public static ContainerInformation
-  unmarshall(Messages.ContainerInformationProto wire) {
+  public static Messages.NodeInformationProto marshall(NodeInformation info) {
+
+    Messages.NodeInformationProto.Builder builder =
+        Messages.NodeInformationProto.newBuilder();
+    builder.setHostname(info.hostname);
+    builder.setLastUpdated(info.lastUpdated);
+    builder.setState(info.state != null? info.state : "unknown");
+    builder.setRackName(info.rackName != null ? info.rackName : "");
+    builder.setHealthReport(info.healthReport != null ? info.healthReport : "");
+    builder.setHttpAddress(info.httpAddress != null ? info.httpAddress : "");
+    builder.setLabels(info.labels != null ? info.labels: "");
+
+
+    if (info.entries != null) {
+      for (Map.Entry<String, NodeEntryInformation> elt : info.entries.entrySet()) {
+        NodeEntryInformation entry = elt.getValue();
+        Messages.NodeEntryInformationProto.Builder node =
+            Messages.NodeEntryInformationProto.newBuilder();
+        node.setPriority(entry.priority);
+        node.setName(elt.getKey());
+        node.setFailed(entry.failed);
+        node.setFailedRecently(entry.failedRecently);
+        node.setLive(entry.live);
+        node.setLastUsed(entry.lastUsed);
+        node.setPreempted(entry.preempted);
+        node.setRequested(entry.requested);
+        node.setReleasing(entry.releasing);
+        node.setStartFailed(entry.startFailed);
+        node.setStarting(entry.starting);
+        builder.addEntries(node.build());
+      }
+    }
+    return builder.build();
+  }
+
+  public static NodeInformation unmarshall(Messages.NodeInformationProto wire) {
+    NodeInformation info = new NodeInformation();
+    info.healthReport = wire.getHealthReport();
+    info.hostname = wire.getHostname();
+    info.httpAddress = wire.getHttpAddress();
+    info.labels = wire.getLabels();
+    info.lastUpdated = wire.getLastUpdated();
+    info.rackName = wire.getRackName();
+    info.state = wire.getState();
+    List<Messages.NodeEntryInformationProto> entriesList = wire.getEntriesList();
+    if (entriesList != null) {
+      info.entries = new HashMap<>(entriesList.size());
+      for (Messages.NodeEntryInformationProto entry : entriesList) {
+        NodeEntryInformation nei = new NodeEntryInformation();
+        nei.failed = entry.getFailed();
+        nei.failedRecently = entry.getFailedRecently();
+        nei.lastUsed = entry.getLastUsed();
+        nei.live = entry.getLive();
+        nei.preempted = entry.getPreempted();
+        nei.priority = entry.getPriority();
+        nei.requested = entry.getRequested();
+        nei.releasing = entry.getReleasing();
+        nei.startFailed = entry.getStartFailed();
+        nei.starting = entry.getStarting();
+        info.entries.put(entry.getName(), nei);
+      }
+    }
+    return info;
+  }
+
+  public static ContainerInformation unmarshall(Messages.ContainerInformationProto wire) {
     ContainerInformation info = new ContainerInformation();
     info.containerId = wire.getContainerId();
     info.component = wire.getComponent();
@@ -168,19 +244,15 @@
     return info;
   }
 
-  public static List<ContainerInformation> unmarshall(
-      Messages.GetLiveContainersResponseProto wire) {
-    List<ContainerInformation> infoList = new ArrayList<ContainerInformation>(
-        wire.getContainersList().size());
-    for (Messages.ContainerInformationProto container : wire
-        .getContainersList()) {
+  public static List<ContainerInformation> unmarshall(Messages.GetLiveContainersResponseProto wire) {
+    List<ContainerInformation> infoList = new ArrayList<>(wire.getContainersList().size());
+    for (Messages.ContainerInformationProto container : wire.getContainersList()) {
       infoList.add(unmarshall(container));
     }
     return infoList;
   }
 
-  public static Messages.ContainerInformationProto
-     marshall(ContainerInformation info) {
+  public static Messages.ContainerInformationProto marshall(ContainerInformation info) {
 
     Messages.ContainerInformationProto.Builder builder =
         Messages.ContainerInformationProto.newBuilder();
@@ -217,8 +289,7 @@
     return builder.build();
   }
 
-  public static String
-    unmarshall(Messages.WrappedJsonProto wire) {
+  public static String unmarshall(Messages.WrappedJsonProto wire) {
     return wire.getJson();
   }
 
diff --git a/slider-core/src/main/java/org/apache/slider/api/proto/SliderClusterAPI.java b/slider-core/src/main/java/org/apache/slider/api/proto/SliderClusterAPI.java
index 702c762..081b7fa 100644
--- a/slider-core/src/main/java/org/apache/slider/api/proto/SliderClusterAPI.java
+++ b/slider-core/src/main/java/org/apache/slider/api/proto/SliderClusterAPI.java
@@ -203,6 +203,22 @@
           com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.ComponentInformationProto> done);
 
       /**
+       * <code>rpc getLiveNodes(.org.apache.slider.api.GetLiveNodesRequestProto) returns (.org.apache.slider.api.GetLiveNodesResponseProto);</code>
+       */
+      public abstract void getLiveNodes(
+          com.google.protobuf.RpcController controller,
+          org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto request,
+          com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto> done);
+
+      /**
+       * <code>rpc getLiveNode(.org.apache.slider.api.GetLiveNodeRequestProto) returns (.org.apache.slider.api.NodeInformationProto);</code>
+       */
+      public abstract void getLiveNode(
+          com.google.protobuf.RpcController controller,
+          org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto request,
+          com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.NodeInformationProto> done);
+
+      /**
        * <code>rpc getModelDesired(.org.apache.slider.api.EmptyPayloadProto) returns (.org.apache.slider.api.WrappedJsonProto);</code>
        *
        * <pre>
@@ -428,6 +444,22 @@
         }
 
         @java.lang.Override
+        public  void getLiveNodes(
+            com.google.protobuf.RpcController controller,
+            org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto request,
+            com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto> done) {
+          impl.getLiveNodes(controller, request, done);
+        }
+
+        @java.lang.Override
+        public  void getLiveNode(
+            com.google.protobuf.RpcController controller,
+            org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto request,
+            com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.NodeInformationProto> done) {
+          impl.getLiveNode(controller, request, done);
+        }
+
+        @java.lang.Override
         public  void getModelDesired(
             com.google.protobuf.RpcController controller,
             org.apache.slider.api.proto.Messages.EmptyPayloadProto request,
@@ -546,20 +578,24 @@
             case 15:
               return impl.getLiveComponent(controller, (org.apache.slider.api.proto.Messages.GetLiveComponentRequestProto)request);
             case 16:
-              return impl.getModelDesired(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
+              return impl.getLiveNodes(controller, (org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto)request);
             case 17:
-              return impl.getModelDesiredAppconf(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
+              return impl.getLiveNode(controller, (org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto)request);
             case 18:
-              return impl.getModelDesiredResources(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
+              return impl.getModelDesired(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
             case 19:
-              return impl.getModelResolved(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
+              return impl.getModelDesiredAppconf(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
             case 20:
-              return impl.getModelResolvedAppconf(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
+              return impl.getModelDesiredResources(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
             case 21:
-              return impl.getModelResolvedResources(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
+              return impl.getModelResolved(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
             case 22:
-              return impl.getLiveResources(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
+              return impl.getModelResolvedAppconf(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
             case 23:
+              return impl.getModelResolvedResources(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
+            case 24:
+              return impl.getLiveResources(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request);
+            case 25:
               return impl.getClientCertificateStore(controller, (org.apache.slider.api.proto.Messages.GetCertificateStoreRequestProto)request);
             default:
               throw new java.lang.AssertionError("Can't get here.");
@@ -608,9 +644,9 @@
             case 15:
               return org.apache.slider.api.proto.Messages.GetLiveComponentRequestProto.getDefaultInstance();
             case 16:
-              return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
+              return org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto.getDefaultInstance();
             case 17:
-              return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
+              return org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto.getDefaultInstance();
             case 18:
               return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
             case 19:
@@ -622,6 +658,10 @@
             case 22:
               return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
             case 23:
+              return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
+            case 24:
+              return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
+            case 25:
               return org.apache.slider.api.proto.Messages.GetCertificateStoreRequestProto.getDefaultInstance();
             default:
               throw new java.lang.AssertionError("Can't get here.");
@@ -670,9 +710,9 @@
             case 15:
               return org.apache.slider.api.proto.Messages.ComponentInformationProto.getDefaultInstance();
             case 16:
-              return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
+              return org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.getDefaultInstance();
             case 17:
-              return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
+              return org.apache.slider.api.proto.Messages.NodeInformationProto.getDefaultInstance();
             case 18:
               return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
             case 19:
@@ -684,6 +724,10 @@
             case 22:
               return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
             case 23:
+              return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
+            case 24:
+              return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
+            case 25:
               return org.apache.slider.api.proto.Messages.GetCertificateStoreResponseProto.getDefaultInstance();
             default:
               throw new java.lang.AssertionError("Can't get here.");
@@ -875,6 +919,22 @@
         com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.ComponentInformationProto> done);
 
     /**
+     * <code>rpc getLiveNodes(.org.apache.slider.api.GetLiveNodesRequestProto) returns (.org.apache.slider.api.GetLiveNodesResponseProto);</code>
+     */
+    public abstract void getLiveNodes(
+        com.google.protobuf.RpcController controller,
+        org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto request,
+        com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto> done);
+
+    /**
+     * <code>rpc getLiveNode(.org.apache.slider.api.GetLiveNodeRequestProto) returns (.org.apache.slider.api.NodeInformationProto);</code>
+     */
+    public abstract void getLiveNode(
+        com.google.protobuf.RpcController controller,
+        org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto request,
+        com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.NodeInformationProto> done);
+
+    /**
      * <code>rpc getModelDesired(.org.apache.slider.api.EmptyPayloadProto) returns (.org.apache.slider.api.WrappedJsonProto);</code>
      *
      * <pre>
@@ -1069,41 +1129,51 @@
               done));
           return;
         case 16:
+          this.getLiveNodes(controller, (org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto)request,
+            com.google.protobuf.RpcUtil.<org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto>specializeCallback(
+              done));
+          return;
+        case 17:
+          this.getLiveNode(controller, (org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto)request,
+            com.google.protobuf.RpcUtil.<org.apache.slider.api.proto.Messages.NodeInformationProto>specializeCallback(
+              done));
+          return;
+        case 18:
           this.getModelDesired(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request,
             com.google.protobuf.RpcUtil.<org.apache.slider.api.proto.Messages.WrappedJsonProto>specializeCallback(
               done));
           return;
-        case 17:
+        case 19:
           this.getModelDesiredAppconf(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request,
             com.google.protobuf.RpcUtil.<org.apache.slider.api.proto.Messages.WrappedJsonProto>specializeCallback(
               done));
           return;
-        case 18:
+        case 20:
           this.getModelDesiredResources(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request,
             com.google.protobuf.RpcUtil.<org.apache.slider.api.proto.Messages.WrappedJsonProto>specializeCallback(
               done));
           return;
-        case 19:
+        case 21:
           this.getModelResolved(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request,
             com.google.protobuf.RpcUtil.<org.apache.slider.api.proto.Messages.WrappedJsonProto>specializeCallback(
               done));
           return;
-        case 20:
+        case 22:
           this.getModelResolvedAppconf(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request,
             com.google.protobuf.RpcUtil.<org.apache.slider.api.proto.Messages.WrappedJsonProto>specializeCallback(
               done));
           return;
-        case 21:
+        case 23:
           this.getModelResolvedResources(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request,
             com.google.protobuf.RpcUtil.<org.apache.slider.api.proto.Messages.WrappedJsonProto>specializeCallback(
               done));
           return;
-        case 22:
+        case 24:
           this.getLiveResources(controller, (org.apache.slider.api.proto.Messages.EmptyPayloadProto)request,
             com.google.protobuf.RpcUtil.<org.apache.slider.api.proto.Messages.WrappedJsonProto>specializeCallback(
               done));
           return;
-        case 23:
+        case 25:
           this.getClientCertificateStore(controller, (org.apache.slider.api.proto.Messages.GetCertificateStoreRequestProto)request,
             com.google.protobuf.RpcUtil.<org.apache.slider.api.proto.Messages.GetCertificateStoreResponseProto>specializeCallback(
               done));
@@ -1155,9 +1225,9 @@
         case 15:
           return org.apache.slider.api.proto.Messages.GetLiveComponentRequestProto.getDefaultInstance();
         case 16:
-          return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
+          return org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto.getDefaultInstance();
         case 17:
-          return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
+          return org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto.getDefaultInstance();
         case 18:
           return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
         case 19:
@@ -1169,6 +1239,10 @@
         case 22:
           return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
         case 23:
+          return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
+        case 24:
+          return org.apache.slider.api.proto.Messages.EmptyPayloadProto.getDefaultInstance();
+        case 25:
           return org.apache.slider.api.proto.Messages.GetCertificateStoreRequestProto.getDefaultInstance();
         default:
           throw new java.lang.AssertionError("Can't get here.");
@@ -1217,9 +1291,9 @@
         case 15:
           return org.apache.slider.api.proto.Messages.ComponentInformationProto.getDefaultInstance();
         case 16:
-          return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
+          return org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.getDefaultInstance();
         case 17:
-          return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
+          return org.apache.slider.api.proto.Messages.NodeInformationProto.getDefaultInstance();
         case 18:
           return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
         case 19:
@@ -1231,6 +1305,10 @@
         case 22:
           return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
         case 23:
+          return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
+        case 24:
+          return org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance();
+        case 25:
           return org.apache.slider.api.proto.Messages.GetCertificateStoreResponseProto.getDefaultInstance();
         default:
           throw new java.lang.AssertionError("Can't get here.");
@@ -1493,37 +1571,37 @@
             org.apache.slider.api.proto.Messages.ComponentInformationProto.getDefaultInstance()));
       }
 
-      public  void getModelDesired(
+      public  void getLiveNodes(
           com.google.protobuf.RpcController controller,
-          org.apache.slider.api.proto.Messages.EmptyPayloadProto request,
-          com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.WrappedJsonProto> done) {
+          org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto request,
+          com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto> done) {
         channel.callMethod(
           getDescriptor().getMethods().get(16),
           controller,
           request,
-          org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance(),
+          org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.getDefaultInstance(),
           com.google.protobuf.RpcUtil.generalizeCallback(
             done,
-            org.apache.slider.api.proto.Messages.WrappedJsonProto.class,
-            org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance()));
+            org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.class,
+            org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.getDefaultInstance()));
       }
 
-      public  void getModelDesiredAppconf(
+      public  void getLiveNode(
           com.google.protobuf.RpcController controller,
-          org.apache.slider.api.proto.Messages.EmptyPayloadProto request,
-          com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.WrappedJsonProto> done) {
+          org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto request,
+          com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.NodeInformationProto> done) {
         channel.callMethod(
           getDescriptor().getMethods().get(17),
           controller,
           request,
-          org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance(),
+          org.apache.slider.api.proto.Messages.NodeInformationProto.getDefaultInstance(),
           com.google.protobuf.RpcUtil.generalizeCallback(
             done,
-            org.apache.slider.api.proto.Messages.WrappedJsonProto.class,
-            org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance()));
+            org.apache.slider.api.proto.Messages.NodeInformationProto.class,
+            org.apache.slider.api.proto.Messages.NodeInformationProto.getDefaultInstance()));
       }
 
-      public  void getModelDesiredResources(
+      public  void getModelDesired(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.EmptyPayloadProto request,
           com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.WrappedJsonProto> done) {
@@ -1538,7 +1616,7 @@
             org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance()));
       }
 
-      public  void getModelResolved(
+      public  void getModelDesiredAppconf(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.EmptyPayloadProto request,
           com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.WrappedJsonProto> done) {
@@ -1553,7 +1631,7 @@
             org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance()));
       }
 
-      public  void getModelResolvedAppconf(
+      public  void getModelDesiredResources(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.EmptyPayloadProto request,
           com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.WrappedJsonProto> done) {
@@ -1568,7 +1646,7 @@
             org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance()));
       }
 
-      public  void getModelResolvedResources(
+      public  void getModelResolved(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.EmptyPayloadProto request,
           com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.WrappedJsonProto> done) {
@@ -1583,7 +1661,7 @@
             org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance()));
       }
 
-      public  void getLiveResources(
+      public  void getModelResolvedAppconf(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.EmptyPayloadProto request,
           com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.WrappedJsonProto> done) {
@@ -1598,12 +1676,42 @@
             org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance()));
       }
 
+      public  void getModelResolvedResources(
+          com.google.protobuf.RpcController controller,
+          org.apache.slider.api.proto.Messages.EmptyPayloadProto request,
+          com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.WrappedJsonProto> done) {
+        channel.callMethod(
+          getDescriptor().getMethods().get(23),
+          controller,
+          request,
+          org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance(),
+          com.google.protobuf.RpcUtil.generalizeCallback(
+            done,
+            org.apache.slider.api.proto.Messages.WrappedJsonProto.class,
+            org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance()));
+      }
+
+      public  void getLiveResources(
+          com.google.protobuf.RpcController controller,
+          org.apache.slider.api.proto.Messages.EmptyPayloadProto request,
+          com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.WrappedJsonProto> done) {
+        channel.callMethod(
+          getDescriptor().getMethods().get(24),
+          controller,
+          request,
+          org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance(),
+          com.google.protobuf.RpcUtil.generalizeCallback(
+            done,
+            org.apache.slider.api.proto.Messages.WrappedJsonProto.class,
+            org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance()));
+      }
+
       public  void getClientCertificateStore(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.GetCertificateStoreRequestProto request,
           com.google.protobuf.RpcCallback<org.apache.slider.api.proto.Messages.GetCertificateStoreResponseProto> done) {
         channel.callMethod(
-          getDescriptor().getMethods().get(23),
+          getDescriptor().getMethods().get(25),
           controller,
           request,
           org.apache.slider.api.proto.Messages.GetCertificateStoreResponseProto.getDefaultInstance(),
@@ -1700,6 +1808,16 @@
           org.apache.slider.api.proto.Messages.GetLiveComponentRequestProto request)
           throws com.google.protobuf.ServiceException;
 
+      public org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto getLiveNodes(
+          com.google.protobuf.RpcController controller,
+          org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto request)
+          throws com.google.protobuf.ServiceException;
+
+      public org.apache.slider.api.proto.Messages.NodeInformationProto getLiveNode(
+          com.google.protobuf.RpcController controller,
+          org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto request)
+          throws com.google.protobuf.ServiceException;
+
       public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelDesired(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.EmptyPayloadProto request)
@@ -1940,31 +2058,31 @@
       }
 
 
-      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelDesired(
+      public org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto getLiveNodes(
           com.google.protobuf.RpcController controller,
-          org.apache.slider.api.proto.Messages.EmptyPayloadProto request)
+          org.apache.slider.api.proto.Messages.GetLiveNodesRequestProto request)
           throws com.google.protobuf.ServiceException {
-        return (org.apache.slider.api.proto.Messages.WrappedJsonProto) channel.callBlockingMethod(
+        return (org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto) channel.callBlockingMethod(
           getDescriptor().getMethods().get(16),
           controller,
           request,
-          org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance());
+          org.apache.slider.api.proto.Messages.GetLiveNodesResponseProto.getDefaultInstance());
       }
 
 
-      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelDesiredAppconf(
+      public org.apache.slider.api.proto.Messages.NodeInformationProto getLiveNode(
           com.google.protobuf.RpcController controller,
-          org.apache.slider.api.proto.Messages.EmptyPayloadProto request)
+          org.apache.slider.api.proto.Messages.GetLiveNodeRequestProto request)
           throws com.google.protobuf.ServiceException {
-        return (org.apache.slider.api.proto.Messages.WrappedJsonProto) channel.callBlockingMethod(
+        return (org.apache.slider.api.proto.Messages.NodeInformationProto) channel.callBlockingMethod(
           getDescriptor().getMethods().get(17),
           controller,
           request,
-          org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance());
+          org.apache.slider.api.proto.Messages.NodeInformationProto.getDefaultInstance());
       }
 
 
-      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelDesiredResources(
+      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelDesired(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.EmptyPayloadProto request)
           throws com.google.protobuf.ServiceException {
@@ -1976,7 +2094,7 @@
       }
 
 
-      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelResolved(
+      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelDesiredAppconf(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.EmptyPayloadProto request)
           throws com.google.protobuf.ServiceException {
@@ -1988,7 +2106,7 @@
       }
 
 
-      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelResolvedAppconf(
+      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelDesiredResources(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.EmptyPayloadProto request)
           throws com.google.protobuf.ServiceException {
@@ -2000,7 +2118,7 @@
       }
 
 
-      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelResolvedResources(
+      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelResolved(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.EmptyPayloadProto request)
           throws com.google.protobuf.ServiceException {
@@ -2012,7 +2130,7 @@
       }
 
 
-      public org.apache.slider.api.proto.Messages.WrappedJsonProto getLiveResources(
+      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelResolvedAppconf(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.EmptyPayloadProto request)
           throws com.google.protobuf.ServiceException {
@@ -2024,12 +2142,36 @@
       }
 
 
+      public org.apache.slider.api.proto.Messages.WrappedJsonProto getModelResolvedResources(
+          com.google.protobuf.RpcController controller,
+          org.apache.slider.api.proto.Messages.EmptyPayloadProto request)
+          throws com.google.protobuf.ServiceException {
+        return (org.apache.slider.api.proto.Messages.WrappedJsonProto) channel.callBlockingMethod(
+          getDescriptor().getMethods().get(23),
+          controller,
+          request,
+          org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance());
+      }
+
+
+      public org.apache.slider.api.proto.Messages.WrappedJsonProto getLiveResources(
+          com.google.protobuf.RpcController controller,
+          org.apache.slider.api.proto.Messages.EmptyPayloadProto request)
+          throws com.google.protobuf.ServiceException {
+        return (org.apache.slider.api.proto.Messages.WrappedJsonProto) channel.callBlockingMethod(
+          getDescriptor().getMethods().get(24),
+          controller,
+          request,
+          org.apache.slider.api.proto.Messages.WrappedJsonProto.getDefaultInstance());
+      }
+
+
       public org.apache.slider.api.proto.Messages.GetCertificateStoreResponseProto getClientCertificateStore(
           com.google.protobuf.RpcController controller,
           org.apache.slider.api.proto.Messages.GetCertificateStoreRequestProto request)
           throws com.google.protobuf.ServiceException {
         return (org.apache.slider.api.proto.Messages.GetCertificateStoreResponseProto) channel.callBlockingMethod(
-          getDescriptor().getMethods().get(23),
+          getDescriptor().getMethods().get(25),
           controller,
           request,
           org.apache.slider.api.proto.Messages.GetCertificateStoreResponseProto.getDefaultInstance());
@@ -2051,7 +2193,7 @@
     java.lang.String[] descriptorData = {
       "\n\033SliderClusterProtocol.proto\022\025org.apach" +
       "e.slider.api\032\033SliderClusterMessages.prot" +
-      "o2\306\026\n\027SliderClusterProtocolPB\022n\n\013stopClu" +
+      "o2\245\030\n\027SliderClusterProtocolPB\022n\n\013stopClu" +
       "ster\022..org.apache.slider.api.StopCluster" +
       "RequestProto\032/.org.apache.slider.api.Sto" +
       "pClusterResponseProto\022\200\001\n\021upgradeContain" +
@@ -2100,31 +2242,37 @@
       "api.GetLiveComponentsResponseProto\022y\n\020ge" +
       "tLiveComponent\0223.org.apache.slider.api.G",
       "etLiveComponentRequestProto\0320.org.apache" +
-      ".slider.api.ComponentInformationProto\022d\n" +
-      "\017getModelDesired\022(.org.apache.slider.api" +
-      ".EmptyPayloadProto\032\'.org.apache.slider.a" +
-      "pi.WrappedJsonProto\022k\n\026getModelDesiredAp" +
-      "pconf\022(.org.apache.slider.api.EmptyPaylo" +
-      "adProto\032\'.org.apache.slider.api.WrappedJ" +
-      "sonProto\022m\n\030getModelDesiredResources\022(.o" +
-      "rg.apache.slider.api.EmptyPayloadProto\032\'" +
-      ".org.apache.slider.api.WrappedJsonProto\022",
-      "e\n\020getModelResolved\022(.org.apache.slider." +
+      ".slider.api.ComponentInformationProto\022q\n" +
+      "\014getLiveNodes\022/.org.apache.slider.api.Ge" +
+      "tLiveNodesRequestProto\0320.org.apache.slid" +
+      "er.api.GetLiveNodesResponseProto\022j\n\013getL" +
+      "iveNode\022..org.apache.slider.api.GetLiveN" +
+      "odeRequestProto\032+.org.apache.slider.api." +
+      "NodeInformationProto\022d\n\017getModelDesired\022" +
+      "(.org.apache.slider.api.EmptyPayloadProt" +
+      "o\032\'.org.apache.slider.api.WrappedJsonPro",
+      "to\022k\n\026getModelDesiredAppconf\022(.org.apach" +
+      "e.slider.api.EmptyPayloadProto\032\'.org.apa" +
+      "che.slider.api.WrappedJsonProto\022m\n\030getMo" +
+      "delDesiredResources\022(.org.apache.slider." +
       "api.EmptyPayloadProto\032\'.org.apache.slide" +
-      "r.api.WrappedJsonProto\022l\n\027getModelResolv" +
-      "edAppconf\022(.org.apache.slider.api.EmptyP" +
-      "ayloadProto\032\'.org.apache.slider.api.Wrap" +
-      "pedJsonProto\022n\n\031getModelResolvedResource" +
-      "s\022(.org.apache.slider.api.EmptyPayloadPr" +
-      "oto\032\'.org.apache.slider.api.WrappedJsonP" +
-      "roto\022e\n\020getLiveResources\022(.org.apache.sl" +
-      "ider.api.EmptyPayloadProto\032\'.org.apache.",
-      "slider.api.WrappedJsonProto\022\214\001\n\031getClien" +
-      "tCertificateStore\0226.org.apache.slider.ap" +
-      "i.GetCertificateStoreRequestProto\0327.org." +
-      "apache.slider.api.GetCertificateStoreRes" +
-      "ponseProtoB5\n\033org.apache.slider.api.prot" +
-      "oB\020SliderClusterAPI\210\001\001\240\001\001"
+      "r.api.WrappedJsonProto\022e\n\020getModelResolv" +
+      "ed\022(.org.apache.slider.api.EmptyPayloadP" +
+      "roto\032\'.org.apache.slider.api.WrappedJson" +
+      "Proto\022l\n\027getModelResolvedAppconf\022(.org.a" +
+      "pache.slider.api.EmptyPayloadProto\032\'.org",
+      ".apache.slider.api.WrappedJsonProto\022n\n\031g" +
+      "etModelResolvedResources\022(.org.apache.sl" +
+      "ider.api.EmptyPayloadProto\032\'.org.apache." +
+      "slider.api.WrappedJsonProto\022e\n\020getLiveRe" +
+      "sources\022(.org.apache.slider.api.EmptyPay" +
+      "loadProto\032\'.org.apache.slider.api.Wrappe" +
+      "dJsonProto\022\214\001\n\031getClientCertificateStore" +
+      "\0226.org.apache.slider.api.GetCertificateS" +
+      "toreRequestProto\0327.org.apache.slider.api" +
+      ".GetCertificateStoreResponseProtoB5\n\033org",
+      ".apache.slider.api.protoB\020SliderClusterA" +
+      "PI\210\001\001\240\001\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
diff --git a/slider-core/src/main/java/org/apache/slider/api/types/ApplicationLivenessInformation.java b/slider-core/src/main/java/org/apache/slider/api/types/ApplicationLivenessInformation.java
index 4dd2cb7..9879d05 100644
--- a/slider-core/src/main/java/org/apache/slider/api/types/ApplicationLivenessInformation.java
+++ b/slider-core/src/main/java/org/apache/slider/api/types/ApplicationLivenessInformation.java
@@ -30,9 +30,15 @@
 @JsonIgnoreProperties(ignoreUnknown = true)
 @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
 public class ApplicationLivenessInformation {
+  /** flag set if the cluster is at size */
   public boolean allRequestsSatisfied;
+
+  /** number of outstanding requests: those needed to satisfy */
   public int requestsOutstanding;
 
+  /** number of requests submitted to YARN */
+  public int activeRequests;
+
   @Override
   public String toString() {
     final StringBuilder sb =
diff --git a/slider-core/src/main/java/org/apache/slider/api/types/ComponentInformation.java b/slider-core/src/main/java/org/apache/slider/api/types/ComponentInformation.java
index 52f6c08..c46a59f 100644
--- a/slider-core/src/main/java/org/apache/slider/api/types/ComponentInformation.java
+++ b/slider-core/src/main/java/org/apache/slider/api/types/ComponentInformation.java
@@ -19,6 +19,7 @@
 package org.apache.slider.api.types;
 
 import org.apache.slider.api.StatusKeys;
+import org.apache.slider.server.appmaster.state.RoleStatus;
 import org.codehaus.jackson.annotate.JsonIgnoreProperties;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
@@ -35,13 +36,15 @@
  * <p>
  * This means that if any fields are added here. they must be added to
  * <code>src/main/proto/SliderClusterMessages.proto</code> and
- * the probuf structures rebuilt.
+ * the protobuf structures rebuilt via a {@code mvn generate-sources -Pcompile-protobuf}
+ *
+ * See also {@link RoleStatus#serialize()}
  */
 @JsonIgnoreProperties(ignoreUnknown = true)
 @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
 
 public class ComponentInformation {
-  
+
   public String name;
   public int priority;
   public int desired, actual, releasing;
@@ -49,6 +52,9 @@
   public int requested;
   public int failed, started, startFailed, completed, totalRequested;
   public int nodeFailed, failedRecently, preempted;
+  public int pendingAntiAffineRequestCount;
+  public boolean isAARequestOutstanding;
+
   public String failureMessage;
   public List<String> containers;
 
@@ -59,16 +65,17 @@
   public Map<String, Integer> buildStatistics() {
     Map<String, Integer> stats = new HashMap<>();
     stats.put(StatusKeys.STATISTICS_CONTAINERS_ACTIVE_REQUESTS, requested);
+    stats.put(StatusKeys.STATISTICS_CONTAINERS_ANTI_AFFINE_PENDING, pendingAntiAffineRequestCount);
     stats.put(StatusKeys.STATISTICS_CONTAINERS_COMPLETED, completed);
     stats.put(StatusKeys.STATISTICS_CONTAINERS_DESIRED, desired);
     stats.put(StatusKeys.STATISTICS_CONTAINERS_FAILED, failed);
+    stats.put(StatusKeys.STATISTICS_CONTAINERS_FAILED_NODE, nodeFailed);
+    stats.put(StatusKeys.STATISTICS_CONTAINERS_FAILED_RECENTLY, failedRecently);
     stats.put(StatusKeys.STATISTICS_CONTAINERS_LIVE, actual);
+    stats.put(StatusKeys.STATISTICS_CONTAINERS_PREEMPTED, preempted);
     stats.put(StatusKeys.STATISTICS_CONTAINERS_REQUESTED, totalRequested);
     stats.put(StatusKeys.STATISTICS_CONTAINERS_STARTED, started);
     stats.put(StatusKeys.STATISTICS_CONTAINERS_START_FAILED, startFailed);
-    stats.put(StatusKeys.STATISTICS_CONTAINERS_FAILED_RECENTLY, failedRecently);
-    stats.put(StatusKeys.STATISTICS_CONTAINERS_FAILED_NODE, nodeFailed);
-    stats.put(StatusKeys.STATISTICS_CONTAINERS_PREEMPTED, preempted);
     return stats;
   }
 
@@ -76,22 +83,24 @@
   public String toString() {
     final StringBuilder sb =
         new StringBuilder("ComponentInformation{");
-    sb.append("failureMessage='").append(failureMessage).append('\'');
-    sb.append(", totalRequested=").append(totalRequested);
-    sb.append(", completed=").append(completed);
-    sb.append(", startFailed=").append(startFailed);
-    sb.append(", started=").append(started);
-    sb.append(", failed=").append(failed);
-    sb.append(", requested=").append(requested);
-    sb.append(", placementPolicy=").append(placementPolicy);
-    sb.append(", releasing=").append(releasing);
-    sb.append(", actual=").append(actual);
-    sb.append(", desired=").append(desired);
-    sb.append(", priority=").append(priority);
     sb.append(", name='").append(name).append('\'');
+    sb.append(", actual=").append(actual);
+    sb.append(", completed=").append(completed);
+    sb.append(", desired=").append(desired);
+    sb.append(", failed=").append(failed);
+    sb.append(", failureMessage='").append(failureMessage).append('\'');
+    sb.append(", placementPolicy=").append(placementPolicy);
+    sb.append(", isAARequestOutstanding=").append(isAARequestOutstanding);
+    sb.append(", pendingAntiAffineRequestCount=").append(pendingAntiAffineRequestCount);
+    sb.append(", priority=").append(priority);
+    sb.append(", releasing=").append(releasing);
+    sb.append(", requested=").append(requested);
+    sb.append(", started=").append(started);
+    sb.append(", startFailed=").append(startFailed);
+    sb.append(", totalRequested=").append(totalRequested);
     sb.append(", container count='")
-      .append(containers== null ? 0: containers.size())
-      .append('\'');
+        .append(containers == null ? 0 : containers.size())
+        .append('\'');
     sb.append('}');
     return sb.toString();
   }
diff --git a/slider-core/src/main/java/org/apache/slider/api/types/NodeEntryInformation.java b/slider-core/src/main/java/org/apache/slider/api/types/NodeEntryInformation.java
new file mode 100644
index 0000000..8424be2
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/api/types/NodeEntryInformation.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.api.types;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+/**
+ * Serialized node entry information. Must be kept in sync with the protobuf equivalent.
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+public class NodeEntryInformation {
+
+  /** incrementing counter of instances that failed */
+  public int failed;
+
+  /** Counter of "failed recently" events. */
+  public int failedRecently;
+
+  /** timestamp of last use */
+  public long lastUsed;
+
+  /** Number of live nodes. */
+  public int live;
+
+  /** incrementing counter of instances that have been pre-empted. */
+  public int preempted;
+
+  /** Priority */
+  public int priority;
+
+  /** instance explicitly requested on this node */
+  public int requested;
+
+  /** number of containers being released off this node */
+  public int releasing;
+
+  /** incrementing counter of instances that failed to start */
+  public int startFailed;
+
+  /** number of starting instances */
+  public int starting;
+
+  @Override
+  public String toString() {
+    final StringBuilder sb = new StringBuilder(
+        "NodeEntryInformation{");
+    sb.append("priority=").append(priority);
+    sb.append(", live=").append(live);
+    sb.append(", requested=").append(requested);
+    sb.append(", releasing=").append(releasing);
+    sb.append(", starting=").append(starting);
+    sb.append(", failed=").append(failed);
+    sb.append(", failedRecently=").append(failedRecently);
+    sb.append(", startFailed=").append(startFailed);
+    sb.append(", preempted=").append(preempted);
+    sb.append(", lastUsed=").append(lastUsed);
+    sb.append('}');
+    return sb.toString();
+  }
+}
diff --git a/slider-core/src/main/java/org/apache/slider/api/types/NodeInformation.java b/slider-core/src/main/java/org/apache/slider/api/types/NodeInformation.java
new file mode 100644
index 0000000..4fe5b4c
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/api/types/NodeInformation.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.api.types;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Serialized node information. Must be kept in sync with the protobuf equivalent.
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+public class NodeInformation {
+
+  public String hostname;
+  public String state;
+  public String labels;
+  public String rackName;
+  public String httpAddress;
+  public String healthReport;
+  public long lastUpdated;
+  public Map<String, NodeEntryInformation> entries = new HashMap<>();
+
+  @Override
+  public String toString() {
+    final StringBuilder sb = new StringBuilder(
+      "NodeInformation{");
+    sb.append("hostname='").append(hostname).append('\'');
+    sb.append(", state='").append(state).append('\'');
+    sb.append(", labels='").append(labels).append('\'');
+    sb.append(", rackName='").append(rackName).append('\'');
+    sb.append(", httpAddress='").append(httpAddress).append('\'');
+    sb.append(", healthReport='").append(healthReport).append('\'');
+    sb.append(", lastUpdated=").append(lastUpdated);
+    sb.append('}');
+    return sb.toString();
+  }
+}
diff --git a/slider-core/src/main/java/org/apache/slider/api/types/NodeInformationList.java b/slider-core/src/main/java/org/apache/slider/api/types/NodeInformationList.java
new file mode 100644
index 0000000..741523e
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/api/types/NodeInformationList.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.api.types;
+
+import org.apache.slider.core.persist.JsonSerDeser;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class NodeInformationList extends ArrayList<NodeInformation> {
+  public NodeInformationList() {
+  }
+
+  public NodeInformationList(Collection<? extends NodeInformation> c) {
+    super(c);
+  }
+
+  public NodeInformationList(int initialCapacity) {
+    super(initialCapacity);
+  }
+
+  public static JsonSerDeser<NodeInformationList> createSerializer() {
+    return new JsonSerDeser<>(NodeInformationList.class);
+  }
+}
diff --git a/slider-core/src/main/java/org/apache/slider/api/types/RoleStatistics.java b/slider-core/src/main/java/org/apache/slider/api/types/RoleStatistics.java
new file mode 100644
index 0000000..c926600
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/api/types/RoleStatistics.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.api.types;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+
+/**
+ * Simple role statistics for state views; can be generated by RoleStatus
+ * instances, and aggregated for summary information.
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class RoleStatistics {
+  public long activeAA  = 0L;
+  public long actual = 0L;
+  public long completed = 0L;
+  public long desired = 0L;
+  public long failed = 0L;
+  public long failedRecently = 0L;
+  public long limitsExceeded = 0L;
+  public long nodeFailed = 0L;
+  public long preempted = 0L;
+  public long releasing = 0L;
+  public long requested = 0L;
+  public long started = 0L;
+  public long startFailed = 0L;
+  public long totalRequested = 0L;
+
+  /**
+   * Add another statistics instance
+   * @param that the other value
+   * @return this entry
+   */
+  public RoleStatistics add(final RoleStatistics that) {
+    activeAA += that.activeAA;
+    actual += that.actual;
+    completed += that.completed;
+    desired += that.desired;
+    failed += that.failed;
+    failedRecently += that.failedRecently;
+    limitsExceeded += that.limitsExceeded;
+    nodeFailed += that.nodeFailed;
+    preempted += that.preempted;
+    releasing += that.releasing;
+    requested += that.requested;
+    started += that.started;
+    startFailed += that.totalRequested;
+    totalRequested += that.totalRequested;
+    return this;
+  }
+}
diff --git a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
index fe0e038..da94dd4 100644
--- a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
+++ b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
@@ -19,8 +19,8 @@
 package org.apache.slider.client;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
 import com.google.common.io.Files;
+
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.ArrayUtils;
@@ -34,7 +34,6 @@
 import org.apache.hadoop.fs.RemoteIterator;
 import org.apache.hadoop.fs.permission.FsAction;
 import org.apache.hadoop.fs.permission.FsPermission;
-import org.apache.hadoop.hdfs.DFSConfigKeys;
 import org.apache.hadoop.hdfs.HdfsConfiguration;
 import org.apache.hadoop.net.NetUtils;
 import org.apache.hadoop.registry.client.api.RegistryConstants;
@@ -65,25 +64,25 @@
 import org.apache.hadoop.yarn.util.ConverterUtils;
 import org.apache.slider.api.ClusterDescription;
 import org.apache.slider.api.ClusterNode;
-import org.apache.slider.api.InternalKeys;
-import org.apache.slider.api.OptionKeys;
-import org.apache.slider.api.ResourceKeys;
+import org.apache.slider.api.SliderApplicationApi;
 import org.apache.slider.api.SliderClusterProtocol;
 import org.apache.slider.api.StateValues;
 import org.apache.slider.api.proto.Messages;
 import org.apache.slider.api.types.ContainerInformation;
+import org.apache.slider.api.types.NodeInformationList;
 import org.apache.slider.api.types.SliderInstanceDescription;
+import org.apache.slider.client.ipc.SliderApplicationIpcClient;
 import org.apache.slider.client.ipc.SliderClusterOperations;
 import org.apache.slider.common.Constants;
 import org.apache.slider.common.SliderExitCodes;
 import org.apache.slider.common.SliderKeys;
-import org.apache.slider.common.SliderXmlConfKeys;
 import org.apache.slider.common.params.AbstractActionArgs;
 import org.apache.slider.common.params.AbstractClusterBuildingActionArgs;
 import org.apache.slider.common.params.ActionAMSuicideArgs;
 import org.apache.slider.common.params.ActionClientArgs;
 import org.apache.slider.common.params.ActionCreateArgs;
 import org.apache.slider.common.params.ActionDependencyArgs;
+import org.apache.slider.common.params.ActionDestroyArgs;
 import org.apache.slider.common.params.ActionDiagnosticArgs;
 import org.apache.slider.common.params.ActionEchoArgs;
 import org.apache.slider.common.params.ActionExistsArgs;
@@ -95,6 +94,7 @@
 import org.apache.slider.common.params.ActionKillContainerArgs;
 import org.apache.slider.common.params.ActionListArgs;
 import org.apache.slider.common.params.ActionLookupArgs;
+import org.apache.slider.common.params.ActionNodesArgs;
 import org.apache.slider.common.params.ActionPackageArgs;
 import org.apache.slider.common.params.ActionRegistryArgs;
 import org.apache.slider.common.params.ActionResolveArgs;
@@ -105,7 +105,6 @@
 import org.apache.slider.common.params.ClientArgs;
 import org.apache.slider.common.params.CommonArgs;
 import org.apache.slider.common.params.LaunchArgsAccessor;
-import org.apache.slider.common.params.SliderActions;
 import org.apache.slider.common.tools.ConfigHelper;
 import org.apache.slider.common.tools.Duration;
 import org.apache.slider.common.tools.SliderFileSystem;
@@ -131,7 +130,6 @@
 import org.apache.slider.core.exceptions.WaitTimeoutException;
 import org.apache.slider.core.launch.AppMasterLauncher;
 import org.apache.slider.core.launch.ClasspathConstructor;
-import org.apache.slider.core.launch.CommandLineBuilder;
 import org.apache.slider.core.launch.JavaCommandLineBuilder;
 import org.apache.slider.core.launch.LaunchedApplication;
 import org.apache.slider.core.launch.RunningApplication;
@@ -140,6 +138,7 @@
 import org.apache.slider.core.persist.AppDefinitionPersister;
 import org.apache.slider.core.persist.ApplicationReportSerDeser;
 import org.apache.slider.core.persist.ConfPersister;
+import org.apache.slider.core.persist.JsonSerDeser;
 import org.apache.slider.core.persist.LockAcquireFailedException;
 import org.apache.slider.core.registry.SliderRegistryUtils;
 import org.apache.slider.core.registry.YarnAppListClient;
@@ -173,7 +172,6 @@
 
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FilenameFilter;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -202,38 +200,13 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import static org.apache.hadoop.registry.client.binding.RegistryUtils.ServiceRecordMarshal;
-import static org.apache.hadoop.registry.client.binding.RegistryUtils.currentUser;
-import static org.apache.hadoop.registry.client.binding.RegistryUtils.extractServiceRecords;
-import static org.apache.hadoop.registry.client.binding.RegistryUtils.listServiceRecords;
-import static org.apache.hadoop.registry.client.binding.RegistryUtils.servicePath;
-import static org.apache.hadoop.registry.client.binding.RegistryUtils.serviceclassPath;
-import static org.apache.hadoop.registry.client.binding.RegistryUtils.statChildren;
-import static org.apache.slider.common.params.SliderActions.ACTION_AM_SUICIDE;
-import static org.apache.slider.common.params.SliderActions.ACTION_BUILD;
-import static org.apache.slider.common.params.SliderActions.ACTION_CLIENT;
-import static org.apache.slider.common.params.SliderActions.ACTION_CREATE;
-import static org.apache.slider.common.params.SliderActions.ACTION_DEPENDENCY;
-import static org.apache.slider.common.params.SliderActions.ACTION_DESTROY;
-import static org.apache.slider.common.params.SliderActions.ACTION_DIAGNOSTICS;
-import static org.apache.slider.common.params.SliderActions.ACTION_EXISTS;
-import static org.apache.slider.common.params.SliderActions.ACTION_FLEX;
-import static org.apache.slider.common.params.SliderActions.ACTION_FREEZE;
-import static org.apache.slider.common.params.SliderActions.ACTION_HELP;
-import static org.apache.slider.common.params.SliderActions.ACTION_INSTALL_KEYTAB;
-import static org.apache.slider.common.params.SliderActions.ACTION_INSTALL_PACKAGE;
-import static org.apache.slider.common.params.SliderActions.ACTION_KEYTAB;
-import static org.apache.slider.common.params.SliderActions.ACTION_KILL_CONTAINER;
-import static org.apache.slider.common.params.SliderActions.ACTION_LIST;
-import static org.apache.slider.common.params.SliderActions.ACTION_LOOKUP;
-import static org.apache.slider.common.params.SliderActions.ACTION_PACKAGE;
-import static org.apache.slider.common.params.SliderActions.ACTION_REGISTRY;
-import static org.apache.slider.common.params.SliderActions.ACTION_RESOLVE;
-import static org.apache.slider.common.params.SliderActions.ACTION_STATUS;
-import static org.apache.slider.common.params.SliderActions.ACTION_THAW;
-import static org.apache.slider.common.params.SliderActions.ACTION_UPDATE;
-import static org.apache.slider.common.params.SliderActions.ACTION_UPGRADE;
-import static org.apache.slider.common.params.SliderActions.ACTION_VERSION;
+import static org.apache.hadoop.registry.client.binding.RegistryUtils.*;
+import static org.apache.slider.api.InternalKeys.*;
+import static org.apache.slider.api.OptionKeys.*;
+import static org.apache.slider.api.ResourceKeys.*;
+import static org.apache.slider.common.params.SliderActions.*;
+import static org.apache.slider.common.tools.SliderUtils.*;
+
 
 /**
  * Client service for Slider
@@ -286,6 +259,7 @@
   /**
    * The YARN registry service
    */
+  @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
   private RegistryOperations registryOperations;
 
   /**
@@ -316,19 +290,19 @@
     ConfigHelper.injectSliderXMLResource();
     // yarn-ify
     YarnConfiguration yarnConfiguration = new YarnConfiguration(config);
-    return SliderUtils.patchConfiguration(yarnConfiguration);
+    return patchConfiguration(yarnConfiguration);
   }
 
   @Override
   protected void serviceInit(Configuration conf) throws Exception {
-    Configuration clientConf = SliderUtils.loadSliderClientXML();
+    Configuration clientConf = loadSliderClientXML();
     ConfigHelper.mergeConfigurations(conf, clientConf, SLIDER_CLIENT_XML, true);
     serviceArgs.applyDefinitions(conf);
     serviceArgs.applyFileSystemBinding(conf);
     // init security with our conf
-    if (SliderUtils.isHadoopClusterSecure(conf)) {
-      SliderUtils.forceLogin();
-      SliderUtils.initProcessSecurity(conf);
+    if (isHadoopClusterSecure(conf)) {
+      forceLogin();
+      initProcessSecurity(conf);
     }
     AbstractActionArgs coreAction = serviceArgs.getCoreAction();
     if (coreAction.getHadoopServicesRequired()) {
@@ -338,90 +312,6 @@
   }
 
   /**
-   * this is where the work is done.
-   * @return the exit code
-   * @throws Throwable anything that went wrong
-   */
-/* JDK7
-
-  @Override
-  public int runService() throws Throwable {
-
-    // choose the action
-    String action = serviceArgs.getAction();
-    int exitCode = EXIT_SUCCESS;
-    String clusterName = serviceArgs.getClusterName();
-    // actions
-    switch (action) {
-      case ACTION_BUILD:
-        exitCode = actionBuild(clusterName, serviceArgs.getActionBuildArgs());
-        break;
-      case ACTION_UPDATE:
-        exitCode = actionUpdate(clusterName, serviceArgs.getActionUpdateArgs());
-        break;
-      case ACTION_UPGRADE:
-        exitCode = actionUpgrade(clusterName, serviceArgs.getActionUpgradeArgs());
-        break;
-      case ACTION_CREATE:
-        exitCode = actionCreate(clusterName, serviceArgs.getActionCreateArgs());
-        break;
-      case ACTION_FREEZE:
-        exitCode = actionFreeze(clusterName, serviceArgs.getActionFreezeArgs());
-        break;
-      case ACTION_THAW:
-        exitCode = actionThaw(clusterName, serviceArgs.getActionThawArgs());
-        break;
-      case ACTION_DESTROY:
-        exitCode = actionDestroy(clusterName);
-        break;
-      case ACTION_EXISTS:
-        exitCode = actionExists(clusterName,
-            serviceArgs.getActionExistsArgs().live);
-        break;
-      case ACTION_FLEX:
-        exitCode = actionFlex(clusterName, serviceArgs.getActionFlexArgs());
-        break;
-      case ACTION_GETCONF:
-        exitCode =
-            actionGetConf(clusterName, serviceArgs.getActionGetConfArgs());
-        break;
-      case ACTION_HELP:
-      case ACTION_USAGE:
-        log.info(serviceArgs.usage());
-        break;
-      case ACTION_KILL_CONTAINER:
-        exitCode = actionKillContainer(clusterName,
-            serviceArgs.getActionKillContainerArgs());
-        break;
-      case ACTION_AM_SUICIDE:
-        exitCode = actionAmSuicide(clusterName,
-            serviceArgs.getActionAMSuicideArgs());
-        break;
-      case ACTION_LIST:
-        exitCode = actionList(clusterName, serviceArgs.getActionListArgs());
-        break;
-      case ACTION_REGISTRY:
-        exitCode = actionRegistry(
-            serviceArgs.getActionRegistryArgs());
-        break;
-      case ACTION_STATUS:
-        exitCode = actionStatus(clusterName,
-            serviceArgs.getActionStatusArgs());
-        break;
-      case ACTION_VERSION:
-        exitCode = actionVersion();
-        break;
-      default:
-        throw new SliderException(EXIT_UNIMPLEMENTED,
-            "Unimplemented: " + action);
-    }
-
-    return exitCode;
-  }
-
-*/
-
-  /**
    * Launched service execution. This runs {@link #exec()}
    * then catches some exceptions and converts them to exit codes
    * @return an exit code
@@ -445,11 +335,10 @@
 
     // choose the action
     String action = serviceArgs.getAction();
-    if (SliderUtils.isUnset(action)) {
-      throw new SliderException(EXIT_USAGE,
-          serviceArgs.usage());
+    if (isUnset(action)) {
+      throw new SliderException(EXIT_USAGE, serviceArgs.usage());
     }
-      
+
     int exitCode = EXIT_SUCCESS;
     String clusterName = serviceArgs.getClusterName();
     // actions
@@ -477,7 +366,7 @@
         break;
 
       case ACTION_DESTROY:
-        exitCode = actionDestroy(clusterName);
+        exitCode = actionDestroy(clusterName, serviceArgs.getActionDestroyArgs());
         break;
 
       case ACTION_DIAGNOSTICS:
@@ -507,8 +396,7 @@
         break;
       
       case ACTION_INSTALL_KEYTAB:
-        exitCode =
-            actionInstallKeytab(serviceArgs.getActionInstallKeytabArgs());
+        exitCode = actionInstallKeytab(serviceArgs.getActionInstallKeytabArgs());
         break;
       
       case ACTION_INSTALL_PACKAGE:
@@ -522,11 +410,15 @@
       case ACTION_LIST:
         exitCode = actionList(clusterName, serviceArgs.getActionListArgs());
         break;
-      
+
       case ACTION_LOOKUP:
         exitCode = actionLookup(serviceArgs.getActionLookupArgs());
         break;
 
+      case ACTION_NODES:
+        exitCode = actionNodes("", serviceArgs.getActionNodesArgs());
+        break;
+
       case ACTION_PACKAGE:
         exitCode = actionPackage(serviceArgs.getActionPackageArgs());
         break;
@@ -567,7 +459,7 @@
     return exitCode;
   }
 
-/**
+  /**
    * Perform everything needed to init the hadoop binding.
    * This assumes that the service is already  in inited or started state
    * @throws IOException
@@ -575,7 +467,7 @@
    */
   protected void initHadoopBinding() throws IOException, SliderException {
     // validate the client
-    SliderUtils.validateSliderClientEnvironment(null);
+    validateSliderClientEnvironment(null);
     //create the YARN client
     yarnClient = new SliderYarnClientImpl();
     yarnClient.init(getConfig());
@@ -586,7 +478,7 @@
     yarnAppListClient =
         new YarnAppListClient(yarnClient, getUsername(), getConfig());
     // create the filesystem
-    sliderFileSystem = new SliderFileSystem(getConfig());    
+    sliderFileSystem = new SliderFileSystem(getConfig());
   }
 
   /**
@@ -620,6 +512,13 @@
 
   /**
    * Create the zookeeper node associated with the calling user and the cluster
+   *
+   * @param clusterName slider application name
+   * @param nameOnly should the name only be created (i.e. don't create ZK node)
+   * @return the path, using the policy implemented in
+   *   {@link ZKIntegration#mkClusterPath(String, String)}
+   * @throws YarnException
+   * @throws IOException
    */
   @VisibleForTesting
   public String createZookeeperNode(String clusterName, Boolean nameOnly) throws YarnException, IOException {
@@ -639,7 +538,8 @@
    * -throwing exceptions on any failure
    * @param clusterName cluster name
    * @param nameOnly create the path, not the node
-   * @return the path, with the node created
+   * @return the path, using the policy implemented in
+   *   {@link ZKIntegration#mkClusterPath(String, String)}
    * @throws YarnException
    * @throws IOException
    * @throws KeeperException
@@ -657,7 +557,7 @@
     if (client != null) {
       // set up the permissions. This must be done differently on a secure cluster from an insecure
       // one
-      List<ACL> zkperms = new ArrayList<ACL>();
+      List<ACL> zkperms = new ArrayList<>();
       if (UserGroupInformation.isSecurityEnabled()) {
         zkperms.add(new ACL(ZooDefs.Perms.ALL, ZooDefs.Ids.AUTH_IDS));
         zkperms.add(new ACL(ZooDefs.Perms.READ, ZooDefs.Ids.ANYONE_ID_UNSAFE));
@@ -681,7 +581,8 @@
     ZKIntegration client = null;
     try {
       BlockingZKWatcher watcher = new BlockingZKWatcher();
-      client = ZKIntegration.newInstance(registryQuorum, user, clusterName, true, false, watcher);
+      client = ZKIntegration.newInstance(registryQuorum, user, clusterName, true, false, watcher,
+          ZKIntegration.SESSION_TIMEOUT);
       client.init();
       watcher.waitForZKConnection(2 * 1000);
     } catch (InterruptedException e) {
@@ -693,14 +594,28 @@
     return client;
   }
 
+  /**
+   * Keep this signature for backward compatibility with
+   * force=true by default.
+   */
   @Override
   public int actionDestroy(String clustername) throws YarnException,
                                                       IOException {
+    ActionDestroyArgs destroyArgs = new ActionDestroyArgs();
+    destroyArgs.force = true;
+    return actionDestroy(clustername, destroyArgs);
+  }
+
+  @Override
+  public int actionDestroy(String clustername,
+      ActionDestroyArgs destroyArgs) throws YarnException, IOException {
     // verify that a live cluster isn't there
-    SliderUtils.validateClusterName(clustername);
+    validateClusterName(clustername);
     //no=op, it is now mandatory. 
     verifyBindingsDefined();
     verifyNoLiveClusters(clustername, "Destroy");
+    boolean forceDestroy = destroyArgs.force;
+    log.debug("actionDestroy({}, force={})", clustername, forceDestroy);
 
     // create the directory path
     Path clusterDirectory = sliderFileSystem.buildClusterDirPath(clustername);
@@ -709,9 +624,12 @@
     boolean exists = fs.exists(clusterDirectory);
     if (exists) {
       log.debug("Application Instance {} found at {}: destroying", clustername, clusterDirectory);
-      boolean deleted =
-          fs.delete(clusterDirectory, true);
-      if (!deleted) {
+      if (!forceDestroy) {
+        // fail the command if --force is not explicitly specified
+        throw new UsageException("Destroy will permanently delete directories and registries. "
+            + "Reissue this command with the --force option if you want to proceed.");
+      }
+      if (!fs.delete(clusterDirectory, true)) {
         log.warn("Filesystem returned false from delete() operation");
       }
 
@@ -807,33 +725,26 @@
     // Otherwise the internal app config and resources states of the app will be
     // unwantedly modified and the change will take effect to the running app
     // immediately.
-    if (template != null && resources == null) {
-      throw new BadCommandArgumentsException(
+    require(!(template != null && resources == null),
           "Option %s must be specified with option %s",
           Arguments.ARG_RESOURCES, Arguments.ARG_TEMPLATE);
-    }
-    if (resources != null && template == null) {
-      throw new BadCommandArgumentsException(
+
+    require(!(resources != null && template == null),
           "Option %s must be specified with option %s",
           Arguments.ARG_TEMPLATE, Arguments.ARG_RESOURCES);
-    }
 
     // For upgrade spec, both --template and --resources should be specified
     // and neither of --containers or --components should be used
     if (template != null && resources != null) {
-      if (CollectionUtils.isNotEmpty(containers)) {
-        throw new BadCommandArgumentsException(
+      require(CollectionUtils.isEmpty(containers),
             "Option %s cannot be specified with %s or %s",
             Arguments.ARG_CONTAINERS, Arguments.ARG_TEMPLATE,
             Arguments.ARG_RESOURCES);
-      }
-      if (CollectionUtils.isNotEmpty(components)) {
-        throw new BadCommandArgumentsException(
-            "Option %s cannot be specified with %s or %s",
-            Arguments.ARG_COMPONENTS, Arguments.ARG_TEMPLATE,
-            Arguments.ARG_RESOURCES);
-      }
-      
+      require(CollectionUtils.isEmpty(components),
+              "Option %s cannot be specified with %s or %s",
+              Arguments.ARG_COMPONENTS, Arguments.ARG_TEMPLATE,
+              Arguments.ARG_RESOURCES);
+
       // not an error to try to upgrade a stopped cluster, just return success
       // code, appropriate log messages have already been dumped
       if (!isAppInRunningState(clustername)) {
@@ -858,7 +769,7 @@
   private int actionUpgradeContainers(String clustername,
       ActionUpgradeArgs upgradeArgs) throws YarnException, IOException {
     verifyBindingsDefined();
-    SliderUtils.validateClusterName(clustername);
+    validateClusterName(clustername);
     int waittime = upgradeArgs.getWaittime(); // ignored for now
     String text = "Upgrade containers";
     log.debug("actionUpgradeContainers({}, reason={}, wait={})", clustername,
@@ -956,13 +867,10 @@
       return false;
     }
     log.debug("App to upgrade was found: {}:\n{}", clustername,
-        new SliderUtils.OnDemandReportStringifier(app));
-    if (app.getYarnApplicationState().ordinal() >= YarnApplicationState.FINISHED
-        .ordinal()) {
-      log.info(
-          "Cluster {} is in a terminated state {}. Use command '{}' instead.",
-          clustername, app.getYarnApplicationState(),
-          SliderActions.ACTION_UPDATE);
+        new OnDemandReportStringifier(app));
+    if (app.getYarnApplicationState().ordinal() >= YarnApplicationState.FINISHED.ordinal()) {
+      log.info("Cluster {} is in a terminated state {}. Use command '{}' instead.",
+          clustername, app.getYarnApplicationState(), ACTION_UPDATE);
       return false;
     }
 
@@ -979,7 +887,7 @@
 
   private static void checkForCredentials(Configuration conf,
       ConfTree tree) throws IOException {
-    if (tree.credentials == null || tree.credentials.size()==0) {
+    if (tree.credentials == null || tree.credentials.isEmpty()) {
       log.info("No credentials requested");
       return;
     }
@@ -994,10 +902,8 @@
         }
         Configuration c = new Configuration(conf);
         c.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, provider);
-        CredentialProvider credentialProvider =
-            CredentialProviderFactory.getProviders(c).get(0);
-        Set<String> existingAliases =
-            new HashSet<>(credentialProvider.getAliases());
+        CredentialProvider credentialProvider = CredentialProviderFactory.getProviders(c).get(0);
+        Set<String> existingAliases = new HashSet<>(credentialProvider.getAliases());
         for (String alias : aliases) {
           if (existingAliases.contains(alias.toLowerCase(Locale.ENGLISH))) {
             log.info("Credentials for " + alias + " found in " + provider);
@@ -1013,21 +919,13 @@
         }
       }
     } finally {
-      if (br != null) {
-        br.close();
-      }
+      org.apache.hadoop.io.IOUtils.closeStream(br);
     }
   }
 
   private static char[] readOnePassword(String alias) throws IOException {
-    BufferedReader br = null;
-    try {
-      br = new BufferedReader(new InputStreamReader(System.in));
+    try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
       return readPassword(alias, br);
-    } finally {
-      if (br != null) {
-        br.close();
-      }
     }
   }
 
@@ -1113,12 +1011,9 @@
 
     Path fileInFs = new Path(pkgPath, keytabInfo.keytab );
     log.info("Deleting keytab {}", fileInFs);
-    if (!sliderFileSystem.getFileSystem().exists(fileInFs)) {
-      throw new BadCommandArgumentsException("No keytab to delete found at " +
-                                             fileInFs.toUri().toString());
-    }
-
-    sliderFileSystem.getFileSystem().delete(fileInFs, false);
+    FileSystem sfs = sliderFileSystem.getFileSystem();
+    require(sfs.exists(fileInFs), "No keytab to delete found at %s", fileInFs.toUri());
+    sfs.delete(fileInFs, false);
 
     return EXIT_SUCCESS;
   }
@@ -1126,40 +1021,31 @@
   private int actionInstallKeytab(ActionKeytabArgs keytabInfo)
       throws BadCommandArgumentsException, IOException {
     Path srcFile = null;
-    if (StringUtils.isEmpty(keytabInfo.folder)) {
-      throw new BadCommandArgumentsException(
-          "A valid destination keytab sub-folder name is required (e.g. 'security').\n"
-          + CommonArgs.usage(serviceArgs, ACTION_KEYTAB));
-    }
+    require(isSet(keytabInfo.folder),
+        "A valid destination keytab sub-folder name is required (e.g. 'security').\n"
+        + CommonArgs.usage(serviceArgs, ACTION_KEYTAB));
 
-    if (StringUtils.isEmpty(keytabInfo.keytab)) {
-      throw new BadCommandArgumentsException("A valid local keytab location is required.");
-    } else {
-      File keytabFile = new File(keytabInfo.keytab);
-      if (!keytabFile.exists() || keytabFile.isDirectory()) {
-        throw new BadCommandArgumentsException("Unable to access supplied keytab file at " +
-                                               keytabFile.getAbsolutePath());
-      } else {
-        srcFile = new Path(keytabFile.toURI());
-      }
-    }
+    requireArgumentSet(Arguments.ARG_KEYTAB, keytabInfo.keytab);
+    File keytabFile = new File(keytabInfo.keytab);
+    require(keytabFile.isFile(),
+        "Unable to access supplied keytab file at %s", keytabFile.getAbsolutePath());
+    srcFile = new Path(keytabFile.toURI());
 
     Path pkgPath = sliderFileSystem.buildKeytabInstallationDirPath(keytabInfo.folder);
-    sliderFileSystem.getFileSystem().mkdirs(pkgPath);
-    sliderFileSystem.getFileSystem().setPermission(pkgPath, new FsPermission(
+    FileSystem sfs = sliderFileSystem.getFileSystem();
+    sfs.mkdirs(pkgPath);
+    sfs.setPermission(pkgPath, new FsPermission(
         FsAction.ALL, FsAction.NONE, FsAction.NONE));
 
     Path fileInFs = new Path(pkgPath, srcFile.getName());
-    log.info("Installing keytab {} at {} and overwrite is {}.", srcFile, fileInFs, keytabInfo.overwrite);
-    if (sliderFileSystem.getFileSystem().exists(fileInFs) && !keytabInfo.overwrite) {
-      throw new BadCommandArgumentsException("Keytab exists at " +
-                                             fileInFs.toUri().toString() +
-                                             ". Use --overwrite to overwrite.");
-    }
+    log.info("Installing keytab {} at {} and overwrite is {}.",
+        srcFile, fileInFs, keytabInfo.overwrite);
+    require(!(sfs.exists(fileInFs) && !keytabInfo.overwrite),
+        "Keytab exists at %s. Use --overwrite to overwrite.", fileInFs.toUri());
 
-    sliderFileSystem.getFileSystem().copyFromLocalFile(false, keytabInfo.overwrite, srcFile, fileInFs);
-    sliderFileSystem.getFileSystem().setPermission(fileInFs, new FsPermission(
-        FsAction.READ_WRITE, FsAction.NONE, FsAction.NONE));
+    sfs.copyFromLocalFile(false, keytabInfo.overwrite, srcFile, fileInFs);
+    sfs.setPermission(fileInFs,
+        new FsPermission(FsAction.READ_WRITE, FsAction.NONE, FsAction.NONE));
 
     return EXIT_SUCCESS;
   }
@@ -1175,44 +1061,29 @@
   public int actionInstallPkg(ActionInstallPackageArgs installPkgInfo) throws
       YarnException,
       IOException {
-    log.warn("The " + SliderActions.ACTION_INSTALL_PACKAGE
+    log.warn("The " + ACTION_INSTALL_PACKAGE
         + " option has been deprecated. Please use '"
-        + SliderActions.ACTION_PACKAGE + " " + ClientArgs.ARG_INSTALL + "'.");
-    Path srcFile = null;
+        + ACTION_PACKAGE + " " + ClientArgs.ARG_INSTALL + "'.");
     if (StringUtils.isEmpty(installPkgInfo.name)) {
       throw new BadCommandArgumentsException(
-          E_INVALID_APPLICATION_TYPE_NAME +"\n"
+          E_INVALID_APPLICATION_TYPE_NAME + "\n"
               + CommonArgs.usage(serviceArgs, ACTION_INSTALL_PACKAGE));
     }
-
-    if (StringUtils.isEmpty(installPkgInfo.packageURI)) {
-      throw new BadCommandArgumentsException(E_INVALID_APPLICATION_PACKAGE_LOCATION);
-    } else {
-      File pkgFile = new File(installPkgInfo.packageURI);
-      if (!pkgFile.exists() || pkgFile.isDirectory()) {
-        throw new BadCommandArgumentsException(
-            E_UNABLE_TO_READ_SUPPLIED_PACKAGE_FILE +": "
-                + pkgFile.getAbsolutePath());
-      } else {
-        srcFile = new Path(pkgFile.toURI());
-      }
-    }
+    Path srcFile = extractPackagePath(installPkgInfo.packageURI);
 
     // Do not provide new options to install-package command as it is in
     // deprecated mode. So version is kept null here. Use package --install.
     Path pkgPath = sliderFileSystem.buildPackageDirPath(installPkgInfo.name,
         null);
-    sliderFileSystem.getFileSystem().mkdirs(pkgPath);
+    FileSystem sfs = sliderFileSystem.getFileSystem();
+    sfs.mkdirs(pkgPath);
 
     Path fileInFs = new Path(pkgPath, srcFile.getName());
-    log.info("Installing package {} at {} and overwrite is {}.", srcFile, fileInFs, installPkgInfo.replacePkg);
-    if (sliderFileSystem.getFileSystem().exists(fileInFs) && !installPkgInfo.replacePkg) {
-      throw new BadCommandArgumentsException(
-          "Package exists at " + fileInFs.toUri().toString() +"."
-              + E_USE_REPLACEPKG_TO_OVERWRITE);
-    }
-
-    sliderFileSystem.getFileSystem().copyFromLocalFile(false, installPkgInfo.replacePkg, srcFile, fileInFs);
+    log.info("Installing package {} at {} and overwrite is {}.",
+        srcFile, fileInFs, installPkgInfo.replacePkg);
+    require(!(sfs.exists(fileInFs) && !installPkgInfo.replacePkg),
+          "Package exists at %s. : %s", fileInFs.toUri(), E_USE_REPLACEPKG_TO_OVERWRITE);
+    sfs.copyFromLocalFile(false, installPkgInfo.replacePkg, srcFile, fileInFs);
     return EXIT_SUCCESS;
   }
 
@@ -1241,11 +1112,7 @@
           + CommonArgs.usage(serviceArgs, ACTION_CLIENT));
     }
 
-    if (clientInfo.name == null) {
-      throw new BadCommandArgumentsException("No application name specified\n"
-                                             + CommonArgs.usage(serviceArgs,
-                                                                ACTION_CLIENT));
-    }
+    requireArgumentSet(Arguments.ARG_NAME, clientInfo.name);
 
     File storeFile = null;
     SecurityStore.StoreType type;
@@ -1257,11 +1124,9 @@
       type = SecurityStore.StoreType.truststore;
     }
 
-    if (storeFile.exists()) {
-      throw new BadCommandArgumentsException("File %s already exists.  "
-                                             + "Please remove that file or select a different file name.",
-                                             storeFile.getAbsolutePath());
-    }
+    require (!storeFile.exists(),
+        "File %s already exists.  Please remove that file or select a different file name.",
+         storeFile.getAbsolutePath());
     String hostname = null;
     if (type == SecurityStore.StoreType.keystore) {
       hostname = clientInfo.hostname;
@@ -1296,10 +1161,8 @@
       }
     }
 
-    byte[]
-        keystore =
-        createClusterOperations(clientInfo.name).getClientCertificateStore(
-            hostname, "client", password, type.name());
+    byte[] keystore = createClusterOperations(clientInfo.name)
+        .getClientCertificateStore(hostname, "client", password, type.name());
     // persist to file
     IOUtils.write(keystore, new FileOutputStream(storeFile));
 
@@ -1309,31 +1172,20 @@
   private int doClientInstall(ActionClientArgs clientInfo)
       throws IOException, SliderException {
 
-    if (clientInfo.installLocation == null) {
-      throw new BadCommandArgumentsException(
+    require(clientInfo.installLocation != null,
           E_INVALID_INSTALL_LOCATION +"\n"
           + CommonArgs.usage(serviceArgs, ACTION_CLIENT));
-    } else {
-      if (!clientInfo.installLocation.exists()) {
-        throw new BadCommandArgumentsException(E_INSTALL_PATH_DOES_NOT_EXIST
-            +": " + clientInfo.installLocation.getAbsolutePath());
-      }
-      if (!clientInfo.installLocation.isDirectory()) {
-        throw new BadCommandArgumentsException(E_INVALID_INSTALL_PATH
-            +": " + clientInfo.installLocation.getAbsolutePath());
-      }
-    }
+    require(clientInfo.installLocation.exists(),
+        E_INSTALL_PATH_DOES_NOT_EXIST + ": " + clientInfo.installLocation.getAbsolutePath());
+
+    require(clientInfo.installLocation.isDirectory(),
+        E_INVALID_INSTALL_PATH + ": " + clientInfo.installLocation.getAbsolutePath());
 
     File pkgFile;
-    if (StringUtils.isEmpty(clientInfo.packageURI)) {
-      throw new BadCommandArgumentsException(E_INVALID_APPLICATION_PACKAGE_LOCATION);
-    } else {
-      pkgFile = new File(clientInfo.packageURI);
-      if (!pkgFile.exists() || pkgFile.isDirectory()) {
-        throw new BadCommandArgumentsException(E_UNABLE_TO_READ_SUPPLIED_PACKAGE_FILE
-            +" at " + pkgFile.getAbsolutePath());
-      }
-    }
+    require(isSet(clientInfo.packageURI), E_INVALID_APPLICATION_PACKAGE_LOCATION);
+    pkgFile = new File(clientInfo.packageURI);
+    require(pkgFile.isFile(),
+        E_UNABLE_TO_READ_SUPPLIED_PACKAGE_FILE + " at %s", pkgFile.getAbsolutePath());
 
     JSONObject config = null;
     if(clientInfo.clientConfig != null) {
@@ -1432,7 +1284,7 @@
       Path appDefPath = null;
       try {
         appDefPath = new Path(
-            SliderUtils.getApplicationDefinitionPath(instanceDefinition
+            getApplicationDefinitionPath(instanceDefinition
                 .getAppConfOperations()));
       } catch (BadConfigException e) {
         // Invalid cluster state, so move on to next. No need to log anything
@@ -1454,11 +1306,8 @@
           println("%-25s  %15s  %30s  %s", clusterName, packageName,
               packageVersion, appDefPathStr);
         }
-      } catch(IOException e) {
-        if(log.isDebugEnabled()) {
-          log.debug(clusterName + " application definition path "
-              + appDefPathStr + " is not found.");
-        }
+      } catch (IOException e) {
+        log.debug("{} application definition path {} is not found.", clusterName, appDefPathStr);
       }
     }
     return EXIT_SUCCESS;
@@ -1467,19 +1316,19 @@
   private int actionPackageList() throws IOException {
     Path pkgPath = sliderFileSystem.buildPackageDirPath(StringUtils.EMPTY,
         StringUtils.EMPTY);
-    log.info("Package install path : " + pkgPath);
-    if (!sliderFileSystem.getFileSystem().isDirectory(pkgPath)) {
+    log.info("Package install path : {}", pkgPath);
+    FileSystem sfs = sliderFileSystem.getFileSystem();
+    if (!sfs.isDirectory(pkgPath)) {
       log.info("No package(s) installed");
       return EXIT_SUCCESS;
     }
-    FileStatus[] fileStatus = sliderFileSystem.getFileSystem().listStatus(
-        pkgPath);
+    FileStatus[] fileStatus = sfs.listStatus(pkgPath);
     boolean hasPackage = false;
     StringBuilder sb = new StringBuilder();
     sb.append("List of installed packages:\n");
     for (FileStatus fstat : fileStatus) {
       if (fstat.isDirectory()) {
-        sb.append("\t" + fstat.getPath().getName());
+        sb.append("\t").append(fstat.getPath().getName());
         sb.append("\n");
         hasPackage = true;
       }
@@ -1492,53 +1341,31 @@
     return EXIT_SUCCESS;
   }
 
-  private int actionPackageInstall(ActionPackageArgs actionPackageArgs) throws
-      YarnException,
-      IOException {
+  private int actionPackageInstall(ActionPackageArgs actionPackageArgs)
+      throws YarnException, IOException {
+    requireArgumentSet(Arguments.ARG_NAME, actionPackageArgs.name);
 
-    Path srcFile = null;
-    if (StringUtils.isEmpty(actionPackageArgs.name)) {
-      throw new BadCommandArgumentsException(
-          "A valid application type name is required (e.g. HBASE).\n"
-              + CommonArgs.usage(serviceArgs, ACTION_PACKAGE));
-    }
-
-    if (StringUtils.isEmpty(actionPackageArgs.packageURI)) {
-      throw new BadCommandArgumentsException(
-          E_INVALID_APPLICATION_PACKAGE_LOCATION);
-    } else {
-      File pkgFile = new File(actionPackageArgs.packageURI);
-      if (!pkgFile.exists() || pkgFile.isDirectory()) {
-        throw new BadCommandArgumentsException(
-            E_UNABLE_TO_READ_SUPPLIED_PACKAGE_FILE
-                + ":  " + pkgFile.getAbsolutePath());
-      } else {
-        srcFile = new Path(pkgFile.toURI());
-      }
-    }
+    Path srcFile = extractPackagePath(actionPackageArgs.packageURI);
 
     Path pkgPath = sliderFileSystem.buildPackageDirPath(actionPackageArgs.name,
         actionPackageArgs.version);
-    if (!sliderFileSystem.getFileSystem().exists(pkgPath)) {
-      sliderFileSystem.getFileSystem().mkdirs(pkgPath);
+    FileSystem fs = sliderFileSystem.getFileSystem();
+    if (!fs.exists(pkgPath)) {
+      fs.mkdirs(pkgPath);
     }
 
     Path fileInFs = new Path(pkgPath, srcFile.getName());
-    if (sliderFileSystem.getFileSystem().exists(fileInFs)
-        && !actionPackageArgs.replacePkg) {
-      throw new BadCommandArgumentsException(E_PACKAGE_EXISTS +" at " +
-           fileInFs.toUri() + ". Use --replacepkg to overwrite.");
-    }
+    require(actionPackageArgs.replacePkg || !fs.exists(fileInFs),
+        E_PACKAGE_EXISTS +" at  %s. Use --replacepkg to overwrite.", fileInFs.toUri());
 
     log.info("Installing package {} to {} (overwrite set to {})", srcFile,
         fileInFs, actionPackageArgs.replacePkg);
-    sliderFileSystem.getFileSystem().copyFromLocalFile(false,
-        actionPackageArgs.replacePkg, srcFile, fileInFs);
+    fs.copyFromLocalFile(false, actionPackageArgs.replacePkg, srcFile, fileInFs);
 
     String destPathWithHomeDir = Path
         .getPathWithoutSchemeAndAuthority(fileInFs).toString();
     String destHomeDir = Path.getPathWithoutSchemeAndAuthority(
-        sliderFileSystem.getFileSystem().getHomeDirectory()).toString();
+        fs.getHomeDirectory()).toString();
     // a somewhat contrived approach to stripping out the home directory and any trailing
     // separator; designed to work on windows and unix
     String destPathWithoutHomeDir;
@@ -1556,23 +1383,26 @@
     return EXIT_SUCCESS;
   }
 
+  private Path extractPackagePath(String packageURI)
+      throws BadCommandArgumentsException {
+    require(isSet(packageURI), E_INVALID_APPLICATION_PACKAGE_LOCATION);
+    File pkgFile = new File(packageURI);
+    require(pkgFile.isFile(),
+        E_UNABLE_TO_READ_SUPPLIED_PACKAGE_FILE + ":  " + pkgFile.getAbsolutePath());
+    return new Path(pkgFile.toURI());
+  }
+
   private int actionPackageDelete(ActionPackageArgs actionPackageArgs) throws
       YarnException, IOException {
-    if (StringUtils.isEmpty(actionPackageArgs.name)) {
-      throw new BadCommandArgumentsException(
-          "A valid application type name is required (e.g. HBASE).\n"
-              + CommonArgs.usage(serviceArgs, ACTION_PACKAGE));
-    }
+    requireArgumentSet(Arguments.ARG_NAME, actionPackageArgs.name);
 
     Path pkgPath = sliderFileSystem.buildPackageDirPath(actionPackageArgs.name,
         actionPackageArgs.version);
-    if (!sliderFileSystem.getFileSystem().exists(pkgPath)) {
-      throw new BadCommandArgumentsException(E_PACKAGE_DOES_NOT_EXIST +": "
-          + pkgPath.toUri().toString());
-    }
+    FileSystem fs = sliderFileSystem.getFileSystem();
+    require(fs.exists(pkgPath), E_PACKAGE_DOES_NOT_EXIST +": %s ", pkgPath.toUri());
     log.info("Deleting package {} at {}.", actionPackageArgs.name, pkgPath);
 
-    if(sliderFileSystem.getFileSystem().delete(pkgPath, true)) {
+    if(fs.delete(pkgPath, true)) {
       log.info("Deleted package {} " + actionPackageArgs.name);
       return EXIT_SUCCESS;
     } else {
@@ -1612,7 +1442,7 @@
       boolean liveClusterAllowed, boolean isUpgradeFlow) throws YarnException,
       IOException {
     // verify that a live cluster isn't there
-    SliderUtils.validateClusterName(clustername);
+    validateClusterName(clustername);
     verifyBindingsDefined();
     if (!liveClusterAllowed) {
       verifyNoLiveClusters(clustername, "Create");
@@ -1691,8 +1521,7 @@
       String count = roleEntry.getValue();
       String key = roleEntry.getKey();
       log.info("{} => {}", key, count);
-      resources.getOrAddComponent(key)
-                 .put(ResourceKeys.COMPONENT_INSTANCES, count);
+      resources.getOrAddComponent(key).put(COMPONENT_INSTANCES, count);
     }
 
     //all CLI role options
@@ -1727,7 +1556,7 @@
     builder.setQueue(buildInfo.queue);
 
     String quorum = buildInfo.getZKhosts();
-    if (SliderUtils.isUnset(quorum)) {
+    if (isUnset(quorum)) {
       quorum = registryQuorum;
     }
     if (isUnset(quorum)) {
@@ -1799,7 +1628,7 @@
       if (!SliderKeys.COMPONENT_AM.equals(componentName)) {
         clientComponentInstances.put(componentName, clientResources
             .getComponentOptInt(componentName,
-                ResourceKeys.COMPONENT_INSTANCES, -1));
+                COMPONENT_INSTANCES, -1));
       }
     }
 
@@ -1809,8 +1638,7 @@
     } catch (LockAcquireFailedException e) {
       log.warn("Failed to get a Lock on cluster resource : {}", e, e);
       throw new BadClusterStateException(
-          "Failed to load client resource definition " + clustername + ": "
-              + e);
+          "Failed to load client resource definition " + clustername + ": " + e, e);
     }
     Map<String, Integer> clusterComponentInstances = new HashMap<>();
     for (Map.Entry<String, Map<String, String>> component : clusterConf
@@ -1819,7 +1647,7 @@
         clusterComponentInstances.put(
             component.getKey(),
             Integer.decode(component.getValue().get(
-                ResourceKeys.COMPONENT_INSTANCES)));
+                COMPONENT_INSTANCES)));
       }
     }
 
@@ -1827,16 +1655,13 @@
     Iterator<Map.Entry<String, Integer>> clientComponentInstanceIt = clientComponentInstances
         .entrySet().iterator();
     while (clientComponentInstanceIt.hasNext()) {
-      Map.Entry<String, Integer> clientComponentInstanceEntry = clientComponentInstanceIt
-          .next();
-      if (clusterComponentInstances
-          .containsKey(clientComponentInstanceEntry.getKey())) {
+      Map.Entry<String, Integer> clientComponentInstanceEntry = clientComponentInstanceIt.next();
+      if (clusterComponentInstances.containsKey(clientComponentInstanceEntry.getKey())) {
         // compare instance count now and remove from both maps if they match
         if (clusterComponentInstances
             .get(clientComponentInstanceEntry.getKey()) == clientComponentInstanceEntry
             .getValue()) {
-          clusterComponentInstances
-              .remove(clientComponentInstanceEntry.getKey());
+          clusterComponentInstances.remove(clientComponentInstanceEntry.getKey());
           clientComponentInstanceIt.remove();
         }
       }
@@ -1910,8 +1735,7 @@
 
   public FsPermission getClusterDirectoryPermissions(Configuration conf) {
     String clusterDirPermsOct =
-      conf.get(CLUSTER_DIRECTORY_PERMISSIONS,
-          DEFAULT_CLUSTER_DIRECTORY_PERMISSIONS);
+      conf.get(CLUSTER_DIRECTORY_PERMISSIONS, DEFAULT_CLUSTER_DIRECTORY_PERMISSIONS);
     return new FsPermission(clusterDirPermsOct);
   }
 
@@ -1921,9 +1745,9 @@
    * @throws BadCommandArgumentsException the exception raised on an invalid config
    */
   public void verifyBindingsDefined() throws BadCommandArgumentsException {
-    InetSocketAddress rmAddr = SliderUtils.getRmAddress(getConfig());
+    InetSocketAddress rmAddr = getRmAddress(getConfig());
     if (!getConfig().getBoolean(YarnConfiguration.RM_HA_ENABLED, false)
-     && !SliderUtils.isAddressDefined(rmAddr)) {
+     && !isAddressDefined(rmAddr)) {
       throw new BadCommandArgumentsException(
         E_NO_RESOURCE_MANAGER
         + " in the argument "
@@ -1987,9 +1811,7 @@
    * @throws UnknownApplicationInstanceException if the file is not found
    */
   public AggregateConf loadInstanceDefinitionUnresolved(String name,
-                                                         Path clusterDirectory) throws
-                                                                      IOException,
-      SliderException {
+            Path clusterDirectory) throws IOException, SliderException {
 
     try {
       AggregateConf definition =
@@ -2001,7 +1823,8 @@
       throw UnknownApplicationInstanceException.unknownInstance(name, e);
     }
   }
-    /**
+
+  /**
    * Load the instance definition. 
    * @param name cluster name
    * @param resolved flag to indicate the cluster should be resolved
@@ -2044,38 +1867,32 @@
 
 
     deployedClusterName = clustername;
-    SliderUtils.validateClusterName(clustername);
+    validateClusterName(clustername);
     verifyNoLiveClusters(clustername, "Launch");
     Configuration config = getConfig();
     lookupZKQuorum();
-    boolean clusterSecure = SliderUtils.isHadoopClusterSecure(config);
+    boolean clusterSecure = isHadoopClusterSecure(config);
     //create the Slider AM provider -this helps set up the AM
     SliderAMClientProvider sliderAM = new SliderAMClientProvider(config);
 
     instanceDefinition.resolve();
     launchedInstanceDefinition = instanceDefinition;
 
-    ConfTreeOperations internalOperations =
-      instanceDefinition.getInternalOperations();
+    ConfTreeOperations internalOperations = instanceDefinition.getInternalOperations();
     MapOperations internalOptions = internalOperations.getGlobalOptions();
-    ConfTreeOperations resourceOperations =
-      instanceDefinition.getResourceOperations();
-    ConfTreeOperations appOperations =
-      instanceDefinition.getAppConfOperations();
+    ConfTreeOperations resourceOperations = instanceDefinition.getResourceOperations();
+    ConfTreeOperations appOperations = instanceDefinition.getAppConfOperations();
     Path generatedConfDirPath =
       createPathThatMustExist(internalOptions.getMandatoryOption(
-        InternalKeys.INTERNAL_GENERATED_CONF_PATH));
+        INTERNAL_GENERATED_CONF_PATH));
     Path snapshotConfPath =
       createPathThatMustExist(internalOptions.getMandatoryOption(
-        InternalKeys.INTERNAL_SNAPSHOT_CONF_PATH));
+        INTERNAL_SNAPSHOT_CONF_PATH));
 
 
     // cluster Provider
     AbstractClientProvider provider = createClientProvider(
-      internalOptions.getMandatoryOption(
-        InternalKeys.INTERNAL_PROVIDER_NAME));
-    // make sure the conf dir is valid;
-    
+      internalOptions.getMandatoryOption(INTERNAL_PROVIDER_NAME));
     if (log.isDebugEnabled()) {
       log.debug(instanceDefinition.toString());
     }
@@ -2085,7 +1902,7 @@
 
     // add the tags if available
     Set<String> applicationTags = provider.getApplicationTags(sliderFileSystem,
-        SliderUtils.getApplicationDefinitionPath(appOperations));
+        getApplicationDefinitionPath(appOperations));
     AppMasterLauncher amLauncher = new AppMasterLauncher(clustername,
         SliderKeys.APP_TYPE,
         config,
@@ -2110,8 +1927,7 @@
     String libdir = "lib";
     Path libPath = new Path(tempPath, libdir);
     sliderFileSystem.getFileSystem().mkdirs(libPath);
-    log.debug("FS={}, tempPath={}, libdir={}",
-        sliderFileSystem, tempPath, libPath);
+    log.debug("FS={}, tempPath={}, libdir={}", sliderFileSystem, tempPath, libPath);
  
     // set local resources for the application master
     // local files or archives as needed
@@ -2122,9 +1938,8 @@
     boolean hasServerLog4jProperties = false;
     Path remoteConfPath = null;
     String relativeConfDir = null;
-    String confdirProp =
-      System.getProperty(SliderKeys.PROPERTY_CONF_DIR);
-    if (confdirProp == null || confdirProp.isEmpty()) {
+    String confdirProp = System.getProperty(SliderKeys.PROPERTY_CONF_DIR);
+    if (isUnset(confdirProp)) {
       log.debug("No local configuration directory provided as system property");
     } else {
       File confDir = new File(confdirProp);
@@ -2132,11 +1947,11 @@
         throw new BadConfigException(E_CONFIGURATION_DIRECTORY_NOT_FOUND,
                                      confDir);
       }
-      Path localConfDirPath = SliderUtils.createLocalPath(confDir);
+      Path localConfDirPath = createLocalPath(confDir);
       remoteConfPath = new Path(clusterDirectory, SliderKeys.SUBMITTED_CONF_DIR);
       log.debug("Slider configuration directory is {}; remote to be {}", 
           localConfDirPath, remoteConfPath);
-      SliderUtils.copyDirectory(config, localConfDirPath, remoteConfPath, null);
+      copyDirectory(config, localConfDirPath, remoteConfPath, null);
 
       File log4jserver =
           new File(confDir, SliderKeys.LOG4J_SERVER_PROP_FILENAME);
@@ -2156,7 +1971,7 @@
         Map<String, LocalResource> submittedConfDir =
           sliderFileSystem.submitDirectory(remoteConfPath,
                                          relativeConfDir);
-        SliderUtils.mergeMaps(localResources, submittedConfDir);
+        mergeMaps(localResources, submittedConfDir);
       }
     }
     // build up the configuration 
@@ -2176,7 +1991,7 @@
     Configuration clientConfExtras = new Configuration(false);
     // then build up the generated path.
     FsPermission clusterPerms = getClusterDirectoryPermissions(config);
-    SliderUtils.copyDirectory(config, snapshotConfPath, generatedConfDirPath,
+    copyDirectory(config, snapshotConfPath, generatedConfDirPath,
         clusterPerms);
 
 
@@ -2229,15 +2044,15 @@
 
     // TODO: consider supporting apps that don't have an image path
     Path imagePath =
-        SliderUtils.extractImagePath(sliderFileSystem, internalOptions);
+        extractImagePath(sliderFileSystem, internalOptions);
     if (sliderFileSystem.maybeAddImagePath(localResources, imagePath)) {
       log.debug("Registered image path {}", imagePath);
     }
 
     // build the environment
     amLauncher.putEnv(
-      SliderUtils.buildEnvMap(sliderAMResourceComponent));
-    ClasspathConstructor classpath = SliderUtils.buildClasspath(relativeConfDir,
+      buildEnvMap(sliderAMResourceComponent));
+    ClasspathConstructor classpath = buildClasspath(relativeConfDir,
         libdir,
         getConfig(),
         sliderFileSystem,
@@ -2249,13 +2064,13 @@
     amLauncher.setEnv("LANGUAGE", "en_US.UTF-8");
     amLauncher.putEnv(getAmLaunchEnv(config));
     
-    for (Map.Entry<String, String> envs : SliderUtils.getSystemEnv().entrySet()) {
+    for (Map.Entry<String, String> envs : getSystemEnv().entrySet()) {
       log.debug("System env {}={}", envs.getKey(), envs.getValue());
     }
     if (log.isDebugEnabled()) {
       log.debug("AM classpath={}", classpath);
       log.debug("Environment Map:\n{}",
-                SliderUtils.stringifyMap(amLauncher.getEnv()));
+                stringifyMap(amLauncher.getEnv()));
       log.debug("Files in lib path\n{}", sliderFileSystem.listFSDir(libPath));
     }
 
@@ -2263,14 +2078,11 @@
 
     InetSocketAddress rmSchedulerAddress;
     try {
-      rmSchedulerAddress = SliderUtils.getRmSchedulerAddress(config);
+      rmSchedulerAddress = getRmSchedulerAddress(config);
     } catch (IllegalArgumentException e) {
       throw new BadConfigException("%s Address invalid: %s",
-                                   YarnConfiguration.RM_SCHEDULER_ADDRESS,
-                                   config.get(
-                                     YarnConfiguration.RM_SCHEDULER_ADDRESS)
-      );
-
+               YarnConfiguration.RM_SCHEDULER_ADDRESS,
+               config.get(YarnConfiguration.RM_SCHEDULER_ADDRESS));
     }
     String rmAddr = NetUtils.getHostPortString(rmSchedulerAddress);
 
@@ -2308,25 +2120,25 @@
       commandLine.add(Arguments.ARG_FILESYSTEM, serviceArgs.getFilesystemBinding());
     }
 
-    /**
-     * pass the registry binding
-     */
-    addConfOptionToCLI(commandLine, config,
-        RegistryConstants.KEY_REGISTRY_ZK_ROOT,
+    // pass the registry binding
+    commandLine.addConfOptionToCLI(config, RegistryConstants.KEY_REGISTRY_ZK_ROOT,
         RegistryConstants.DEFAULT_ZK_REGISTRY_ROOT);
-    addMandatoryConfOptionToCLI(commandLine, config,
-        RegistryConstants.KEY_REGISTRY_ZK_QUORUM);
+    commandLine.addMandatoryConfOption(config, RegistryConstants.KEY_REGISTRY_ZK_QUORUM);
 
     if (clusterSecure) {
       // if the cluster is secure, make sure that
       // the relevant security settings go over
-/*
-      addConfOptionToCLI(commandLine, config, KEY_SECURITY);
-*/
-      addConfOptionToCLI(commandLine,
-          config,
-          DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY);
+      commandLine.addConfOption(config, DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY);
     }
+
+    // copy over any/all YARN RM client values, in case the server-side XML conf file
+    // has the 0.0.0.0 address
+    commandLine.addConfOptions(config,
+        YarnConfiguration.RM_ADDRESS,
+        YarnConfiguration.RM_CLUSTER_ID,
+        YarnConfiguration.RM_HOSTNAME,
+        YarnConfiguration.RM_PRINCIPAL);
+
     // write out the path output
     commandLine.addOutAndErrFiles(STDOUT_AM, STDERR_AM);
 
@@ -2341,23 +2153,19 @@
 
 
     // Set the priority for the application master
-
-    int amPriority = config.getInt(KEY_YARN_QUEUE_PRIORITY,
-                                   DEFAULT_YARN_QUEUE_PRIORITY);
-
-
-    amLauncher.setPriority(amPriority);
+    amLauncher.setPriority(config.getInt(KEY_YARN_QUEUE_PRIORITY,
+                                   DEFAULT_YARN_QUEUE_PRIORITY));
 
     // Set the queue to which this application is to be submitted in the RM
     // Queue for App master
     String amQueue = config.get(KEY_YARN_QUEUE, DEFAULT_YARN_QUEUE);
-    String suppliedQueue = internalOperations.getGlobalOptions().get(InternalKeys.INTERNAL_QUEUE);
-    if(!SliderUtils.isUnset(suppliedQueue)) {
+    String suppliedQueue = internalOperations.getGlobalOptions().get(INTERNAL_QUEUE);
+    if(!isUnset(suppliedQueue)) {
       amQueue = suppliedQueue;
       log.info("Using queue {} for the application instance.", amQueue);
     }
 
-    if (amQueue != null) {
+    if (isSet(amQueue)) {
       amLauncher.setQueue(amQueue);
     }
 
@@ -2367,15 +2175,15 @@
   }
 
   protected Map<String, String> getAmLaunchEnv(Configuration config) {
-    String sliderAmLaunchEnv = config.get(SliderXmlConfKeys.KEY_AM_LAUNCH_ENV);
-    log.debug("{} = {}", SliderXmlConfKeys.KEY_AM_LAUNCH_ENV, sliderAmLaunchEnv);
+    String sliderAmLaunchEnv = config.get(KEY_AM_LAUNCH_ENV);
+    log.debug("{} = {}", KEY_AM_LAUNCH_ENV, sliderAmLaunchEnv);
     // Multiple env variables can be specified with a comma (,) separator
     String[] envs = StringUtils.isEmpty(sliderAmLaunchEnv) ? null
         : sliderAmLaunchEnv.split(",");
     if (ArrayUtils.isEmpty(envs)) {
       return Collections.emptyMap();
     }
-    Map<String, String> amLaunchEnv = new HashMap<String, String>();
+    Map<String, String> amLaunchEnv = new HashMap<>();
     for (String env : envs) {
       if (StringUtils.isNotEmpty(env)) {
         // Each env name/value is separated by equals sign (=)
@@ -2411,9 +2219,9 @@
     if (placeholderMatcher.find()) {
       String placeholderKey = placeholderMatcher.group();
       String systemKey = placeholderKey
-          .substring(2, placeholderKey.length() - 1).toUpperCase()
+          .substring(2, placeholderKey.length() - 1).toUpperCase(Locale.ENGLISH)
           .replaceAll("\\.", "_");
-      String placeholderValue = SliderUtils.getSystemEnv(systemKey);
+      String placeholderValue = getSystemEnv(systemKey);
       log.debug("Placeholder {}={}", placeholderKey, placeholderValue);
       placeholderKeyValueMap.put(placeholderKey, placeholderValue);
     }
@@ -2423,10 +2231,10 @@
   private void propagatePythonExecutable(Configuration config,
                                          AggregateConf instanceDefinition) {
     String pythonExec = config.get(
-        SliderXmlConfKeys.PYTHON_EXECUTABLE_PATH);
+        PYTHON_EXECUTABLE_PATH);
     if (pythonExec != null) {
       instanceDefinition.getAppConfOperations().getGlobalOptions().putIfUnset(
-          SliderXmlConfKeys.PYTHON_EXECUTABLE_PATH,
+          PYTHON_EXECUTABLE_PATH,
           pythonExec);
     }
   }
@@ -2456,7 +2264,7 @@
       new Duration(acceptWaitMillis));
 
     // may have failed, so check that
-    if (SliderUtils.hasAppFinished(report)) {
+    if (hasAppFinished(report)) {
       exitCode = buildExitCode(report);
     } else {
       // exit unless there is a wait
@@ -2489,71 +2297,15 @@
    */
   private void propagatePrincipals(Configuration config,
                                    AggregateConf clusterSpec) {
-    String dfsPrincipal = config.get(
-        DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY);
+    String dfsPrincipal = config.get(DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY);
     if (dfsPrincipal != null) {
-      String siteDfsPrincipal = OptionKeys.SITE_XML_PREFIX +
-                                DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY;
+      String siteDfsPrincipal = SITE_XML_PREFIX + DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY;
       clusterSpec.getAppConfOperations().getGlobalOptions().putIfUnset(
         siteDfsPrincipal,
         dfsPrincipal);
     }
   }
 
-
-  private boolean addConfOptionToCLI(CommandLineBuilder cmdLine,
-      Configuration conf,
-      String key) {
-    String val = conf.get(key);
-    return defineIfSet(cmdLine, key, val);
-  }
-
-  private String addConfOptionToCLI(CommandLineBuilder cmdLine,
-      Configuration conf,
-      String key,
-      String defVal) {
-    String val = conf.get(key, defVal);
-    define(cmdLine, key, val);
-    return val;
-  }
-
-  /**
-   * Add a <code>-D key=val</code> command to the CLI
-   * @param cmdLine command line
-   * @param key key
-   * @param val value
-   */
-  private void define(CommandLineBuilder cmdLine, String key, String val) {
-    Preconditions.checkArgument(key != null, "null key");
-    Preconditions.checkArgument(val != null, "null value");
-    cmdLine.add(Arguments.ARG_DEFINE, key + "=" + val);
-  }
-
-  /**
-   * Add a <code>-D key=val</code> command to the CLI if <code>val</code>
-   * is not null
-   * @param cmdLine command line
-   * @param key key
-   * @param val value
-   */
-  private boolean defineIfSet(CommandLineBuilder cmdLine, String key, String val) {
-    Preconditions.checkArgument(key != null, "null key");
-    if (val != null) {
-      define(cmdLine, key, val);
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  private void addMandatoryConfOptionToCLI(CommandLineBuilder cmdLine,
-      Configuration conf,
-      String key) throws BadConfigException {
-    if (!addConfOptionToCLI(cmdLine, conf, key)) {
-      throw new BadConfigException("Missing configuration option: " + key);
-    }
-  }
-  
   /**
    * Create a path that must exist in the cluster fs
    * @param uri uri to create
@@ -2561,8 +2313,7 @@
    * @throws FileNotFoundException if the path does not exist
    */
   public Path createPathThatMustExist(String uri) throws
-      SliderException,
-                                                  IOException {
+      SliderException, IOException {
     return sliderFileSystem.createPathThatMustExist(uri);
   }
 
@@ -2756,8 +2507,49 @@
   @Override
   public int actionList(String clustername, ActionListArgs args)
       throws IOException, YarnException {
+    Set<String> appInstances = getApplicationList(clustername, args);
+    // getApplicationList never returns null
+    return !appInstances.isEmpty() ? EXIT_SUCCESS
+        : ((appInstances.isEmpty() && isUnset(clustername)) ? EXIT_SUCCESS
+               : EXIT_FALSE);
+  }
+
+  /**
+   * Retrieve a list of all live instances. If clustername is supplied then it
+   * returns this specific cluster, if and only if it exists and is live.
+   * 
+   * @param clustername
+   *          cluster name (if looking for a specific live cluster)
+   * @return the list of application names which satisfies the list criteria
+   * @throws IOException
+   * @throws YarnException
+   */
+  public Set<String> getApplicationList(String clustername) throws IOException,
+      YarnException {
+    ActionListArgs args = new ActionListArgs();
+    args.live = true;
+    return getApplicationList(clustername, args);
+  }
+
+  /**
+   * Retrieve a list of application instances satisfying the query criteria.
+   * 
+   * @param clustername
+   *          List out specific instance name (set null for all)
+   * @param args
+   *          Action list arguments
+   * @return the list of application names which satisfies the list criteria
+   * @throws IOException
+   * @throws YarnException
+   * @throws UnknownApplicationInstanceException
+   *           if a specific instance was named but it was not found
+   */
+  public Set<String> getApplicationList(String clustername, ActionListArgs args)
+      throws IOException, YarnException {
     if (args.help) {
-      return actionHelp(ACTION_LIST);
+      actionHelp(ACTION_LIST);
+      // the above call throws an exception so the return is not really required
+      return Collections.emptySet();
     }
     verifyBindingsDefined();
 
@@ -2807,14 +2599,14 @@
     if (persistentInstances.isEmpty() && isUnset(clustername)) {
       // an empty listing is a success if no cluster was named
       log.debug("No application instances found");
-      return EXIT_SUCCESS;
+      return Collections.emptySet();
     }
 
     // and those the RM knows about
     List<ApplicationReport> instances = listSliderInstances(null);
-    SliderUtils.sortApplicationsByMostRecent(instances);
+    sortApplicationsByMostRecent(instances);
     Map<String, ApplicationReport> reportMap =
-        SliderUtils.buildApplicationReportMap(instances, min, max);
+        buildApplicationReportMap(instances, min, max);
     log.debug("Persisted {} deployed {} filtered[{}-{}] & de-duped to {}",
         persistentInstances.size(),
         instances.size(),
@@ -2839,22 +2631,21 @@
     }
     
     // at this point there is either the entire list or a stripped down instance
-    int listed = 0;
-
+    Set<String> listedInstances = new HashSet<String>();
     for (String name : persistentInstances.keySet()) {
       ApplicationReport report = reportMap.get(name);
       if (!listOnlyInState || report != null) {
         // list the details if all were requested, or the filtering contained
         // a report
-        listed++;
+        listedInstances.add(name);
         // containers will be non-null when only one instance is requested
-        String details = SliderUtils.instanceDetailsToString(name, report,
+        String details = instanceDetailsToString(name, report,
             containers, version, components, verbose);
         print(details);
       }
     }
     
-    return listed > 0 ? EXIT_SUCCESS: EXIT_FALSE;
+    return listedInstances;
   }
 
   public List<ContainerInformation> getContainers(String name)
@@ -2930,11 +2721,15 @@
   @Override
   @VisibleForTesting
   public int actionFlex(String name, ActionFlexArgs args) throws YarnException, IOException {
+    validateClusterName(name);
+    Map<String, String> roleMap = args.getComponentMap();
+    // throw usage exception if no changes proposed
+    if (roleMap.size() == 0) {
+      actionHelp(ACTION_FLEX);
+    }
     verifyBindingsDefined();
-    SliderUtils.validateClusterName(name);
     log.debug("actionFlex({})", name);
     Map<String, Integer> roleInstances = new HashMap<>();
-    Map<String, String> roleMap = args.getComponentMap();
     for (Map.Entry<String, String> roleEntry : roleMap.entrySet()) {
       String key = roleEntry.getKey();
       String val = roleEntry.getValue();
@@ -2958,7 +2753,7 @@
 
   public int actionExists(String name, ActionExistsArgs args) throws YarnException, IOException {
     verifyBindingsDefined();
-    SliderUtils.validateClusterName(name);
+    validateClusterName(name);
     boolean checkLive = args.live;
     log.debug("actionExists({}, {}, {})", name, checkLive, args.state);
 
@@ -2968,7 +2763,7 @@
       throw unknownClusterException(name);
     }
     String state = args.state;
-    if (!checkLive && SliderUtils.isUnset(state)) {
+    if (!checkLive && isUnset(state)) {
       log.info("Application {} exists", name);
       return EXIT_SUCCESS;
     }
@@ -3002,8 +2797,8 @@
       }
     }
 
-    SliderUtils.OnDemandReportStringifier report =
-        new SliderUtils.OnDemandReportStringifier(instance);
+    OnDemandReportStringifier report =
+        new OnDemandReportStringifier(instance);
     if (!inDesiredState) {
       //cluster in the list of apps but not running
       log.info("Application {} found but is in wrong state {}", name,
@@ -3023,7 +2818,7 @@
   public int actionKillContainer(String name,
       ActionKillContainerArgs args) throws YarnException, IOException {
     String id = args.id;
-    if (SliderUtils.isUnset(id)) {
+    if (isUnset(id)) {
       throw new BadCommandArgumentsException("Missing container id");
     }
     log.info("killingContainer {}:{}", name, id);
@@ -3119,7 +2914,7 @@
                                               YarnException,
                                               IOException {
     verifyBindingsDefined();
-    SliderUtils.validateClusterName(clustername);
+    validateClusterName(clustername);
     String outfile = statusArgs.getOutput();
     ClusterDescription status = getClusterDescription(clustername);
     String text = status.toJsonString();
@@ -3141,7 +2936,7 @@
   public int actionFreeze(String clustername,
       ActionFreezeArgs freezeArgs) throws YarnException, IOException {
     verifyBindingsDefined();
-    SliderUtils.validateClusterName(clustername);
+    validateClusterName(clustername);
     int waittime = freezeArgs.getWaittime();
     String text = freezeArgs.message;
     boolean forcekill = freezeArgs.force;
@@ -3160,7 +2955,7 @@
       return EXIT_SUCCESS;
     }
     log.debug("App to stop was found: {}:\n{}", clustername,
-              new SliderUtils.OnDemandReportStringifier(app));
+              new OnDemandReportStringifier(app));
     if (app.getYarnApplicationState().ordinal() >=
         YarnApplicationState.FINISHED.ordinal()) {
       log.info("Cluster {} is in a terminated state {}", clustername,
@@ -3227,7 +3022,7 @@
 
   @Override
   public int actionThaw(String clustername, ActionThawArgs thaw) throws YarnException, IOException {
-    SliderUtils.validateClusterName(clustername);
+    validateClusterName(clustername);
     verifyBindingsDefined();
     // see if it is actually running and bail out;
     verifyNoLiveClusters(clustername, "Start");
@@ -3247,7 +3042,7 @@
   public int flex(String clustername, Map<String, Integer> roleInstances)
       throws YarnException, IOException {
     verifyBindingsDefined();
-    SliderUtils.validateClusterName(clustername);
+    validateClusterName(clustername);
     Path clusterDirectory = sliderFileSystem.buildClusterDirPath(clustername);
     AggregateConf instanceDefinition = loadInstanceDefinitionUnresolved(
       clustername,
@@ -3258,7 +3053,7 @@
     for (Map.Entry<String, Integer> entry : roleInstances.entrySet()) {
       String role = entry.getKey();
       int count = entry.getValue();
-      resources.getOrAddComponent(role).put(ResourceKeys.COMPONENT_INSTANCES,
+      resources.getOrAddComponent(role).put(COMPONENT_INSTANCES,
                                             Integer.toString(count));
 
       log.debug("Flexed cluster specification ( {} -> {}) : \n{}",
@@ -3269,7 +3064,7 @@
     SliderAMClientProvider sliderAM = new SliderAMClientProvider(getConfig());
     AbstractClientProvider provider = createClientProvider(
         instanceDefinition.getInternalOperations().getGlobalOptions().getMandatoryOption(
-            InternalKeys.INTERNAL_PROVIDER_NAME));
+            INTERNAL_PROVIDER_NAME));
     // slider provider to validate what there is
     validateInstanceDefinition(sliderAM, instanceDefinition, sliderFileSystem);
     validateInstanceDefinition(provider, instanceDefinition, sliderFileSystem);
@@ -3580,7 +3375,7 @@
           } else {
             String filename = RegistryPathUtils.lastPathEntry(name) + ".json";
             File jsonFile = new File(destDir, filename);
-            SliderUtils.write(jsonFile,
+            write(jsonFile,
                 serviceRecordMarshal.toBytes(instance),
                 true);
           }
@@ -3593,7 +3388,7 @@
           outFile = new File(args.destdir, RegistryPathUtils.lastPathEntry(path));
         }
         if (outFile != null) {
-          SliderUtils.write(outFile, serviceRecordMarshal.toBytes(instance), true);
+          write(outFile, serviceRecordMarshal.toBytes(instance), true);
         } else {
           println(serviceRecordMarshal.toJson(instance));
         }
@@ -3624,12 +3419,12 @@
       } else if (registryArgs.listExports) {
         // list the exports
         actionRegistryListExports(registryArgs);
-      } else if (SliderUtils.isSet(registryArgs.getConf)) {
+      } else if (isSet(registryArgs.getConf)) {
         // get a configuration
         PublishedConfiguration publishedConfiguration =
             actionRegistryGetConfig(registryArgs);
         outputConfig(publishedConfiguration, registryArgs);
-      } else if (SliderUtils.isSet(registryArgs.getExport)) {
+      } else if (isSet(registryArgs.getExport)) {
         // get a export group
         PublishedExports publishedExports =
             actionRegistryGetExport(registryArgs);
@@ -3641,11 +3436,11 @@
       }
 //      JDK7
     } catch (FileNotFoundException e) {
-      log.info("{}", e);
+      log.info("{}", e.toString());
       log.debug("{}", e, e);
       return EXIT_NOT_FOUND;
     } catch (PathNotFoundException e) {
-      log.info("{}", e);
+      log.info("{}", e.toString());
       log.debug("{}", e, e);
       return EXIT_NOT_FOUND;
     }
@@ -3669,10 +3464,7 @@
     RegistryOperations operations = getRegistryOperations();
     Collection<ServiceRecord> serviceRecords;
     if (StringUtils.isEmpty(name)) {
-      String path =
-          serviceclassPath(
-              currentUser(),
-              serviceType);
+      String path = serviceclassPath(currentUser(), serviceType);
 
       try {
         Map<String, ServiceRecord> recordMap =
@@ -3730,18 +3522,15 @@
     // application name after --application option and member variable
     // cluster name has to be put behind action
     String clusterName = diagnosticArgs.name;
-    if(SliderUtils.isUnset(clusterName)){
-      throw new BadCommandArgumentsException("application name must be provided with --name option");
-    }
-    
+    requireArgumentSet(Arguments.ARG_NAME, clusterName);
+
     try {
-      SliderUtils.validateClientConfigFile();
+      validateClientConfigFile();
       log.info("Slider-client.xml is accessible");
     } catch (IOException e) {
       // we are catching exceptions here because those are indication of
       // validation result, and we need to print them here
-      log.error(
-          "validation of slider-client.xml fails because: " + e.toString(), e);
+      log.error("validation of slider-client.xml fails because: " + e, e);
       return;
     }
     SliderClusterOperations clusterOperations = createClusterOperations(clusterName);
@@ -3754,7 +3543,7 @@
       AggregateConf instanceDefinition = clusterOperations
           .getInstanceDefinition();
       String imagePath = instanceDefinition.getInternalOperations().get(
-          InternalKeys.INTERNAL_APPLICATION_IMAGE_PATH);
+          INTERNAL_APPLICATION_IMAGE_PATH);
       // if null, that means slider uploaded the agent tarball for the user
       // and we need to use where slider has put
       if (imagePath == null) {
@@ -3765,26 +3554,27 @@
             + "/agent");
         imagePath = subPath.toString();
       }
+      String pathStr = imagePath + "/" + AGENT_TAR;
       try {
-        SliderUtils.validateHDFSFile(sliderFileSystem, imagePath + "/" + AGENT_TAR);
+        validateHDFSFile(sliderFileSystem, pathStr);
         log.info("Slider agent package is properly installed");
       } catch (FileNotFoundException e) {
-        log.error("can not find agent package: " + e.toString());
+        log.error("can not find agent package: {}", pathStr);
+        log.debug("can not find agent package: {}", pathStr, e);
         return;
       } catch (IOException e) {
-        log.error("can not open agent package: " + e.toString());
+        log.error("can not open agent package: {}", pathStr, e);
         return;
       }
-      String pkgTarballPath = SliderUtils
-          .getApplicationDefinitionPath(instanceDefinition
+      String pkgTarballPath = getApplicationDefinitionPath(instanceDefinition
               .getAppConfOperations());
       try {
-        SliderUtils.validateHDFSFile(sliderFileSystem, pkgTarballPath);
+        validateHDFSFile(sliderFileSystem, pkgTarballPath);
         log.info("Application package is properly installed");
       } catch (FileNotFoundException e) {
-        log.error("can not find application package: {}", e);
+        log.error("can not find application package: {}", pkgTarballPath,  e);
       } catch (IOException e) {
-        log.error("can not open application package: {} ", e);
+        log.error("can not open application package: {} ", pkgTarballPath, e);
       }
     }
   }
@@ -3801,11 +3591,10 @@
 
   private void actionDiagnosticCredentials() throws BadConfigException,
       IOException {
-    if (SliderUtils.isHadoopClusterSecure(SliderUtils
-        .loadSliderClientXML())) {
+    if (isHadoopClusterSecure(loadSliderClientXML())) {
       String credentialCacheFileDescription = null;
       try {
-        credentialCacheFileDescription = SliderUtils.checkCredentialCacheFile();
+        credentialCacheFileDescription = checkCredentialCacheFile();
       } catch (BadConfigException e) {
         log.error("The credential config is not valid: " + e.toString());
         throw e;
@@ -3867,25 +3656,12 @@
     // application name after --application option and member variable
     // cluster name has to be put behind action
     String clusterName = diagnosticArgs.name;
-    if(SliderUtils.isUnset(clusterName)){
+    if(isUnset(clusterName)){
       throw new BadCommandArgumentsException("application name must be provided with --name option");
     }
-    SliderClusterOperations clusterOperations;
-    AggregateConf instanceDefinition = null;
-    try {
-      clusterOperations = createClusterOperations(clusterName);
-      instanceDefinition = clusterOperations.getInstanceDefinition();
-    } catch (YarnException e) {
-      log.error("Exception happened when retrieving instance definition from YARN: "
-          + e.toString());
-      throw e;
-    } catch (IOException e) {
-      log.error("Network problem happened when retrieving instance definition from YARN: "
-          + e.toString());
-      throw e;
-    }
+    AggregateConf instanceDefinition = fetchInstanceDefinition(clusterName);
     String imagePath = instanceDefinition.getInternalOperations().get(
-        InternalKeys.INTERNAL_APPLICATION_IMAGE_PATH);
+        INTERNAL_APPLICATION_IMAGE_PATH);
     // if null, it will be uploaded by Slider and thus at slider's path
     if (imagePath == null) {
       ApplicationReport appReport = findInstance(clusterName);
@@ -3897,58 +3673,54 @@
     log.info("The path of slider agent tarball on HDFS is: " + imagePath);
   }
 
+  private AggregateConf fetchInstanceDefinition(String clusterName)
+      throws YarnException, IOException {
+    SliderClusterOperations clusterOperations;
+    AggregateConf instanceDefinition = null;
+    try {
+      clusterOperations = createClusterOperations(clusterName);
+      instanceDefinition = clusterOperations.getInstanceDefinition();
+    } catch (YarnException | IOException e) {
+      log.error("Failed to retrieve instance definition from YARN: "
+          + e.toString());
+      throw e;
+    }
+    return instanceDefinition;
+  }
+
   private void actionDiagnosticApplication(ActionDiagnosticArgs diagnosticArgs)
       throws YarnException, IOException {
     // not using member variable clustername because we want to place
     // application name after --application option and member variable
     // cluster name has to be put behind action
     String clusterName = diagnosticArgs.name;
-    if(SliderUtils.isUnset(clusterName)){
-      throw new BadCommandArgumentsException("application name must be provided with --name option");
-    }
-    SliderClusterOperations clusterOperations;
-    AggregateConf instanceDefinition = null;
-    try {
-      clusterOperations = createClusterOperations(clusterName);
-      instanceDefinition = clusterOperations.getInstanceDefinition();
-    } catch (YarnException e) {
-      log.error("Exception happened when retrieving instance definition from YARN: "
-          + e.toString());
-      throw e;
-    } catch (IOException e) {
-      log.error("Network problem happened when retrieving instance definition from YARN: "
-          + e.toString());
-      throw e;
-    }
+    requireArgumentSet(Arguments.ARG_NAME, clusterName);
+    AggregateConf instanceDefinition = fetchInstanceDefinition(clusterName);
     String clusterDir = instanceDefinition.getAppConfOperations()
         .getGlobalOptions().get(AgentKeys.APP_ROOT);
-    String pkgTarball = SliderUtils
-        .getApplicationDefinitionPath(instanceDefinition.getAppConfOperations());
+    String pkgTarball = getApplicationDefinitionPath(instanceDefinition.getAppConfOperations());
     String runAsUser = instanceDefinition.getAppConfOperations()
         .getGlobalOptions().get(AgentKeys.RUNAS_USER);
 
-    log.info("The location of the cluster instance directory in HDFS is: "
-        + clusterDir);
-    log.info("The name of the application package tarball on HDFS is: "
-        + pkgTarball);
-    log.info("The runas user of the application in the cluster is: "
-        + runAsUser);
+    log.info("The location of the cluster instance directory in HDFS is: {}", clusterDir);
+    log.info("The name of the application package tarball on HDFS is: {}",pkgTarball);
+    log.info("The runas user of the application in the cluster is: {}",runAsUser);
 
     if (diagnosticArgs.verbose) {
-      log.info("App config of the application: "
-          + instanceDefinition.getAppConf().toJson());
-      log.info("Resource config of the application: "
-          + instanceDefinition.getResources().toJson());
+      log.info("App config of the application:\n{}",
+          instanceDefinition.getAppConf().toJson());
+      log.info("Resource config of the application:\n{}",
+          instanceDefinition.getResources().toJson());
     }
   }
 
   private void actionDiagnosticClient(ActionDiagnosticArgs diagnosticArgs)
       throws SliderException, IOException {
     try {
-      String currentCommandPath = SliderUtils.getCurrentCommandPath();
+      String currentCommandPath = getCurrentCommandPath();
       SliderVersionInfo.loadAndPrintVersionInfo(log);
-      String clientConfigPath = SliderUtils.getClientConfigPath();
-      String jdkInfo = SliderUtils.getJDKInfo();
+      String clientConfigPath = getClientConfigPath();
+      String jdkInfo = getJDKInfo();
       println("The slider command path: %s", currentCommandPath);
       println("The slider-client.xml used by current running command path: %s",
           clientConfigPath);
@@ -3956,7 +3728,7 @@
 
       // security info
       Configuration config = getConfig();
-      if (SliderUtils.isHadoopClusterSecure(config)) {
+      if (isHadoopClusterSecure(config)) {
         println("Hadoop Cluster is secure");
         println("Login user is %s", UserGroupInformation.getLoginUser());
         println("Current user is %s", UserGroupInformation.getCurrentUser());
@@ -3968,7 +3740,7 @@
       // verbose?
       if (diagnosticArgs.verbose) {
         // do the environment
-        Map<String, String> env = SliderUtils.getSystemEnv();
+        Map<String, String> env = getSystemEnv();
         Set<String> envList = ConfigHelper.sortedConfigKeys(env.entrySet());
         StringBuilder builder = new StringBuilder("Environment variables:\n");
         for (String key : envList) {
@@ -3979,7 +3751,7 @@
         // Java properties
         builder = new StringBuilder("JVM Properties\n");
         Map<String, String> props =
-            SliderUtils.sortedMap(SliderUtils.toMap(System.getProperties()));
+            sortedMap(toMap(System.getProperties()));
         for (Entry<String, String> entry : props.entrySet()) {
           builder.append(entry.getKey()).append("=")
                  .append(entry.getValue()).append("\n");
@@ -3988,12 +3760,10 @@
         println(builder.toString());
 
         // then the config
-        println("Slider client configuration:\n"
-                + ConfigHelper.dumpConfigToString(config));
-        
+        println("Slider client configuration:\n" + ConfigHelper.dumpConfigToString(config));
       }
 
-      SliderUtils.validateSliderClientEnvironment(log);
+      validateSliderClientEnvironment(log);
     } catch (SliderException | IOException e) {
       log.error(e.toString());
       throw e;
@@ -4154,8 +3924,7 @@
 
     RegistryRetriever retriever = new RegistryRetriever(getConfig(), instance);
     boolean external = !registryArgs.internal;
-    PublishedExportsSet exports =
-        retriever.getExports(external);
+    PublishedExportsSet exports = retriever.getExports(external);
 
     PublishedExports published = retriever.retrieveExports(exports,
                                                            registryArgs.getExport,
@@ -4427,7 +4196,7 @@
       return EXIT_FALSE;
     }
     
-    String version = SliderUtils.getSliderVersion();
+    String version = getSliderVersion();
     Path dependencyLibTarGzip = sliderFileSystem.getDependencyTarGzip();
     
     // Check if dependency has already been uploaded, in which case log
@@ -4441,23 +4210,13 @@
     }
     
     String libDir = System.getProperty(SliderKeys.PROPERTY_LIB_DIR);
-    if (SliderUtils.isSet(libDir)) {
+    if (isSet(libDir)) {
       File srcFolder = new File(libDir);
       File tempLibTarGzipFile = File.createTempFile(
           SliderKeys.SLIDER_DEPENDENCY_TAR_GZ_FILE_NAME + "_",
           SliderKeys.SLIDER_DEPENDENCY_TAR_GZ_FILE_EXT);
       // copy all jars except slider-core-<version>.jar
-      FilenameFilter jarFilter = new FilenameFilter() {
-        public boolean accept(File dir, String name) {
-          String lowercaseName = name.toLowerCase();
-          if (lowercaseName.endsWith(".jar")) {
-            return true;
-          } else {
-            return false;
-          }
-        }
-      };
-      SliderUtils.tarGzipFolder(srcFolder, tempLibTarGzipFile, jarFilter);
+      tarGzipFolder(srcFolder, tempLibTarGzipFile, createJarFilter());
 
       log.info("Uploading dependency for AM (version {}) from {} to {}",
           version, tempLibTarGzipFile.toURI(), dependencyLibTarGzip.toUri());
@@ -4479,6 +4238,73 @@
     throw new UsageException("%s %s", errMsg, CommonArgs.usage(serviceArgs,
         actionName));
   }
+
+  /**
+   * List the nodes in the cluster, possibly filtering by node state or label.
+   *
+   * @param args argument list
+   * @return a possibly empty list of nodes in the cluster
+   * @throws IOException IO problems
+   * @throws YarnException YARN problems
+   */
+  @Override
+  public NodeInformationList listYarnClusterNodes(ActionNodesArgs args)
+    throws YarnException, IOException {
+    return yarnClient.listNodes(args.label, args.healthy);
+  }
+
+  /**
+   * List the nodes in the cluster, possibly filtering by node state or label.
+   *
+   * @param args argument list
+   * @return a possibly empty list of nodes in the cluster
+   * @throws IOException IO problems
+   * @throws YarnException YARN problems
+   */
+  public NodeInformationList listInstanceNodes(String instance, ActionNodesArgs args)
+    throws YarnException, IOException {
+    // TODO
+    log.info("listInstanceNodes {}", instance);
+    SliderClusterOperations clusterOps =
+      new SliderClusterOperations(bondToCluster(instance));
+    return clusterOps.getLiveNodes();
+  }
+
+  /**
+   * List the nodes in the cluster, possibly filtering by node state or label.
+   * Prints them to stdout unless the args names a file instead.
+   * @param args argument list
+   * @throws IOException IO problems
+   * @throws YarnException YARN problems
+   */
+  public int actionNodes(String instance, ActionNodesArgs args) throws YarnException, IOException {
+
+    args.instance = instance;
+    NodeInformationList nodes;
+    if (SliderUtils.isUnset(instance)) {
+      nodes = listYarnClusterNodes(args);
+    } else {
+      nodes = listInstanceNodes(instance, args);
+    }
+    log.debug("Node listing for {} has {} nodes", args, nodes.size());
+    JsonSerDeser<NodeInformationList> serDeser = NodeInformationList.createSerializer();
+    if (args.outputFile != null) {
+      serDeser.save(nodes, args.outputFile);
+    } else {
+      println(serDeser.toJson(nodes));
+    }
+    return 0;
+  }
+
+  /**
+   * Create a new IPC client for talking to slider via what follows the REST API.
+   * Client must already be bonded to the cluster
+   * @return a new IPC client
+   */
+  public SliderApplicationApi createIpcClient()
+    throws IOException, YarnException {
+    return new SliderApplicationIpcClient(createClusterOperations());
+  }
 }
 
 
diff --git a/slider-core/src/main/java/org/apache/slider/client/SliderClientAPI.java b/slider-core/src/main/java/org/apache/slider/client/SliderClientAPI.java
index bab451f..5c5d96b 100644
--- a/slider-core/src/main/java/org/apache/slider/client/SliderClientAPI.java
+++ b/slider-core/src/main/java/org/apache/slider/client/SliderClientAPI.java
@@ -23,11 +23,13 @@
 import org.apache.hadoop.yarn.api.records.ApplicationReport;
 import org.apache.hadoop.yarn.api.records.YarnApplicationState;
 import org.apache.hadoop.yarn.exceptions.YarnException;
+import org.apache.slider.api.types.NodeInformationList;
 import org.apache.slider.api.types.SliderInstanceDescription;
 import org.apache.slider.common.params.AbstractClusterBuildingActionArgs;
 import org.apache.slider.common.params.ActionAMSuicideArgs;
 import org.apache.slider.common.params.ActionClientArgs;
 import org.apache.slider.common.params.ActionDependencyArgs;
+import org.apache.slider.common.params.ActionDestroyArgs;
 import org.apache.slider.common.params.ActionDiagnosticArgs;
 import org.apache.slider.common.params.ActionEchoArgs;
 import org.apache.slider.common.params.ActionFlexArgs;
@@ -35,6 +37,7 @@
 import org.apache.slider.common.params.ActionInstallKeytabArgs;
 import org.apache.slider.common.params.ActionInstallPackageArgs;
 import org.apache.slider.common.params.ActionKeytabArgs;
+import org.apache.slider.common.params.ActionNodesArgs;
 import org.apache.slider.common.params.ActionPackageArgs;
 import org.apache.slider.common.params.ActionKillContainerArgs;
 import org.apache.slider.common.params.ActionListArgs;
@@ -62,6 +65,9 @@
    * #1 the cluster is started between verifying that there are no live
    * clusters of that name.
    */
+  int actionDestroy(String clustername, ActionDestroyArgs destroyArgs)
+      throws YarnException, IOException;
+
   int actionDestroy(String clustername) throws YarnException,
       IOException;
 
@@ -99,7 +105,7 @@
    * @throws YarnException Yarn problems
    * @throws IOException other problems
    * @throws BadCommandArgumentsException bad arguments.
-   * @deperecated use #actionKeytab
+   * @deprecated use #actionKeytab
    */
   int actionInstallKeytab(ActionInstallKeytabArgs installKeytabInfo)
       throws YarnException, IOException;
@@ -111,7 +117,7 @@
    * @throws YarnException Yarn problems
    * @throws IOException other problems
    * @throws BadCommandArgumentsException bad arguments.
-   * @deperecated use #actionKeytab
+   * @deprecated use #actionKeytab
    */
   int actionKeytab(ActionKeytabArgs keytabInfo)
       throws YarnException, IOException;
@@ -338,4 +344,14 @@
    */
   int actionDependency(ActionDependencyArgs dependencyArgs) throws IOException,
       YarnException;
+
+  /**
+   * List the nodes
+   * @param args
+   * @return
+   * @throws YarnException
+   * @throws IOException
+   */
+  NodeInformationList listYarnClusterNodes(ActionNodesArgs args)
+    throws YarnException, IOException;
 }
diff --git a/slider-core/src/main/java/org/apache/slider/client/SliderYarnClientImpl.java b/slider-core/src/main/java/org/apache/slider/client/SliderYarnClientImpl.java
index 3b7a65c..85a582b 100644
--- a/slider-core/src/main/java/org/apache/slider/client/SliderYarnClientImpl.java
+++ b/slider-core/src/main/java/org/apache/slider/client/SliderYarnClientImpl.java
@@ -20,6 +20,7 @@
 
 import com.google.common.base.Preconditions;
 import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
@@ -27,12 +28,18 @@
 import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationResponse;
 import org.apache.hadoop.yarn.api.records.ApplicationId;
 import org.apache.hadoop.yarn.api.records.ApplicationReport;
+import org.apache.hadoop.yarn.api.records.NodeReport;
+import org.apache.hadoop.yarn.api.records.NodeState;
 import org.apache.hadoop.yarn.api.records.YarnApplicationState;
 import org.apache.hadoop.yarn.client.api.impl.YarnClientImpl;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.hadoop.yarn.util.ConverterUtils;
 import org.apache.hadoop.yarn.util.Records;
+import org.apache.slider.api.types.NodeInformation;
+import org.apache.slider.api.types.NodeInformationList;
 import org.apache.slider.common.SliderKeys;
+import org.apache.slider.common.params.ActionNodesArgs;
 import org.apache.slider.common.tools.CoreFileSystem;
 import org.apache.slider.common.tools.Duration;
 import org.apache.slider.common.tools.SliderFileSystem;
@@ -42,6 +49,8 @@
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
+import java.net.BindException;
+import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -55,8 +64,7 @@
  * from the slider entry point service
  */
 public class SliderYarnClientImpl extends YarnClientImpl {
-  protected static final Logger
-    log = LoggerFactory.getLogger(SliderYarnClientImpl.class);
+  protected static final Logger log = LoggerFactory.getLogger(SliderYarnClientImpl.class);
 
   /**
    * Keyword to use in the {@link #emergencyForceKill(String)}
@@ -65,6 +73,18 @@
    */
   public static final String KILL_ALL = "all";
 
+  @Override
+  protected void serviceInit(Configuration conf) throws Exception {
+    InetSocketAddress clientRpcAddress = SliderUtils.getRmAddress(conf);
+    if (!SliderUtils.isAddressDefined(clientRpcAddress)) {
+      // address isn't known; fail fast
+      throw new BindException("Invalid " + YarnConfiguration.RM_ADDRESS
+          + " value:" + conf.get(YarnConfiguration.RM_ADDRESS)
+          + " - see https://wiki.apache.org/hadoop/UnsetHostnameOrPort");
+    }
+    super.serviceInit(conf);
+  }
+
   /**
    * Get the RM Client RPC interface
    * @return an RPC interface valid after initialization and authentication
@@ -96,10 +116,10 @@
   public List<ApplicationReport> listDeployedInstances(String user)
     throws YarnException, IOException {
     Preconditions.checkArgument(user != null, "Null User");
-    Set<String> types = new HashSet<String>(1);
+    Set<String> types = new HashSet<>(1);
     types.add(SliderKeys.APP_TYPE);
     List<ApplicationReport> allApps = getApplications(types);
-    List<ApplicationReport> results = new ArrayList<ApplicationReport>();
+    List<ApplicationReport> results = new ArrayList<>();
     for (ApplicationReport report : allApps) {
       if (StringUtils.isEmpty(user) || user.equals(report.getUser())) {
         results.add(report);
@@ -108,7 +128,6 @@
     return results;
   }
 
-
   /**
    * find all instances of a specific app -if there is more than one in the
    * YARN cluster,
@@ -124,7 +143,7 @@
 
     List<ApplicationReport> instances = listDeployedInstances(user);
     List<ApplicationReport> results =
-      new ArrayList<ApplicationReport>(instances.size());
+      new ArrayList<>(instances.size());
     for (ApplicationReport report : instances) {
       if (report.getName().equals(appname)) {
         results.add(report);
@@ -142,8 +161,7 @@
   public boolean isApplicationLive(ApplicationReport app) {
     Preconditions.checkArgument(app != null, "Null app report");
 
-    return app.getYarnApplicationState().ordinal() <=
-           YarnApplicationState.RUNNING.ordinal();
+    return app.getYarnApplicationState().ordinal() <= YarnApplicationState.RUNNING.ordinal();
   }
 
 
@@ -330,8 +348,6 @@
     Preconditions.checkArgument(StringUtils.isNotEmpty(appname),
         "Null/empty application name");
     Preconditions.checkArgument(desiredState != null, "Null desiredState");
-    ApplicationReport found = null;
-    ApplicationReport foundAndLive = null;
     log.debug("Searching {} records for instance name {} in state '{}'",
         instances.size(), appname, desiredState);
     for (ApplicationReport app : instances) {
@@ -350,4 +366,45 @@
     log.debug("No match");
     return null;
   }
+
+  /**
+   * List the nodes in the cluster, possibly filtering by node state or label.
+   *
+   * @param label label to filter by -or "" for any
+   * @param live flag to request running nodes only
+   * @return a possibly empty list of nodes in the cluster
+   * @throws IOException IO problems
+   * @throws YarnException YARN problems
+   */
+  public NodeInformationList listNodes(String label, boolean live)
+    throws IOException, YarnException {
+    Preconditions.checkArgument(label != null, "null label");
+    NodeState[] states;
+    if (live) {
+      states = new NodeState[1];
+      states[0] = NodeState.RUNNING;
+    } else {
+      states = new NodeState[0];
+    }
+    List<NodeReport> reports = getNodeReports(states);
+    NodeInformationList results = new NodeInformationList(reports.size());
+    for (NodeReport report : reports) {
+      if (live && report.getNodeState() != NodeState.RUNNING) {
+        continue;
+      }
+      if (!label.isEmpty() && !report.getNodeLabels().contains(label)) {
+        continue;
+      }
+      // build node info from report
+      NodeInformation info = new NodeInformation();
+      info.hostname = report.getNodeId().getHost();
+      info.healthReport  = report.getHealthReport();
+      info.httpAddress = report.getHttpAddress();
+      info.labels = SliderUtils.extractNodeLabel(report);
+      info.rackName = report.getRackName();
+      info.state = report.getNodeState().toString();
+      results.add(info);
+    }
+    return results;
+  }
 }
diff --git a/slider-core/src/main/java/org/apache/slider/client/ipc/SliderApplicationIpcClient.java b/slider-core/src/main/java/org/apache/slider/client/ipc/SliderApplicationIpcClient.java
index bada24e..a007326 100644
--- a/slider-core/src/main/java/org/apache/slider/client/ipc/SliderApplicationIpcClient.java
+++ b/slider-core/src/main/java/org/apache/slider/client/ipc/SliderApplicationIpcClient.java
@@ -23,6 +23,8 @@
 import org.apache.slider.api.types.ApplicationLivenessInformation;
 import org.apache.slider.api.types.ComponentInformation;
 import org.apache.slider.api.types.ContainerInformation;
+import org.apache.slider.api.types.NodeInformation;
+import org.apache.slider.api.types.NodeInformationList;
 import org.apache.slider.api.types.PingInformation;
 import org.apache.slider.api.SliderApplicationApi;
 import org.apache.slider.core.conf.AggregateConf;
@@ -186,8 +188,7 @@
   }
 
   @Override
-  public ComponentInformation getComponent(String componentName) throws
-      IOException {
+  public ComponentInformation getComponent(String componentName) throws IOException {
     try {
       return operations.getComponent(componentName);
     } catch (IOException e) {
@@ -196,6 +197,24 @@
   }
 
   @Override
+  public NodeInformationList getLiveNodes() throws IOException {
+    try {
+      return operations.getLiveNodes();
+    } catch (IOException e) {
+      throw convert(e);
+    }
+  }
+
+  @Override
+  public NodeInformation getLiveNode(String hostname) throws IOException {
+    try {
+      return operations.getLiveNode(hostname);
+    } catch (IOException e) {
+      throw convert(e);
+    }
+  }
+
+  @Override
   public PingInformation ping(String text) throws IOException {
     return null;
   }
diff --git a/slider-core/src/main/java/org/apache/slider/client/ipc/SliderClusterOperations.java b/slider-core/src/main/java/org/apache/slider/client/ipc/SliderClusterOperations.java
index 69dcb3b..392f451 100644
--- a/slider-core/src/main/java/org/apache/slider/client/ipc/SliderClusterOperations.java
+++ b/slider-core/src/main/java/org/apache/slider/client/ipc/SliderClusterOperations.java
@@ -19,6 +19,9 @@
 package org.apache.slider.client.ipc;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import org.apache.hadoop.yarn.api.records.NodeReport;
+import org.apache.hadoop.yarn.api.records.NodeState;
 import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.slider.api.ClusterDescription;
 import org.apache.slider.api.ClusterNode;
@@ -30,8 +33,11 @@
 import org.apache.slider.api.types.ApplicationLivenessInformation;
 import org.apache.slider.api.types.ComponentInformation;
 import org.apache.slider.api.types.ContainerInformation;
+import org.apache.slider.api.types.NodeInformation;
+import org.apache.slider.api.types.NodeInformationList;
 import org.apache.slider.api.types.PingInformation;
 import org.apache.slider.common.tools.Duration;
+import org.apache.slider.common.tools.SliderUtils;
 import org.apache.slider.core.conf.AggregateConf;
 import org.apache.slider.core.conf.ConfTree;
 import org.apache.slider.core.conf.ConfTreeOperations;
@@ -102,7 +108,7 @@
    */
   public List<ClusterNode> convertNodeWireToClusterNodes(List<Messages.RoleInstanceState> nodes)
     throws IOException {
-    List<ClusterNode> nodeList = new ArrayList<ClusterNode>(nodes.size());
+    List<ClusterNode> nodeList = new ArrayList<>(nodes.size());
     for (Messages.RoleInstanceState node : nodes) {
       nodeList.add(ClusterNode.fromProtobuf(node));
     }
@@ -116,16 +122,12 @@
    * @throws YarnException
    * @throws IOException
    */
-  public String echo(String text) throws
-                                          YarnException,
-                                          IOException {
+  public String echo(String text) throws YarnException, IOException {
     Messages.EchoRequestProto.Builder builder =
       Messages.EchoRequestProto.newBuilder();
     builder.setText(text);
-    Messages.EchoRequestProto req =
-      builder.build();
-    Messages.EchoResponseProto response =
-      appMaster.echo(req);
+    Messages.EchoRequestProto req = builder.build();
+    Messages.EchoResponseProto response = appMaster.echo(req);
     return response.getText();
   }
 
@@ -145,9 +147,7 @@
     try {
       return ClusterDescription.fromJson(statusJson);
     } catch (JsonParseException e) {
-      log.error(
-        "Exception " + e + " parsing:\n" + statusJson,
-        e);
+      log.error("Exception " + e + " parsing:\n" + statusJson, e);
       throw e;
     }
   }
@@ -191,10 +191,8 @@
     Messages.KillContainerRequestProto.Builder builder =
       Messages.KillContainerRequestProto.newBuilder();
     builder.setId(id);
-    Messages.KillContainerRequestProto req =
-      builder.build();
-    Messages.KillContainerResponseProto response =
-      appMaster.killContainer(req);
+    Messages.KillContainerRequestProto req = builder.build();
+    Messages.KillContainerResponseProto response = appMaster.killContainer(req);
     return response.getSuccess();
   }
 
@@ -205,24 +203,19 @@
    * @throws IOException
    * @throws YarnException
    */
-  public String[] listNodeUUIDsByRole(String role) throws
-                                                   IOException,
-                                                   YarnException {
+  public String[] listNodeUUIDsByRole(String role) throws IOException, YarnException {
     Collection<String> uuidList = innerListNodeUUIDSByRole(role);
     String[] uuids = new String[uuidList.size()];
     return uuidList.toArray(uuids);
   }
 
-  public List<String> innerListNodeUUIDSByRole(String role) throws
-                                                             IOException,
-                                                             YarnException {
+  public List<String> innerListNodeUUIDSByRole(String role) throws IOException, YarnException {
     Messages.ListNodeUUIDsByRoleRequestProto req =
       Messages.ListNodeUUIDsByRoleRequestProto
               .newBuilder()
               .setRole(role)
               .build();
-    Messages.ListNodeUUIDsByRoleResponseProto resp =
-      appMaster.listNodeUUIDsByRole(req);
+    Messages.ListNodeUUIDsByRoleResponseProto resp = appMaster.listNodeUUIDsByRole(req);
     return resp.getUuidList();
   }
 
@@ -234,9 +227,8 @@
    * @throws IOException
    * @throws YarnException
    */
-  public List<ClusterNode> listClusterNodesInRole(String role) throws
-                                                               IOException,
-                                                               YarnException {
+  public List<ClusterNode> listClusterNodesInRole(String role)
+      throws IOException, YarnException {
 
     Collection<String> uuidList = innerListNodeUUIDSByRole(role);
     Messages.GetClusterNodesRequestProto req =
@@ -250,15 +242,14 @@
 
   /**
    * Get the details on a list of uuids
-   * @param uuids
+   * @param uuids instance IDs
    * @return a possibly empty list of node details
    * @throws IOException
    * @throws YarnException
    */
   @VisibleForTesting
-  public List<ClusterNode> listClusterNodes(String[] uuids) throws
-                                                            IOException,
-                                                            YarnException {
+  public List<ClusterNode> listClusterNodes(String[] uuids)
+      throws IOException, YarnException {
 
     Messages.GetClusterNodesRequestProto req =
       Messages.GetClusterNodesRequestProto
@@ -341,8 +332,7 @@
       Messages.FlexClusterRequestProto.newBuilder()
               .setClusterSpec(resources.toJson())
               .build();
-    Messages.FlexClusterResponseProto response =
-      appMaster.flexCluster(request);
+    Messages.FlexClusterResponseProto response = appMaster.flexCluster(request);
     return response.getResponse();
   }
 
@@ -365,10 +355,8 @@
     }
     builder.setSignal(signal);
     builder.setDelay(delay);
-    Messages.AMSuicideRequestProto req =
-      builder.build();
-    Messages.AMSuicideResponseProto response =
-      appMaster.amSuicide(req);
+    Messages.AMSuicideRequestProto req = builder.build();
+    appMaster.amSuicide(req);
   }
 
   /**
@@ -385,45 +373,38 @@
 
   }
 
-   
   public AggregateConf getModelDesired() throws IOException {
     return unmarshallToAggregateConf(appMaster.getModelDesired(EMPTY));
   }
 
   
   public ConfTreeOperations getModelDesiredAppconf() throws IOException {
-    return unmarshallToCTO(
-        appMaster.getModelDesiredAppconf(EMPTY));
+    return unmarshallToCTO(appMaster.getModelDesiredAppconf(EMPTY));
   }
 
   
   public ConfTreeOperations getModelDesiredResources() throws IOException {
-    return unmarshallToCTO(
-        appMaster.getModelDesiredResources(EMPTY));
+    return unmarshallToCTO(appMaster.getModelDesiredResources(EMPTY));
   }
 
   
   public AggregateConf getModelResolved() throws IOException {
-    return unmarshallToAggregateConf(
-        appMaster.getModelResolved(EMPTY));
+    return unmarshallToAggregateConf(appMaster.getModelResolved(EMPTY));
   }
 
   
   public ConfTreeOperations getModelResolvedAppconf() throws IOException {
-    return unmarshallToCTO(
-        appMaster.getModelResolvedAppconf(EMPTY));
+    return unmarshallToCTO(appMaster.getModelResolvedAppconf(EMPTY));
   }
 
   
   public ConfTreeOperations getModelResolvedResources() throws IOException {
-    return unmarshallToCTO(
-        appMaster.getModelDesiredResources(EMPTY));
+    return unmarshallToCTO(appMaster.getModelDesiredResources(EMPTY));
   }
 
   
   public ConfTreeOperations getLiveResources() throws IOException {
-    return unmarshallToCTO(
-        appMaster.getLiveResources(EMPTY));
+    return unmarshallToCTO(appMaster.getLiveResources(EMPTY));
   }
 
   
@@ -439,8 +420,7 @@
                       + ") does not match the number of records returned: " 
                       + records);
     }
-    Map<String, ContainerInformation> map =
-        new HashMap<String, ContainerInformation>(namesCount);
+    Map<String, ContainerInformation> map = new HashMap<>(namesCount);
     for (int i = 0; i < namesCount; i++) {
       map.put(response.getNames(i), unmarshall(response.getContainers(i)));
     }
@@ -473,42 +453,53 @@
     int namesCount = response.getNamesCount();
     int records = response.getComponentsCount();
     if (namesCount != records) {
-      throw new IOException("Number of names returned (" + namesCount
-                            +
-                            ") does not match the number of records returned: "
-                            + records);
+      throw new IOException(
+          "Number of names returned (" + namesCount + ")" +
+          " does not match the number of records returned: " + records);
     }
-    Map<String, ComponentInformation> map =
-        new HashMap<String, ComponentInformation>(namesCount);
+    Map<String, ComponentInformation> map = new HashMap<>(namesCount);
     for (int i = 0; i < namesCount; i++) {
       map.put(response.getNames(i), unmarshall(response.getComponents(i)));
     }
     return map;
   }
 
-  
   public ComponentInformation getComponent(String componentName)
       throws IOException {
     Messages.GetLiveComponentRequestProto.Builder builder =
         Messages.GetLiveComponentRequestProto.newBuilder();
     builder.setName(componentName);
-    Messages.ComponentInformationProto proto =
-        appMaster.getLiveComponent(builder.build());
-    
+    Messages.ComponentInformationProto proto = appMaster.getLiveComponent(builder.build());
     return unmarshall(proto);
   }
 
-  
+  public NodeInformationList getLiveNodes() throws IOException {
+    Messages.GetLiveNodesResponseProto response =
+      appMaster.getLiveNodes(Messages.GetLiveNodesRequestProto.newBuilder().build());
+
+    int records = response.getNodesCount();
+    NodeInformationList nil = new NodeInformationList(records);
+    for (int i = 0; i < records; i++) {
+      nil.add(unmarshall(response.getNodes(i)));
+    }
+    return nil;
+  }
+
+  public NodeInformation getLiveNode(String hostname) throws IOException {
+    Messages.GetLiveNodeRequestProto.Builder builder =
+        Messages.GetLiveNodeRequestProto.newBuilder();
+    builder.setName(hostname);
+    return unmarshall(appMaster.getLiveNode(builder.build()));
+  }
+
   public PingInformation ping(String text) throws IOException {
     return null;
   }
 
-  
   public void stop(String text) throws IOException {
     amSuicide(text, 3, 0);
   }
 
-  
   public ApplicationLivenessInformation getApplicationLiveness() throws
       IOException {
     Messages.ApplicationLivenessInformationProto proto =
@@ -535,5 +526,4 @@
 
     return unmarshall(response);
   }
-
 }
diff --git a/slider-core/src/main/java/org/apache/slider/client/rest/SliderApplicationApiRestClient.java b/slider-core/src/main/java/org/apache/slider/client/rest/SliderApplicationApiRestClient.java
index b1aa633..4283ee8 100644
--- a/slider-core/src/main/java/org/apache/slider/client/rest/SliderApplicationApiRestClient.java
+++ b/slider-core/src/main/java/org/apache/slider/client/rest/SliderApplicationApiRestClient.java
@@ -21,7 +21,6 @@
 import com.google.common.base.Preconditions;
 import com.sun.jersey.api.client.Client;
 import com.sun.jersey.api.client.ClientHandlerException;
-import com.sun.jersey.api.client.ClientResponse;
 import com.sun.jersey.api.client.GenericType;
 import com.sun.jersey.api.client.UniformInterfaceException;
 import com.sun.jersey.api.client.WebResource;
@@ -31,11 +30,12 @@
 import org.apache.slider.api.types.ComponentInformation;
 import org.apache.slider.api.types.ContainerInformation;
 import org.apache.slider.api.SliderApplicationApi;
+import org.apache.slider.api.types.NodeInformation;
+import org.apache.slider.api.types.NodeInformationList;
 import org.apache.slider.core.conf.AggregateConf;
 import org.apache.slider.core.conf.ConfTree;
 import org.apache.slider.core.conf.ConfTreeOperations;
 import org.apache.slider.core.exceptions.ExceptionConverter;
-import org.apache.slider.core.persist.ConfTreeSerDeser;
 import org.apache.slider.core.restclient.HttpVerb;
 import org.apache.slider.api.types.PingInformation;
 import org.slf4j.Logger;
@@ -67,6 +67,19 @@
     this.appResource = appResource;
   }
 
+  /**
+   * Create an instance
+   * @param jerseyClient jersey client for operations
+   * @param appmaster URL of appmaster/proxy to AM
+   */
+  public SliderApplicationApiRestClient(Client jerseyClient, String appmaster) {
+    super(jerseyClient);
+    WebResource amResource = jerseyClient.resource(appmaster);
+    amResource.type(MediaType.APPLICATION_JSON);
+    this.appResource = amResource.path(SLIDER_PATH_APPLICATION);
+  }
+
+
   @Override
   public String toString() {
     final StringBuilder sb =
@@ -232,8 +245,7 @@
   public Map<String, ComponentInformation> enumComponents() throws
       IOException {
     return getApplicationResource(LIVE_COMPONENTS,
-        new GenericType<Map<String, ComponentInformation>>() {
-        });
+        new GenericType<Map<String, ComponentInformation>>() { });
   }
 
   @Override
@@ -244,6 +256,17 @@
   }
 
   @Override
+  public NodeInformationList getLiveNodes() throws IOException {
+    return getApplicationResource(LIVE_NODES, NodeInformationList.class);
+  }
+
+  @Override
+  public NodeInformation getLiveNode(String hostname) throws IOException {
+    return getApplicationResource(LIVE_NODES + "/" + hostname,
+        NodeInformation.class);
+  }
+
+  @Override
   public PingInformation ping(String text) throws IOException {
     return pingPost(text);
   }
diff --git a/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java b/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java
index 3d2b868..26109a7 100644
--- a/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java
+++ b/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java
@@ -125,6 +125,8 @@
       "hadoop.http.filter.initializers";
   String KEY_KEYSTORE_LOCATION = "ssl.server.keystore.location";
   String KEY_AM_LOGIN_KEYTAB_NAME = "slider.am.login.keytab.name";
+  /** Declare that a keytab must be provided */
+  String KEY_AM_LOGIN_KEYTAB_REQUIRED = "slider.am.login.keytab.required";
   String KEY_HDFS_KEYTAB_DIR = "slider.hdfs.keytab.dir";
   String KEY_AM_KEYTAB_LOCAL_PATH = "slider.am.keytab.local.path";
   String KEY_KEYTAB_PRINCIPAL = "slider.keytab.principal.name";
@@ -166,11 +168,39 @@
    */
   String KEY_IPC_CLIENT_RETRY_POLICY_ENABLED =
       "slider.ipc.client.retry.enabled";
-  public static final boolean IPC_CLIENT_RETRY_POLICY_ENABLED_DEFAULT = true;
-  public static final String KEY_IPC_CLIENT_RETRY_POLICY_SPEC =
+  boolean IPC_CLIENT_RETRY_POLICY_ENABLED_DEFAULT = true;
+  String KEY_IPC_CLIENT_RETRY_POLICY_SPEC =
       "slider.ipc.client.retry.policy.spec";
-  public static final String IPC_CLIENT_RETRY_POLICY_SPEC_DEFAULT =
+  String IPC_CLIENT_RETRY_POLICY_SPEC_DEFAULT =
       "10000,6,60000,10"; //t1,n1,t2,n2,... 
 
   String KEY_AM_LAUNCH_ENV = "slider.am.launch.env";
+
+  /**
+   * From {@code DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY}
+   */
+  String DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY = "dfs.namenode.kerberos.principal";
+
+  String DFS_DATANODE_KERBEROS_PRINCIPAL_KEY = "dfs.datanode.kerberos.principal";
+
+  //Delegation token related keys
+  String DFS_NAMENODE_DELEGATION_KEY_UPDATE_INTERVAL_KEY
+      = "dfs.namenode.delegation.key.update-interval";
+  long DFS_NAMENODE_DELEGATION_KEY_UPDATE_INTERVAL_DEFAULT = 24 * 60 * 60 *
+      1000; // 1 day
+  String DFS_NAMENODE_DELEGATION_TOKEN_RENEW_INTERVAL_KEY
+      = "dfs.namenode.delegation.token.renew-interval";
+  long DFS_NAMENODE_DELEGATION_TOKEN_RENEW_INTERVAL_DEFAULT = 24 * 60 * 60 *
+      1000;  // 1 day
+  String DFS_NAMENODE_DELEGATION_TOKEN_MAX_LIFETIME_KEY
+      = "dfs.namenode.delegation.token.max-lifetime";
+  long DFS_NAMENODE_DELEGATION_TOKEN_MAX_LIFETIME_DEFAULT = 7 * 24 * 60 * 60 *
+      1000; // 7 days
+  String DFS_NAMENODE_DELEGATION_TOKEN_ALWAYS_USE_KEY
+      = "dfs.namenode.delegation.token.always-use"; // for tests
+  boolean DFS_NAMENODE_DELEGATION_TOKEN_ALWAYS_USE_DEFAULT = false;
+  String DFS_NAMENODE_KEYTAB_FILE_KEY = "dfs.namenode.keytab.file";
+  String DFS_NAMENODE_DU_RESERVED_KEY = "dfs.namenode.resource.du.reserved";
+
+
 }
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/AbstractActionArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/AbstractActionArgs.java
index 17c235f..d0b1693 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/AbstractActionArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/AbstractActionArgs.java
@@ -56,7 +56,7 @@
    * This is the default parameter
    */
   @Parameter
-  public final List<String> parameters = new ArrayList<String>();
+  public final List<String> parameters = new ArrayList<>();
 
   /**
    * get the name: relies on arg 1 being the cluster name in all operations 
@@ -77,7 +77,7 @@
    */
 
   @Parameter(names = ARG_DEFINE, arity = 1, description = "Definitions")
-  public final List<String> definitions = new ArrayList<String>();
+  public final List<String> definitions = new ArrayList<>();
 
   /**
    * System properties
@@ -85,7 +85,7 @@
   @Parameter(names = {ARG_SYSPROP}, arity = 1,
              description = "system properties in the form name value" +
                            " These are set after the JVM is started.")
-  public final List<String> sysprops = new ArrayList<String>(0);
+  public final List<String> sysprops = new ArrayList<>(0);
 
 
   @Parameter(names = {ARG_MANAGER_SHORT, ARG_MANAGER},
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java
index f2e3c61..1c694bd 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java
@@ -59,7 +59,7 @@
 
   /**
    * --image path
-   the full path to a .tar or .tar.gz path containing an HBase image.
+   * the full path to a .tar or .tar.gz path containing an HBase image.
    */
   @Parameter(names = ARG_IMAGE,
       description = "The full path to a .tar or .tar.gz path containing the application",
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ActionAMSuicideArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ActionAMSuicideArgs.java
index d6cabf5..5b4cfdc 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ActionAMSuicideArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ActionAMSuicideArgs.java
@@ -21,7 +21,6 @@
 import com.beust.jcommander.Parameter;
 import com.beust.jcommander.Parameters;
 
-
 @Parameters(commandNames = {SliderActions.ACTION_AM_SUICIDE},
             commandDescription = SliderActions.DESCRIBE_ACTION_AM_SUICIDE)
 public class ActionAMSuicideArgs extends AbstractActionArgs {
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ActionDestroyArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ActionDestroyArgs.java
index 1203d28..4a129ab 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ActionDestroyArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ActionDestroyArgs.java
@@ -18,15 +18,20 @@
 
 package org.apache.slider.common.params;
 
+import com.beust.jcommander.Parameter;
 import com.beust.jcommander.Parameters;
 
 @Parameters(commandNames = {SliderActions.ACTION_DESTROY},
             commandDescription = SliderActions.DESCRIBE_ACTION_DESTROY)
 
 public class ActionDestroyArgs extends AbstractActionArgs {
-  
+
   @Override
   public String getActionName() {
     return SliderActions.ACTION_DESTROY;
   }
+
+  @Parameter(names = {ARG_FORCE},
+             description = "force the operation")
+  public boolean force;
 }
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ActionDiagnosticArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ActionDiagnosticArgs.java
index 4b03336..c891873 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ActionDiagnosticArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ActionDiagnosticArgs.java
@@ -37,7 +37,7 @@
 	  @Parameter(names = {ARG_CLIENT}, 
 	      description = "print configuration of the slider client")
 	  public boolean client = false;
-	
+
 	  @Parameter(names = {ARG_APPLICATION}, 
 	      description = "print configuration of the running application")
 	  public boolean application;
@@ -49,15 +49,15 @@
 	  @Parameter(names = {ARG_YARN}, 
 	      description = "print configuration of the YARN cluster")
 	  public boolean yarn = false;
-	
+
 	  @Parameter(names = {ARG_CREDENTIALS}, 
 	      description = "print credentials of the current user")
 	  public boolean credentials = false;
-	
+
 	  @Parameter(names = {ARG_ALL}, 
 	      description = "print all of the information above")
 	  public boolean all;
-	
+
 	  @Parameter(names = {ARG_LEVEL}, 
 	      description = "diagnose each slider configuration one by one")
 	  public boolean level;
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ActionEchoArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ActionEchoArgs.java
index b0f53f8..d05f10b 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ActionEchoArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ActionEchoArgs.java
@@ -20,15 +20,10 @@
 
 import com.beust.jcommander.Parameter;
 
-/*
-
-@Parameters(commandNames = {SliderActions.ACTION_KILL_CONTAINER},
-            commandDescription = SliderActions.DESCRIBE_ACTION_KILL_CONTAINER)
-*/
 public class ActionEchoArgs extends AbstractActionArgs {
   @Override
   public String getActionName() {
-    return SliderActions.ACTION_DESTROY;
+    return SliderActions.ACTION_ECHO;
   }
 
   @Parameter(names = {ARG_MESSAGE},
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ActionListArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ActionListArgs.java
index 0bc5792..739b5fc 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ActionListArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ActionListArgs.java
@@ -57,7 +57,7 @@
   @Parameter(names = {ARG_COMPONENTS}, variableArity = true,
       description = "Filter containers by component names (used with " +
                     ARG_CONTAINERS + ")")
-  public Set<String> components = new HashSet<>(0);;
+  public Set<String> components = new HashSet<>(0);
 
   /**
    * Get the min #of params expected
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ActionLookupArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ActionLookupArgs.java
index 3b69e74..1b73522 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ActionLookupArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ActionLookupArgs.java
@@ -43,7 +43,7 @@
   }
   
   @Parameter(names = {ARG_ID},
-             description = "ID of the container")
+             description = "ID of the application")
   public String id;
 
   @Parameter(names = {ARG_OUTPUT, ARG_OUTPUT_SHORT},
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ActionNodesArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ActionNodesArgs.java
new file mode 100644
index 0000000..5ddccf6
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ActionNodesArgs.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.common.params;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+
+import java.io.File;
+
+@Parameters(commandNames = {SliderActions.ACTION_NODES},
+            commandDescription = SliderActions.DESCRIBE_ACTION_NODES)
+public class ActionNodesArgs extends AbstractActionArgs {
+
+  /**
+   * Instance for API use; on CLI the name is derived from {@link #getClusterName()}.
+   */
+  public String instance;
+
+  @Override
+  public String getActionName() {
+    return SliderActions.ACTION_NODES;
+  }
+
+  @Parameter(names = {ARG_OUTPUT, ARG_OUTPUT_SHORT},
+             description = "Output file for the information")
+  public File outputFile;
+
+  @Parameter(names = {ARG_LABEL})
+  public String label = "";
+
+  @Parameter(names = {ARG_HEALTHY} )
+  public boolean healthy;
+
+  @Override
+  public int getMinParams() {
+    return 0;
+  }
+
+  @Override
+  public String toString() {
+    final StringBuilder sb = new StringBuilder(
+      "ActionNodesArgs{");
+    sb.append("instance='").append(instance).append('\'');
+    sb.append(", outputFile=").append(outputFile);
+    sb.append(", label='").append(label).append('\'');
+    sb.append(", healthy=").append(healthy);
+    sb.append('}');
+    return sb.toString();
+  }
+}
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ActionStatusArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ActionStatusArgs.java
index a7edb65..00178df 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ActionStatusArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ActionStatusArgs.java
@@ -25,13 +25,14 @@
             commandDescription = SliderActions.DESCRIBE_ACTION_STATUS)
 
 public class ActionStatusArgs extends AbstractActionArgs {
+
   @Override
   public String getActionName() {
     return SliderActions.ACTION_STATUS;
   }
 
   @Parameter(names = {ARG_OUTPUT, ARG_OUTPUT_SHORT},
-             description = "Output file for the configuration data")
+             description = "Output file for the status information")
   public String output;
 
   public String getOutput() {
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ActionUpgradeArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ActionUpgradeArgs.java
index 832e1cc..6ef51b2 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ActionUpgradeArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ActionUpgradeArgs.java
@@ -61,11 +61,11 @@
 
   @Parameter(names={ARG_CONTAINERS}, variableArity = true,
              description = "stop specific containers")
-  public List<String> containers = new ArrayList<String>(0);
+  public List<String> containers = new ArrayList<>(0);
 
   @Parameter(names={ARG_COMPONENTS}, variableArity = true,
       description = "stop all containers of specific components")
-  public List<String> components = new ArrayList<String>(0);
+  public List<String> components = new ArrayList<>(0);
 
   @Parameter(names = {ARG_FORCE},
       description = "force spec upgrade operation")
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/AddonArgsDelegate.java b/slider-core/src/main/java/org/apache/slider/common/params/AddonArgsDelegate.java
index 65ebc4b..3ef8e19 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/AddonArgsDelegate.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/AddonArgsDelegate.java
@@ -34,7 +34,7 @@
       arity = 2,
       description = "--addon <name> <folder or package>",
       splitter = DontSplitArguments.class)
-  public List<String> addonTuples = new ArrayList<String>(0);
+  public List<String> addonTuples = new ArrayList<>(0);
 
 
   /**
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/AppAndResouceOptionArgsDelegate.java b/slider-core/src/main/java/org/apache/slider/common/params/AppAndResouceOptionArgsDelegate.java
index 1f07de3..248e4c2 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/AppAndResouceOptionArgsDelegate.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/AppAndResouceOptionArgsDelegate.java
@@ -37,7 +37,7 @@
   @Parameter(names = {ARG_OPTION, ARG_OPTION_SHORT}, arity = 2,
              description = ARG_OPTION + "<name> <value>",
              splitter = DontSplitArguments.class)
-  public List<String> optionTuples = new ArrayList<String>(0);
+  public List<String> optionTuples = new ArrayList<>(0);
 
 
   /**
@@ -47,7 +47,7 @@
              description = "Component option " + ARG_COMP_OPT +
                            " <component> <name> <option>",
              splitter = DontSplitArguments.class)
-  public List<String> compOptTriples = new ArrayList<String>(0);
+  public List<String> compOptTriples = new ArrayList<>(0);
 
   /**
    * Resource Options
@@ -55,7 +55,7 @@
   @Parameter(names = {ARG_RESOURCE_OPT, ARG_RESOURCE_OPT_SHORT}, arity = 2,
              description = "Resource option "+ ARG_RESOURCE_OPT + "<name> <value>",
              splitter = DontSplitArguments.class)
-  public List<String> resOptionTuples = new ArrayList<String>(0);
+  public List<String> resOptionTuples = new ArrayList<>(0);
 
 
   /**
@@ -65,7 +65,7 @@
              description = "Component resource option " + ARG_RES_COMP_OPT +
                            " <component> <name> <option>",
              splitter = DontSplitArguments.class)
-  public List<String> resCompOptTriples = new ArrayList<String>(0);
+  public List<String> resCompOptTriples = new ArrayList<>(0);
 
 
   public Map<String, String> getOptionsMap() throws
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ArgOps.java b/slider-core/src/main/java/org/apache/slider/common/params/ArgOps.java
index aeb2979..12a2032 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ArgOps.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ArgOps.java
@@ -44,20 +44,13 @@
    * create a 3-tuple
    */
   public static List<Object> triple(String msg, int min, int max) {
-    List<Object> l = new ArrayList<Object>(3);
+    List<Object> l = new ArrayList<>(3);
     l.add(msg);
     l.add(min);
     l.add(max);
     return l;
   }
 
-  /**
-   * Create a tuple
-   */
-  public static List<Object> tuple(String msg, int min) {
-    return triple(msg, min, min);
-  }
-
   public static void applyFileSystemBinding(String filesystemBinding,
       Configuration conf) {
     if (filesystemBinding != null) {
@@ -100,7 +93,7 @@
   public static Map<String, String> convertTupleListToMap(String description,
                                                           List<String> list) throws
                                                                              BadCommandArgumentsException {
-    Map<String, String> results = new HashMap<String, String>();
+    Map<String, String> results = new HashMap<>();
     if (list != null && !list.isEmpty()) {
       int size = list.size();
       if (size % 2 != 0) {
@@ -131,10 +124,9 @@
    * @throws BadCommandArgumentsException odd #of arguments received
    */
   public static Map<String, Map<String, String>> convertTripleListToMaps(String description,
-                                                                         List<String> list) throws
-                                                                                            BadCommandArgumentsException {
-    Map<String, Map<String, String>> results =
-      new HashMap<String, Map<String, String>>();
+         List<String> list) throws BadCommandArgumentsException {
+
+    Map<String, Map<String, String>> results = new HashMap<>();
     if (list != null && !list.isEmpty()) {
       int size = list.size();
       if (size % 3 != 0) {
@@ -149,7 +141,7 @@
         Map<String, String> roleMap = results.get(role);
         if (roleMap == null) {
           //demand create new role map
-          roleMap = new HashMap<String, String>();
+          roleMap = new HashMap<>();
           results.put(role, roleMap);
         }
         if (roleMap.get(key) != null) {
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java b/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java
index c2fa09c..ca22c24 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java
@@ -60,6 +60,7 @@
   String ARG_GETCONF = "--getconf";
   String ARG_GETEXP = "--getexp";
   String ARG_GETFILES = "--getfiles";
+  String ARG_HEALTHY= "--healthy";
   String ARG_HELP = "--help";
   String ARG_HOSTNAME = "--hostname";
   String ARG_ID = "--id";
@@ -70,6 +71,7 @@
   String ARG_KEYTABINSTALL = "--install";
   String ARG_KEYTABDELETE = "--delete";
   String ARG_KEYTABLIST = "--list";
+  String ARG_LABEL = "--label";
   String ARG_LEVEL = "--level";
   String ARG_LIST = "--list";
   String ARG_LISTCONF = "--listconf";
@@ -125,10 +127,14 @@
 
 
   /**
-   * Deprecated
+   * Deprecated: use ARG_COMPONENT
    */
   @Deprecated
   String ARG_ROLE = "--role";
+
+  /**
+   * Deprecated: use ARG_COMP_OPT
+   */
   @Deprecated
   String ARG_ROLEOPT = "--roleopt";
 
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ClientArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ClientArgs.java
index 3c430f3..ea1448b 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ClientArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ClientArgs.java
@@ -66,6 +66,7 @@
     new ActionKillContainerArgs();
   private final ActionListArgs actionListArgs = new ActionListArgs();
   private final ActionLookupArgs actionLookupArgs = new ActionLookupArgs();
+  private final ActionNodesArgs actionNodesArgs = new ActionNodesArgs();
   private final ActionRegistryArgs actionRegistryArgs = new ActionRegistryArgs();
   private final ActionResolveArgs actionResolveArgs = new ActionResolveArgs();
   private final ActionStatusArgs actionStatusArgs = new ActionStatusArgs();
@@ -86,31 +87,32 @@
   protected void addActionArguments() {
 
     addActions(
-        actionPackageArgs,
-        actionKeytabArgs,
+        actionAMSuicideArgs,
         actionBuildArgs,
-        actionDependencyArgs,
-        actionCreateArgs,
-        actionListArgs,
-        actionStatusArgs,
-        actionRegistryArgs,
         actionClientArgs,
-        actionFlexArgs,
+        actionCreateArgs,
+        actionDependencyArgs,
+        actionDestroyArgs,
         actionDiagnosticArgs,
+        actionExistsArgs,
+        actionFlexArgs,
         actionFreezeArgs,
+        actionHelpArgs,
+        actionInstallKeytabArgs,
+        actionInstallPackageArgs,
+        actionKeytabArgs,
+        actionKillContainerArgs,
+        actionListArgs,
+        actionLookupArgs,
+        actionNodesArgs,
+        actionPackageArgs,
+        actionRegistryArgs,
+        actionResolveArgs,
+        actionStatusArgs,
         actionThawArgs,
         actionUpdateArgs,
         actionUpgradeArgs,
-        actionDestroyArgs,
-        actionExistsArgs,
-        actionLookupArgs,
-        actionResolveArgs,
-        actionKillContainerArgs,
-        actionAMSuicideArgs,
-        actionInstallPackageArgs,
-        actionInstallKeytabArgs,
-        actionVersionArgs,
-        actionHelpArgs
+        actionVersionArgs
     );
   }
 
@@ -196,6 +198,10 @@
     return actionListArgs;
   }
 
+  public ActionNodesArgs getActionNodesArgs() {
+    return actionNodesArgs;
+  }
+
   public ActionLookupArgs getActionLookupArgs() {
     return actionLookupArgs;
   }
@@ -286,6 +292,9 @@
     } else if (SliderActions.ACTION_LOOKUP.equals(action)) {
       bindCoreAction(actionLookupArgs);
 
+    } else if (SliderActions.ACTION_NODES.equals(action)) {
+      bindCoreAction(actionNodesArgs);
+
     } else if (SliderActions.ACTION_REGISTRY.equals(action)) {
       bindCoreAction(actionRegistryArgs);
 
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/CommonArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/CommonArgs.java
index 7e02eec..162a87d 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/CommonArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/CommonArgs.java
@@ -91,12 +91,12 @@
     return coreAction.getClusterName();
   }
 
-  public CommonArgs(String[] args) {
+  protected CommonArgs(String[] args) {
     this.args = args;
     commander = new JCommander(this);
   }
 
-  public CommonArgs(Collection args) {
+  protected CommonArgs(Collection args) {
     List<String> argsAsStrings = SliderUtils.collectionToStringList(args);
     this.args = argsAsStrings.toArray(new String[argsAsStrings.size()]);
     commander = new JCommander(this);
@@ -123,7 +123,7 @@
           .append("Most commands print help when invoked without parameters or with --help");
       result = helperMessage.toString();
     } else {
-      helperMessage.append("\nUsage: slider " + commandOfInterest);
+      helperMessage.append("\nUsage: slider ").append(commandOfInterest);
       helperMessage.append(serviceArgs.coreAction.getMinParams() > 0 ? " <application>" : "");
       helperMessage.append("\n");
       for (ParameterDescription paramDesc : serviceArgs.commander.getCommands()
@@ -171,7 +171,7 @@
   /**
    * Add a command
    * @param name action
-   * @param arg
+   * @param arg value
    */
   protected void addAction(String name, Object arg) {
     commander.addCommand(name, arg);
@@ -249,7 +249,7 @@
       throw new BadCommandArgumentsException(badArgMsgBuilder.toString());
     } catch (UsageException e) {
       StringBuilder badArgMsgBuilder = new StringBuilder();
-      badArgMsgBuilder.append(e.toString() + "\n");
+      badArgMsgBuilder.append(e.toString()).append("\n");
       badArgMsgBuilder.append(usage(this, coreAction.getActionName()));
       throw new UsageException(badArgMsgBuilder.toString());
     }
@@ -289,12 +289,6 @@
     return coreAction.manager;
   }
 
-
-//  public String getRmAddress() {
-//    return rmAddress;
-//  }
-
-
   public String getAction() {
     return commander.getParsedCommand();
   }
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ComponentArgsDelegate.java b/slider-core/src/main/java/org/apache/slider/common/params/ComponentArgsDelegate.java
index 494258e..abda53f 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ComponentArgsDelegate.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ComponentArgsDelegate.java
@@ -34,7 +34,7 @@
              arity = 2,
              description = "--component <name> <count>",
              splitter = DontSplitArguments.class)
-  public List<String> componentTuples = new ArrayList<String>(0);
+  public List<String> componentTuples = new ArrayList<>(0);
 
 
   /**
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/DontSplitArguments.java b/slider-core/src/main/java/org/apache/slider/common/params/DontSplitArguments.java
index 3225133..0344305 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/DontSplitArguments.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/DontSplitArguments.java
@@ -27,7 +27,7 @@
 
   @Override
   public List<String> split(String value) {
-    List<String> list = new ArrayList<String>(1);
+    List<String> list = new ArrayList<>(1);
     list.add(value);
     return list;
   }
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/SliderActions.java b/slider-core/src/main/java/org/apache/slider/common/params/SliderActions.java
index 4d0e04d..1d4e0ea 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/SliderActions.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/SliderActions.java
@@ -39,6 +39,7 @@
   String ACTION_KILL_CONTAINER = "kill-container";
   String ACTION_LIST = "list";
   String ACTION_LOOKUP = "lookup";
+  String ACTION_NODES = "nodes";
   String ACTION_PREFLIGHT = "preflight";
   String ACTION_RECONFIGURE = "reconfigure";
   String ACTION_REGISTRY = "registry";
@@ -65,7 +66,7 @@
   String DESCRIBE_ACTION_UPGRADE =
       "Rolling upgrade/downgrade the application to a newer/previous version";
   String DESCRIBE_ACTION_DESTROY =
-        "Destroy a frozen Slider application)";
+        "Destroy a stopped Slider application";
   String DESCRIBE_ACTION_EXISTS =
             "Probe for an application running";
   String DESCRIBE_ACTION_FLEX = "Flex a Slider application";
@@ -80,6 +81,7 @@
                   "List running Slider applications";
   String DESCRIBE_ACTION_LOOKUP =
                   "look up a YARN application";
+  String DESCRIBE_ACTION_NODES = "List the node information for the YARN cluster or a running application";
   String DESCRIBE_ACTION_MONITOR =
                     "Monitor a running application";
   String DESCRIBE_ACTION_REGISTRY =
diff --git a/slider-core/src/main/java/org/apache/slider/common/tools/Comparators.java b/slider-core/src/main/java/org/apache/slider/common/tools/Comparators.java
index 0ccca0f..6380d0c 100644
--- a/slider-core/src/main/java/org/apache/slider/common/tools/Comparators.java
+++ b/slider-core/src/main/java/org/apache/slider/common/tools/Comparators.java
@@ -21,6 +21,9 @@
 import java.io.Serializable;
 import java.util.Comparator;
 
+/**
+ * Some general comparators
+ */
 public class Comparators {
 
   public static class LongComparator implements Comparator<Long>, Serializable {
@@ -30,12 +33,20 @@
       // need to comparisons with a diff greater than integer size
       if (result < 0 ) {
         return -1;
-      } else if (result >0) {
+      } else if (result > 0) {
         return 1;
       }
       return 0;
     }
   }
+public static class InvertedLongComparator implements Comparator<Long>, Serializable {
+  private static final LongComparator inner = new LongComparator();
+    @Override
+    public int compare(Long o1, Long o2) {
+      return -inner.compare(o1, o2);
+    }
+  }
+
 
   /**
    * Little template class to reverse any comparitor
diff --git a/slider-core/src/main/java/org/apache/slider/common/tools/CoreFileSystem.java b/slider-core/src/main/java/org/apache/slider/common/tools/CoreFileSystem.java
index d34dd2a..a1ad690 100644
--- a/slider-core/src/main/java/org/apache/slider/common/tools/CoreFileSystem.java
+++ b/slider-core/src/main/java/org/apache/slider/common/tools/CoreFileSystem.java
@@ -159,7 +159,7 @@
     Preconditions.checkNotNull(packageName);
     Path path = getBaseApplicationPath();
     path = new Path(path, SliderKeys.PACKAGE_DIRECTORY + "/" + packageName);
-    if (StringUtils.isNotEmpty(packageVersion)) {
+    if (SliderUtils.isSet(packageVersion)) {
       path = new Path(path, packageVersion);
     }
     return path;
diff --git a/slider-core/src/main/java/org/apache/slider/common/tools/Duration.java b/slider-core/src/main/java/org/apache/slider/common/tools/Duration.java
index 25b68ae..e5fa424 100644
--- a/slider-core/src/main/java/org/apache/slider/common/tools/Duration.java
+++ b/slider-core/src/main/java/org/apache/slider/common/tools/Duration.java
@@ -68,7 +68,7 @@
   }
 
   protected long now() {
-    return System.currentTimeMillis();
+    return System.nanoTime()/1000000;
   }
 
   public long getInterval() {
@@ -103,9 +103,7 @@
         builder.append(" -  exceeded");
       }
     }
-    
     return  builder.toString();
   }
 
-
 }
diff --git a/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java b/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
index 8488f71..712eb75 100644
--- a/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
+++ b/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
@@ -35,7 +35,6 @@
 import org.apache.hadoop.fs.GlobFilter;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.fs.permission.FsPermission;
-import org.apache.hadoop.hdfs.DFSConfigKeys;
 import org.apache.hadoop.io.IOUtils;
 import org.apache.hadoop.io.nativeio.NativeIO;
 import org.apache.hadoop.net.NetUtils;
@@ -48,7 +47,9 @@
 import org.apache.hadoop.yarn.api.records.ApplicationReport;
 import org.apache.hadoop.yarn.api.records.Container;
 import org.apache.hadoop.yarn.api.records.LocalResource;
+import org.apache.hadoop.yarn.api.records.NodeReport;
 import org.apache.hadoop.yarn.api.records.YarnApplicationState;
+import org.apache.hadoop.yarn.client.api.AMRMClient;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.slider.Slider;
 import org.apache.slider.api.InternalKeys;
@@ -155,6 +156,7 @@
    * name of docker program
    */
   public static final String DOCKER = "docker";
+  public static final int NODE_LIST_LIMIT = 10;
 
   private SliderUtils() {
   }
@@ -501,8 +503,7 @@
 
     //if the fallback option is NOT set, enable it.
     //if it is explicitly set to anything -leave alone
-    if (conf.get(SliderXmlConfKeys.IPC_CLIENT_FALLBACK_TO_SIMPLE_AUTH) ==
-        null) {
+    if (conf.get(SliderXmlConfKeys.IPC_CLIENT_FALLBACK_TO_SIMPLE_AUTH) == null) {
       conf.set(SliderXmlConfKeys.IPC_CLIENT_FALLBACK_TO_SIMPLE_AUTH, "true");
     }
     return conf;
@@ -747,10 +748,7 @@
    *         through
    */
   public static boolean filter(String value, String filter) {
-    if (StringUtils.isEmpty(filter) || filter.equals(value)) {
-      return false;
-    }
-    return true;
+    return !(StringUtils.isEmpty(filter) || filter.equals(value));
   }
 
   /**
@@ -1035,7 +1033,7 @@
    * something other than 0.0.0.0
    */
   public static boolean isAddressDefined(InetSocketAddress address) {
-    return !(address.getHostName().equals("0.0.0.0"));
+    return !(address.getHostString().equals("0.0.0.0"));
   }
 
   public static void setRmAddress(Configuration conf, String rmAddr) {
@@ -1225,11 +1223,11 @@
    * @param conf configuration to look at
    * @return true if the cluster is secure
    * @throws IOException cluster is secure
-   * @throws BadConfigException the configuration/process is invalid
+   * @throws SliderException the configuration/process is invalid
    */
   public static boolean maybeInitSecurity(Configuration conf) throws
       IOException,
-      BadConfigException {
+      SliderException {
     boolean clusterSecure = isHadoopClusterSecure(conf);
     if (clusterSecure) {
       log.debug("Enabling security");
@@ -1247,7 +1245,7 @@
    */
   public static boolean initProcessSecurity(Configuration conf) throws
       IOException,
-      BadConfigException {
+      SliderException {
 
     if (processSecurityAlreadyInitialized.compareAndSet(true, true)) {
       //security is already inited
@@ -1270,27 +1268,26 @@
         UserGroupInformation.AuthenticationMethod.KERBEROS, conf);*/
     UserGroupInformation.setConfiguration(conf);
     UserGroupInformation authUser = UserGroupInformation.getCurrentUser();
-    log.debug("Authenticating as " + authUser.toString());
+    log.debug("Authenticating as {}", authUser);
     log.debug("Login user is {}", UserGroupInformation.getLoginUser());
     if (!UserGroupInformation.isSecurityEnabled()) {
-      throw new BadConfigException("Although secure mode is enabled," +
-                                   "the application has already set up its user as an insecure entity %s",
+      throw new SliderException(LauncherExitCodes.EXIT_UNAUTHORIZE,
+          "Although secure mode is enabled," +
+         "the application has already set up its user as an insecure entity %s",
           authUser);
     }
     if (authUser.getAuthenticationMethod() ==
         UserGroupInformation.AuthenticationMethod.SIMPLE) {
       throw new BadConfigException("Auth User is not Kerberized %s" +
-                                   " -security has already been set up with the wrong authentication method. "
-                                   +
-                                   "This can occur if a file system has already been created prior to the loading of "
-                                   + "the security configuration.",
+         " -security has already been set up with the wrong authentication method. "
+         + "This can occur if a file system has already been created prior to the loading of "
+         + "the security configuration.",
           authUser);
 
     }
 
     SliderUtils.verifyPrincipalSet(conf, YarnConfiguration.RM_PRINCIPAL);
-    SliderUtils.verifyPrincipalSet(conf,
-        DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY);
+    SliderUtils.verifyPrincipalSet(conf, SliderXmlConfKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY);
     return true;
   }
 
@@ -1354,16 +1351,7 @@
     log.info("Loading all dependencies from {}", srcPath);
     if (SliderUtils.isSet(srcPath)) {
       File srcFolder = new File(srcPath);
-      FilenameFilter jarFilter = new FilenameFilter() {
-        public boolean accept(File dir, String name) {
-          String lowercaseName = name.toLowerCase();
-          if (lowercaseName.endsWith(".jar")) {
-            return true;
-          } else {
-            return false;
-          }
-        }
-      };
+      FilenameFilter jarFilter = createJarFilter();
       File[] listOfJars = srcFolder.listFiles(jarFilter);
       for (File jarFile : listOfJars) {
         LocalResource res = sliderFileSystem.submitFile(jarFile, tempPath, libDir, jarFile.getName());
@@ -1373,6 +1361,18 @@
   }
 
   /**
+   * Accept all filenames ending with {@code .jar}
+   * @return a filename filter
+   */
+  public static FilenameFilter createJarFilter() {
+    return new FilenameFilter() {
+      public boolean accept(File dir, String name) {
+        return name.toLowerCase(Locale.ENGLISH).endsWith(".jar");
+      }
+    };
+  }
+
+  /**
    * Submit the AM tar.gz containing all dependencies and map it
    * @param providerResources provider map to build up
    * @param sliderFileSystem remote fs
@@ -1775,6 +1775,19 @@
     return toTruncate.substring(0, maxSize - pad.length()).concat(pad);
   }
 
+  /**
+   * Get a string node label value from a node report
+   * @param report node report
+   * @return a single trimmed label or ""
+   */
+  public static String extractNodeLabel(NodeReport report) {
+    Set<String> newlabels = report.getNodeLabels();
+    if (newlabels != null && !newlabels.isEmpty()) {
+      return newlabels.iterator().next().trim();
+    } else {
+      return "";
+    }
+  }
 
   /**
    * Callable for async/scheduled halt
@@ -2027,10 +2040,10 @@
       errorText.append("No native IO library. ");
     }
     try {
-      String path = Shell.getQualifiedBinPath("winutils.exe");
+      String path = Shell.getQualifiedBinPath(WINUTILS);
       log.debug("winutils is at {}", path);
     } catch (IOException e) {
-      errorText.append("No WINUTILS.EXE. ");
+      errorText.append("No " + WINUTILS);
       log.warn("No winutils: {}", e, e);
     }
     try {
@@ -2333,6 +2346,7 @@
   public static String getClientConfigPath() {
     URL path = ConfigHelper.class.getClassLoader().getResource(
         SliderKeys.SLIDER_CLIENT_XML);
+    Preconditions.checkNotNull(path, "Failed to locate resource " + SliderKeys.SLIDER_CLIENT_XML);
     return path.toString();
   }
 
@@ -2469,7 +2483,7 @@
    * @return +ve if x is less than y, -ve if y is greater than x; 0 for equality
    */
   public static int compareTwoLongsReverse(long x, long y) {
-    return (x < y) ? +1 : ((x == y) ? 0 : -1);
+    return (x < y) ? 1 : ((x == y) ? 0 : -1);
   }
 
   public static String getSystemEnv(String property) {
@@ -2479,4 +2493,34 @@
   public static Map<String, String> getSystemEnv() {
     return System.getenv();
   }
+
+  public static String requestToString(AMRMClient.ContainerRequest request) {
+    Preconditions.checkArgument(request != null, "Null request");
+    StringBuilder buffer = new StringBuilder(request.toString());
+    buffer.append("; ");
+    buffer.append("relaxLocality=").append(request.getRelaxLocality()).append("; ");
+    String labels = request.getNodeLabelExpression();
+    if (labels != null) {
+      buffer.append("nodeLabels=").append(labels).append("; ");
+    }
+    List<String> nodes = request.getNodes();
+    if (nodes != null) {
+      buffer.append("Nodes = [ ");
+      int size = nodes.size();
+      for (int i = 0; i < Math.min(NODE_LIST_LIMIT, size); i++) {
+        buffer.append(nodes.get(i)).append(' ');
+      }
+      if (size > NODE_LIST_LIMIT) {
+        buffer.append(String.format("...(total %d entries)", size));
+      }
+      buffer.append("]; ");
+    }
+    List<String> racks = request.getRacks();
+    if (racks != null) {
+      buffer.append("racks = [")
+          .append(join(racks, ", ", false))
+          .append("]; ");
+    }
+    return buffer.toString();
+  }
 }
diff --git a/slider-core/src/main/java/org/apache/slider/core/build/InstanceBuilder.java b/slider-core/src/main/java/org/apache/slider/core/build/InstanceBuilder.java
index 0a8dcdb..7756055 100644
--- a/slider-core/src/main/java/org/apache/slider/core/build/InstanceBuilder.java
+++ b/slider-core/src/main/java/org/apache/slider/core/build/InstanceBuilder.java
@@ -23,7 +23,6 @@
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.fs.permission.FsPermission;
-import org.apache.hadoop.hdfs.DFSConfigKeys;
 import org.apache.slider.api.InternalKeys;
 import org.apache.slider.api.OptionKeys;
 import org.apache.slider.api.StatusKeys;
@@ -203,11 +202,10 @@
    * Propagate any critical principals from the current site config down to the HBase one.
    */
   public void propagatePrincipals() {
-    String dfsPrincipal = conf.get(
-        DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY);
+    String dfsPrincipal = conf.get(SliderXmlConfKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY);
     if (dfsPrincipal != null) {
       String siteDfsPrincipal = OptionKeys.SITE_XML_PREFIX +
-                                DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY;
+                                SliderXmlConfKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY;
       instanceDescription.getAppConfOperations().set(siteDfsPrincipal, dfsPrincipal);
     }
   }
diff --git a/slider-core/src/main/java/org/apache/slider/core/conf/ConfTreeOperations.java b/slider-core/src/main/java/org/apache/slider/core/conf/ConfTreeOperations.java
index bc116e7..58896ee 100644
--- a/slider-core/src/main/java/org/apache/slider/core/conf/ConfTreeOperations.java
+++ b/slider-core/src/main/java/org/apache/slider/core/conf/ConfTreeOperations.java
@@ -432,5 +432,14 @@
   public void setComponentOpt(String role, String option, int val) {
     setComponentOpt(role, option, Integer.toString(val));
   }
+  /**
+   * Set a long role option, creating the role if necessary
+   * @param role role name
+   * @param option option name
+   * @param val long value
+   */
+  public void setComponentOpt(String role, String option, long val) {
+    setComponentOpt(role, option, Long.toString(val));
+  }
 
 }
diff --git a/slider-core/src/main/java/org/apache/slider/core/conf/MapOperations.java b/slider-core/src/main/java/org/apache/slider/core/conf/MapOperations.java
index 5f7b5f0..e58178c 100644
--- a/slider-core/src/main/java/org/apache/slider/core/conf/MapOperations.java
+++ b/slider-core/src/main/java/org/apache/slider/core/conf/MapOperations.java
@@ -138,6 +138,21 @@
     String val = getOption(option, Integer.toString(defVal));
     return Integer.decode(val);
   }
+
+  /**
+   * Get a long option; use {@link Long#decode(String)} so as to take hex
+   * oct and bin values too.
+   *
+   * @param option option name
+   * @param defVal default value
+   * @return parsed value
+   * @throws NumberFormatException
+   */
+  public long getOptionLong(String option, long defVal) {
+    String val = getOption(option, Long.toString(defVal));
+    return Long.decode(val);
+  }
+
   /**
    * Get a mandatory integer option; use {@link Integer#decode(String)} so as to take hex
    * oct and bin values too.
diff --git a/slider-core/src/main/java/org/apache/slider/core/launch/AbstractLauncher.java b/slider-core/src/main/java/org/apache/slider/core/launch/AbstractLauncher.java
index 93aff08..22bf328 100644
--- a/slider-core/src/main/java/org/apache/slider/core/launch/AbstractLauncher.java
+++ b/slider-core/src/main/java/org/apache/slider/core/launch/AbstractLauncher.java
@@ -27,6 +27,7 @@
 import org.apache.hadoop.io.DataOutputBuffer;
 import org.apache.hadoop.security.Credentials;
 import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext;
 import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
 import org.apache.hadoop.yarn.api.records.LocalResource;
 import org.apache.hadoop.yarn.api.records.LogAggregationContext;
@@ -279,6 +280,30 @@
     }
   }
 
+  /**
+   * Extract the value for option
+   * yarn.resourcemanager.am.retry-count-window-ms
+   * and set it on the ApplicationSubmissionContext. Use the default value
+   * if option is not set.
+   *
+   * @param submissionContext
+   * @param map
+   */
+  public void extractAmRetryCount(ApplicationSubmissionContext submissionContext,
+                                  Map<String, String> map) {
+
+    if (map != null) {
+      MapOperations options = new MapOperations("", map);
+      long amRetryCountWindow = options.getOptionLong(ResourceKeys
+          .YARN_RESOURCEMANAGER_AM_RETRY_COUNT_WINDOW_MS,
+          ResourceKeys.DEFAULT_AM_RETRY_COUNT_WINDOW_MS);
+      log.info("Setting {} to {}",
+          ResourceKeys.YARN_RESOURCEMANAGER_AM_RETRY_COUNT_WINDOW_MS,
+          amRetryCountWindow);
+      submissionContext.setAttemptFailuresValidityInterval(amRetryCountWindow);
+    }
+  }
+
   public void extractLogAggregationContext(Map<String, String> map) {
     if (map != null) {
       String logPatternSepStr = "\\|";
@@ -423,7 +448,7 @@
   }
 
   /**
-   * Suubmit an entire directory
+   * Submit an entire directory
    * @param srcDir src path in filesystem
    * @param destRelativeDir relative path under destination local dir
    * @throws IOException IO problems
diff --git a/slider-core/src/main/java/org/apache/slider/core/launch/AppMasterLauncher.java b/slider-core/src/main/java/org/apache/slider/core/launch/AppMasterLauncher.java
index b4ca791..c82affa 100644
--- a/slider-core/src/main/java/org/apache/slider/core/launch/AppMasterLauncher.java
+++ b/slider-core/src/main/java/org/apache/slider/core/launch/AppMasterLauncher.java
@@ -106,6 +106,8 @@
       submissionContext.setApplicationTags(applicationTags);
     }
     submissionContext.setNodeLabelExpression(extractLabelExpression(options));
+
+    extractAmRetryCount(submissionContext, resourceGlobalOptions);
     extractResourceRequirements(resource, options);
     extractLogAggregationContext(resourceGlobalOptions);
   }
@@ -220,8 +222,7 @@
     }
 
     Token<? extends TokenIdentifier>[] tokens = null;
-    boolean tokensProvided =
-        this.getConf().get(MAPREDUCE_JOB_CREDENTIALS_BINARY) != null;
+    boolean tokensProvided = getConf().get(MAPREDUCE_JOB_CREDENTIALS_BINARY) != null;
     if (!tokensProvided) {
         // For now, only getting tokens for the default file-system.
         FileSystem fs = coreFileSystem.getFileSystem();
@@ -232,7 +233,7 @@
     if (tokens != null && tokens.length > 0) {
       AbstractDelegationTokenIdentifier id =
         (AbstractDelegationTokenIdentifier)tokens[0].decodeIdentifier();
-      Date d = new Date(id.getIssueDate() + 24*60*60*1000);
+      Date d = new Date(id.getIssueDate() + 24 * 60 * 60 * 1000);
       log.info("HDFS delegation tokens for AM launch context require renewal by {}",
                DateFormat.getDateTimeInstance().format(d));
     } else {
diff --git a/slider-core/src/main/java/org/apache/slider/core/launch/ClasspathConstructor.java b/slider-core/src/main/java/org/apache/slider/core/launch/ClasspathConstructor.java
index 3ba0181..6eb4058 100644
--- a/slider-core/src/main/java/org/apache/slider/core/launch/ClasspathConstructor.java
+++ b/slider-core/src/main/java/org/apache/slider/core/launch/ClasspathConstructor.java
@@ -38,7 +38,6 @@
 public class ClasspathConstructor {
 
     public static final String CLASS_PATH_SEPARATOR = ApplicationConstants.CLASS_PATH_SEPARATOR;
-//  public static final String CLASS_PATH_SEPARATOR = File.pathSeparator;
   private final List<String> pathElements = new ArrayList<>();
 
   public ClasspathConstructor() {
diff --git a/slider-core/src/main/java/org/apache/slider/core/launch/ContainerLauncher.java b/slider-core/src/main/java/org/apache/slider/core/launch/ContainerLauncher.java
index f8ea4ee..69b937d 100644
--- a/slider-core/src/main/java/org/apache/slider/core/launch/ContainerLauncher.java
+++ b/slider-core/src/main/java/org/apache/slider/core/launch/ContainerLauncher.java
@@ -55,17 +55,13 @@
   public UserGroupInformation setupUGI() {
     UserGroupInformation user =
       UserGroupInformation.createRemoteUser(container.getId().toString());
-    String cmIpPortStr =
-      container.getNodeId().getHost() + ":" + container.getNodeId().getPort();
-    final InetSocketAddress cmAddress =
-      NetUtils.createSocketAddr(cmIpPortStr);
+    String cmIpPortStr = container.getNodeId().getHost() + ":" + container.getNodeId().getPort();
+    final InetSocketAddress cmAddress = NetUtils.createSocketAddr(cmIpPortStr);
 
-    org.apache.hadoop.yarn.api.records.Token containerToken =
-      container.getContainerToken();
+    org.apache.hadoop.yarn.api.records.Token containerToken = container.getContainerToken();
     if (containerToken != null) {
       Token<ContainerTokenIdentifier> token =
-        ConverterUtils.convertFromYarn(containerToken,
-                                       cmAddress);
+        ConverterUtils.convertFromYarn(containerToken, cmAddress);
       user.addToken(token);
     }
     return user;
diff --git a/slider-core/src/main/java/org/apache/slider/core/launch/JavaCommandLineBuilder.java b/slider-core/src/main/java/org/apache/slider/core/launch/JavaCommandLineBuilder.java
index 0b3fa10..dcb322e 100644
--- a/slider-core/src/main/java/org/apache/slider/core/launch/JavaCommandLineBuilder.java
+++ b/slider-core/src/main/java/org/apache/slider/core/launch/JavaCommandLineBuilder.java
@@ -20,11 +20,15 @@
 
 
 import com.google.common.base.Preconditions;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.yarn.api.ApplicationConstants;
 import org.apache.slider.common.tools.SliderUtils;
+import org.apache.slider.core.exceptions.BadConfigException;
 
 /**
- * Command line builder purely for the Java CLI
+ * Command line builder purely for the Java CLI.
+ * Some of the <code>define</code> methods are designed to work with Hadoop tool and
+ * Slider launcher applications.
  */
 public class JavaCommandLineBuilder extends CommandLineBuilder {
 
@@ -80,4 +84,68 @@
     sysprop("java.awt.headless", "true");
     return this;
   }
+
+  public boolean addConfOption(Configuration conf, String key) {
+    return defineIfSet(key, conf.get(key));
+  }
+
+  /**
+   * Add a varargs list of configuration parameters —if they are present
+   * @param conf configuration source
+   * @param keys keys
+   */
+  public void addConfOptions(Configuration conf, String...keys) {
+    for (String key : keys) {
+      addConfOption(conf, key);
+    }
+  }
+
+  public String addConfOptionToCLI(Configuration conf,
+      String key,
+      String defVal) {
+    String val = conf.get(key, defVal);
+    define(key, val);
+    return val;
+  }
+
+  /**
+   * Add a <code>-D key=val</code> command to the CLI. This is very Hadoop API
+   * @param key key
+   * @param val value
+   */
+  public void define(String key, String val) {
+    Preconditions.checkArgument(key != null, "null key");
+    Preconditions.checkArgument(val != null, "null value");
+    add("-D", key + "=" + val);
+  }
+
+  /**
+   * Add a <code>-D key=val</code> command to the CLI if <code>val</code>
+   * is not null
+   * @param key key
+   * @param val value
+   */
+  public boolean defineIfSet(String key, String val) {
+    Preconditions.checkArgument(key != null, "null key");
+    if (val != null) {
+      define(key, val);
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * Add a mandatory config option
+   * @param conf configuration
+   * @param key key
+   * @throws BadConfigException if the key is missing
+   */
+  public void addMandatoryConfOption(Configuration conf,
+      String key) throws BadConfigException {
+    if (!addConfOption(conf, key)) {
+      throw new BadConfigException("Missing configuration option: " + key);
+    }
+  }
+
 }
diff --git a/slider-core/src/main/java/org/apache/slider/core/persist/ConfPersister.java b/slider-core/src/main/java/org/apache/slider/core/persist/ConfPersister.java
index 60717f6..9759205 100644
--- a/slider-core/src/main/java/org/apache/slider/core/persist/ConfPersister.java
+++ b/slider-core/src/main/java/org/apache/slider/core/persist/ConfPersister.java
@@ -101,7 +101,7 @@
    * Make the persistent directory
    * @throws IOException IO failure
    */
-  private void mkPersistDir() throws IOException {
+  public void mkPersistDir() throws IOException {
     coreFS.getFileSystem().mkdirs(persistDir);
   }
   
@@ -165,13 +165,15 @@
    * Acquire the writelock
    * @throws IOException IO
    * @throws LockAcquireFailedException
-   * @throws FileNotFoundException if the target dir does not exist
+   * @throws FileNotFoundException if the target dir does not exist.
    */
   @VisibleForTesting
   boolean acquireReadLock() throws FileNotFoundException,
                                   IOException,
                                   LockAcquireFailedException {
     if (!coreFS.getFileSystem().exists(persistDir)) {
+      // the dir is not there, so the data is not there, so there
+      // is nothing to read
       throw new FileNotFoundException(persistDir.toString());
     }
     long now = System.currentTimeMillis();
diff --git a/slider-core/src/main/java/org/apache/slider/core/persist/JsonSerDeser.java b/slider-core/src/main/java/org/apache/slider/core/persist/JsonSerDeser.java
index c5908bb..4f60c06 100644
--- a/slider-core/src/main/java/org/apache/slider/core/persist/JsonSerDeser.java
+++ b/slider-core/src/main/java/org/apache/slider/core/persist/JsonSerDeser.java
@@ -91,10 +91,11 @@
    */
   public T fromFile(File jsonFile)
     throws IOException, JsonParseException, JsonMappingException {
+    File absoluteFile = jsonFile.getAbsoluteFile();
     try {
-      return mapper.readValue(jsonFile, classType);
+      return mapper.readValue(absoluteFile, classType);
     } catch (IOException e) {
-      log.error("Exception while parsing json file {}: {}", jsonFile, e);
+      log.error("Exception while parsing json file {}", absoluteFile, e);
       throw e;
     }
   }
@@ -106,7 +107,6 @@
    * @throws IOException IO problems
    * @throws JsonMappingException failure to map from the JSON to this class
    */
-/* JDK7
  public T fromResource(String resource)
     throws IOException, JsonParseException, JsonMappingException {
     try(InputStream resStream = this.getClass().getResourceAsStream(resource)) {
@@ -115,34 +115,9 @@
       }
       return (T) (mapper.readValue(resStream, classType));
     } catch (IOException e) {
-      log.error("Exception while parsing json resource {}: {}", resource, e);
+      log.error("Exception while parsing json resource {}", resource, e);
       throw e;
     }
-  }*/
-
-  /**
-   * Convert from a JSON file
-   * @param resource input file
-   * @return the parsed JSON
-   * @throws IOException IO problems
-   * @throws JsonMappingException failure to map from the JSON to this class
-   */
-  @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
-  public synchronized T fromResource(String resource)
-      throws IOException, JsonParseException, JsonMappingException {
-    InputStream resStream = null;
-    try {
-      resStream = this.getClass().getResourceAsStream(resource);
-      if (resStream == null) {
-        throw new FileNotFoundException(resource);
-      }
-      return (T) (mapper.readValue(resStream, classType));
-    } catch (IOException e) {
-      log.error("Exception while parsing json resource {}: {}", resource, e);
-      throw e;
-    } finally {
-      IOUtils.closeStream(resStream);
-    }
   }
 
   /**
@@ -155,7 +130,7 @@
     try {
       return (T) (mapper.readValue(stream, classType));
     } catch (IOException e) {
-      log.error("Exception while parsing json input stream: {}", e);
+      log.error("Exception while parsing json input stream", e);
       throw e;
     } finally {
       IOUtils.closeStream(stream);
@@ -201,7 +176,7 @@
     FSDataInputStream dataInputStream = fs.open(path);
     int count = dataInputStream.read(b);
     if (count != len) {
-      throw new EOFException("Read finished prematurely");
+      throw new EOFException("Read of " + path +" finished prematurely");
     }
     return fromBytes(b);
   }
@@ -230,9 +205,9 @@
    */
   public void save(T instance, File file) throws
       IOException {
-    writeJsonAsBytes(instance, new FileOutputStream(file));
+    writeJsonAsBytes(instance, new FileOutputStream(file.getAbsoluteFile()));
   }
-  
+
   /**
    * Write the json as bytes -then close the file
    * @param dataOutputStream an outout stream that will always be closed
@@ -251,7 +226,6 @@
     }
   }
 
-
   /**
    * Convert an object to a JSON string
    * @param instance instance to convert
@@ -265,6 +239,5 @@
     mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
     return mapper.writeValueAsString(instance);
   }
-  
-  
+
 }
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfigSet.java b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfigSet.java
index eac34c0..edc129e 100644
--- a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfigSet.java
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfigSet.java
@@ -41,7 +41,7 @@
       RestPaths.PUBLISHED_CONFIGURATION_REGEXP);
   
   public Map<String, PublishedConfiguration> configurations =
-      new HashMap<String, PublishedConfiguration>();
+      new HashMap<>();
 
   public PublishedConfigSet() {
   }
@@ -84,7 +84,7 @@
   }
   
   public Set<String> keys() {
-    TreeSet<String> keys = new TreeSet<String>();
+    TreeSet<String> keys = new TreeSet<>();
     keys.addAll(configurations.keySet());
     return keys;
   }
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfiguration.java b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfiguration.java
index e453fb1..50b522f 100644
--- a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfiguration.java
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedConfiguration.java
@@ -47,7 +47,7 @@
   
   public String updatedTime;
 
-  public Map<String, String> entries = new HashMap<String, String>();
+  public Map<String, String> entries = new HashMap<>();
 
   public PublishedConfiguration() {
   }
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedExports.java b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedExports.java
index bf96e8c..0759b4e 100644
--- a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedExports.java
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedExports.java
@@ -41,7 +41,7 @@
   public String description;
   public long updated;
   public String updatedTime;
-  public Map<String, List<ExportEntry>> entries = new HashMap<String, List<ExportEntry>>();
+  public Map<String, List<ExportEntry>> entries = new HashMap<>();
 
   public PublishedExports() {
   }
@@ -68,7 +68,8 @@
   }
 
   /**
-   * Is the configuration empty. This means either that it has not been given any values, or it is stripped down copy
+   * Is the configuration empty. This means either that it has not been given any values,
+   * or it is stripped down copy
    * set down over the wire.
    *
    * @return true if it is empty
@@ -87,8 +88,8 @@
   }
 
   /**
-   * Set the values from an iterable (this includes a Hadoop Configuration and Java properties object). Any existing
-   * value set is discarded
+   * Set the values from an iterable (this includes a Hadoop Configuration and Java properties
+   * object). Any existing value set is discarded
    *
    * @param entries entries to put
    */
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedExportsSet.java b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedExportsSet.java
index cdd35de..339d3d6 100644
--- a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedExportsSet.java
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/PublishedExportsSet.java
@@ -40,8 +40,7 @@
   private static final PatternValidator validator = new PatternValidator(
       RestPaths.PUBLISHED_CONFIGURATION_REGEXP);
   
-  public Map<String, PublishedExports> exports =
-      new HashMap<String, PublishedExports>();
+  public Map<String, PublishedExports> exports = new HashMap<>();
 
   public PublishedExportsSet() {
   }
@@ -84,15 +83,14 @@
   }
   
   public Set<String> keys() {
-    TreeSet<String> keys = new TreeSet<String>();
+    TreeSet<String> keys = new TreeSet<>();
     keys.addAll(exports.keySet());
     return keys;
   }
 
   public PublishedExportsSet shallowCopy() {
     PublishedExportsSet that = new PublishedExportsSet();
-    for (Map.Entry<String, PublishedExports> entry :
-        exports.entrySet()) {
+    for (Map.Entry<String, PublishedExports> entry : exports.entrySet()) {
       that.put(entry.getKey(), entry.getValue().shallowCopy());
     }
     return that;
diff --git a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/UriMap.java b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/UriMap.java
index a76e28d..120966f 100644
--- a/slider-core/src/main/java/org/apache/slider/core/registry/docstore/UriMap.java
+++ b/slider-core/src/main/java/org/apache/slider/core/registry/docstore/UriMap.java
@@ -29,7 +29,7 @@
 @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
 public class UriMap {
 
-  public Map<String, String> uris = new HashMap<String, String>();
+  public Map<String, String> uris = new HashMap<>();
   
   @JsonIgnore
   public void put(String key, String value) {
diff --git a/slider-core/src/main/java/org/apache/slider/core/zk/ZKIntegration.java b/slider-core/src/main/java/org/apache/slider/core/zk/ZKIntegration.java
index 9a9cae4..ca41e4b 100644
--- a/slider-core/src/main/java/org/apache/slider/core/zk/ZKIntegration.java
+++ b/slider-core/src/main/java/org/apache/slider/core/zk/ZKIntegration.java
@@ -57,7 +57,7 @@
     ZK_USERS_PATH_LIST.add(ZK_USERS);
   }
 
-  public static int SESSION_TIMEOUT = 5000;
+  public static int SESSION_TIMEOUT = 30000;
   protected static final Logger log =
     LoggerFactory.getLogger(ZKIntegration.class);
   private ZooKeeper zookeeper;
@@ -80,7 +80,8 @@
                           String clustername,
                           boolean canBeReadOnly,
                           boolean createClusterPath,
-                          Watcher watchEventHandler
+                          Watcher watchEventHandler,
+                          int sessionTimeout
   ) throws IOException {
     this.username = username;
     this.clustername = clustername;
@@ -88,6 +89,7 @@
     this.zkConnection = zkConnection;
     this.canBeReadOnly = canBeReadOnly;
     this.createClusterPath = createClusterPath;
+    this.sessionTimeout = sessionTimeout;
     this.userPath = mkSliderUserPath(username);
   }
 
@@ -107,14 +109,21 @@
    * @return the new instance
    * @throws IOException
    */
-  public static ZKIntegration newInstance(String zkConnection, String username, String clustername, boolean createClusterPath, boolean canBeReadOnly, Watcher watchEventHandler) throws IOException {
+  public static ZKIntegration newInstance(String zkConnection,
+      String username,
+      String clustername,
+      boolean createClusterPath,
+      boolean canBeReadOnly,
+      Watcher watchEventHandler,
+      int sessionTimeout) throws IOException {
 
     return new ZKIntegration(zkConnection,
                              username,
                              clustername,
                              canBeReadOnly,
                              createClusterPath,
-                             watchEventHandler);
+                             watchEventHandler,
+                             sessionTimeout);
   }
 
 
diff --git a/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java b/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
index 7cba840..c701a55 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
@@ -81,7 +81,7 @@
   protected YarnRegistryViewForProviders yarnRegistry;
   protected QueueAccess queueAccess;
 
-  public AbstractProviderService(String name) {
+  protected AbstractProviderService(String name) {
     super(name);
     setStopIfNoChildServicesAtStartup(false);
   }
@@ -343,12 +343,6 @@
 
     return details;
   }
-  
-  protected String getInfoAvoidingNull(ClusterDescription clusterDesc, String key) {
-    String value = clusterDesc.getInfo(key);
-
-    return null == value ? "N/A" : value;
-  }
 
   @Override
   public void buildEndpointDetails(Map<String, String> details) {
@@ -363,10 +357,8 @@
           if (!urls.isEmpty()) {
             details.put(endpoint.api, urls.get(0).toString());
           }
-        } catch (InvalidRecordException ignored) {
+        } catch (InvalidRecordException  | MalformedURLException ignored) {
           // Ignored
-        } catch (MalformedURLException ignored) {
-          // ignored
         }
 
       }
diff --git a/slider-core/src/main/java/org/apache/slider/providers/PlacementPolicy.java b/slider-core/src/main/java/org/apache/slider/providers/PlacementPolicy.java
index 4e85a93..71d7566 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/PlacementPolicy.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/PlacementPolicy.java
@@ -27,7 +27,12 @@
   /**
    * Default value: history used, anti-affinity hinted at on rebuild/flex up
    */
-  public static final int DEFAULT = 0;
+  public static final int NONE = 0;
+
+  /**
+   * Default value: history used, anti-affinity hinted at on rebuild/flex up
+   */
+  public static final int DEFAULT = NONE;
 
   /**
    * Strict placement: when asking for an instance for which there is
@@ -41,7 +46,7 @@
   public static final int NO_DATA_LOCALITY = 2;
 
   /**
-   * Anti-affinity is mandatory. This is not supported in YARN
+   * Anti-affinity is mandatory.
    */
   public static final int ANTI_AFFINITY_REQUIRED = 4;
   
diff --git a/slider-core/src/main/java/org/apache/slider/providers/ProviderRole.java b/slider-core/src/main/java/org/apache/slider/providers/ProviderRole.java
index 3009f50..1b95b42 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/ProviderRole.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/ProviderRole.java
@@ -32,13 +32,15 @@
   public int placementPolicy;
   public int nodeFailureThreshold;
   public final long placementTimeoutSeconds;
+  public final String labelExpression;
 
   public ProviderRole(String name, int id) {
     this(name,
         id,
         PlacementPolicy.DEFAULT,
         ResourceKeys.DEFAULT_NODE_FAILURE_THRESHOLD,
-        ResourceKeys.DEFAULT_PLACEMENT_ESCALATE_DELAY_SECONDS);
+        ResourceKeys.DEFAULT_PLACEMENT_ESCALATE_DELAY_SECONDS,
+        ResourceKeys.DEF_YARN_LABEL_EXPRESSION);
   }
 
   /**
@@ -49,18 +51,20 @@
    * @param nodeFailureThreshold threshold for node failures (within a reset interval)
    * after which a node failure is considered an app failure
    * @param placementTimeoutSeconds for lax placement, timeout in seconds before
-   * a relaxed placement request is generated.
+   * @param labelExpression label expression for requests; may be null
    */
   public ProviderRole(String name,
       int id,
       int policy,
       int nodeFailureThreshold,
-      long placementTimeoutSeconds) {
+      long placementTimeoutSeconds,
+      String labelExpression) {
     this.name = name;
     this.id = id;
     this.placementPolicy = policy;
     this.nodeFailureThreshold = nodeFailureThreshold;
     this.placementTimeoutSeconds = placementTimeoutSeconds;
+    this.labelExpression = labelExpression;
   }
 
   @Override
@@ -83,11 +87,14 @@
 
   @Override
   public String toString() {
-    return "ProviderRole {" +
-           "name='" + name + '\'' +
-           ", id=" + id +
-           ", policy=" + placementPolicy +
-           ", nodeFailureThreshold=" + nodeFailureThreshold +
-           '}';
+    final StringBuilder sb = new StringBuilder("ProviderRole{");
+    sb.append("name='").append(name).append('\'');
+    sb.append(", id=").append(id);
+    sb.append(", placementPolicy=").append(placementPolicy);
+    sb.append(", nodeFailureThreshold=").append(nodeFailureThreshold);
+    sb.append(", placementTimeoutSeconds=").append(placementTimeoutSeconds);
+    sb.append(", labelExpression='").append(labelExpression).append('\'');
+    sb.append('}');
+    return sb.toString();
   }
 }
diff --git a/slider-core/src/main/java/org/apache/slider/providers/agent/application/metadata/Application.java b/slider-core/src/main/java/org/apache/slider/providers/agent/application/metadata/Application.java
index 5967a3a..3a445f4 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/agent/application/metadata/Application.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/agent/application/metadata/Application.java
@@ -16,10 +16,10 @@
  */
 package org.apache.slider.providers.agent.application.metadata;
 
-import com.fasterxml.jackson.annotation.JsonIgnore;
 import org.apache.slider.common.tools.SliderUtils;
 import org.apache.slider.core.exceptions.BadCommandArgumentsException;
 import org.apache.slider.core.exceptions.SliderException;
+import org.codehaus.jackson.annotate.JsonIgnore;
 import org.codehaus.jackson.annotate.JsonProperty;
 
 import java.util.ArrayList;
diff --git a/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMClientProvider.java b/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMClientProvider.java
index e1dc4f9..e5430f2 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMClientProvider.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMClientProvider.java
@@ -90,7 +90,7 @@
       new ProviderRole(COMPONENT_AM, KEY_AM,
           PlacementPolicy.EXCLUDE_FROM_FLEXING,
           ResourceKeys.DEFAULT_NODE_FAILURE_THRESHOLD, 
-          0);
+          0, "");
 
   /**
    * Initialize role list
@@ -174,8 +174,7 @@
       Path tempPath, boolean miniClusterTestRun)
     throws IOException, SliderException {
 
-    Map<String, LocalResource> providerResources =
-        new HashMap<String, LocalResource>();
+    Map<String, LocalResource> providerResources = new HashMap<>();
 
     ProviderUtils.addProviderJar(providerResources,
         this,
@@ -219,11 +218,12 @@
    * @param instanceDescription
    * @param providerResources
    * @throws IOException
+   * @throws BadConfigException if there's no keytab and it is explicitly required.
    */
   protected void addKeytabResourceIfNecessary(SliderFileSystem fileSystem,
                                               AggregateConf instanceDescription,
                                               Map<String, LocalResource> providerResources)
-      throws IOException {
+    throws IOException, BadConfigException {
     if (UserGroupInformation.isSecurityEnabled()) {
       String keytabPathOnHost = instanceDescription.getAppConfOperations()
           .getComponent(SliderKeys.COMPONENT_AM).get(
@@ -244,10 +244,16 @@
           providerResources.put(SliderKeys.KEYTAB_DIR + "/" +
                                  amKeytabName, keytabRes);
         } else {
-          log.warn("No keytab file was found at {}.  The AM will be "
-                   + "started without a kerberos authenticated identity. "
-                   + "The application is therefore not guaranteed to remain "
-                   + "operational beyond 24 hours.", keytabPath);
+          log.warn("No keytab file was found at {}.", keytabPath);
+          if (getConf().getBoolean(KEY_AM_LOGIN_KEYTAB_REQUIRED, false)) {
+            throw new BadConfigException("No keytab file was found at %s.", keytabPath);
+
+          } else {
+            log.warn("The AM will be "
+              + "started without a kerberos authenticated identity. "
+              + "The application is therefore not guaranteed to remain "
+              + "operational beyond 24 hours.");
+          }
         }
       }
     }
diff --git a/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java b/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
index cee7a97..e382058 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
@@ -88,12 +88,11 @@
       MapOperations resourceComponent,
       MapOperations appComponent,
       Path containerTmpDirPath) throws IOException, SliderException {
-    
   }
 
   @Override
   public List<ProviderRole> getRoles() {
-    return new ArrayList<ProviderRole>(0);
+    return new ArrayList<>(0);
   }
 
   @Override
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/AMUtils.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/AMUtils.java
deleted file mode 100644
index 32684c6..0000000
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/AMUtils.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.slider.server.appmaster;
-
-import org.apache.slider.common.SliderExitCodes;
-import org.apache.slider.core.main.LauncherExitCodes;
-
-public class AMUtils {
-  /**
-   * Map an exit code from a process 
-   * @param exitCode
-   * @return an exit code
-   */
-  public static int mapProcessExitCodeToYarnExitCode(int exitCode) {
-    switch (exitCode) {
-      case LauncherExitCodes.EXIT_SUCCESS:
-        return LauncherExitCodes.EXIT_SUCCESS;
-      //remap from a planned shutdown to a failure
-      case LauncherExitCodes.EXIT_CLIENT_INITIATED_SHUTDOWN:
-        return SliderExitCodes.EXIT_SUCCESS;
-      default:
-        return exitCode;
-    }
-  }
-
-  public static boolean isMappedExitAFailure(int mappedExitCode) {
-    return mappedExitCode != 0;
-  }
-
-}
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/AppMasterActionOperations.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/AppMasterActionOperations.java
index d78b718..288f25a 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/AppMasterActionOperations.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/AppMasterActionOperations.java
@@ -18,11 +18,8 @@
 
 package org.apache.slider.server.appmaster;
 
-import org.apache.slider.server.appmaster.operations.AbstractRMOperation;
 import org.apache.slider.server.appmaster.operations.RMOperationHandlerActions;
 
-import java.util.List;
-
 /**
  * Interface of AM operations
  */
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/ProtobufRecordFactory.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/ProtobufClusterServices.java
similarity index 75%
rename from slider-core/src/main/java/org/apache/slider/server/appmaster/ProtobufRecordFactory.java
rename to slider-core/src/main/java/org/apache/slider/server/appmaster/ProtobufClusterServices.java
index d7f79f1..5d52441 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/ProtobufRecordFactory.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/ProtobufClusterServices.java
@@ -20,10 +20,17 @@
 
 import org.apache.hadoop.yarn.api.records.Resource;
 import org.apache.hadoop.yarn.util.Records;
-import org.apache.slider.server.appmaster.state.AbstractRecordFactory;
+import org.apache.hadoop.yarn.util.resource.Resources;
+import org.apache.slider.server.appmaster.state.AbstractClusterServices;
 
-public class ProtobufRecordFactory extends AbstractRecordFactory {
+public class ProtobufClusterServices extends AbstractClusterServices {
+
   public Resource newResource() {
     return Records.newRecord(Resource.class);
   }
+
+  @Override
+  public Resource newResource(int memory, int cores) {
+    return Resources.createResource(memory, cores);
+  }
 }
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
index 45e2ff9..18d5bfa 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
@@ -20,6 +20,9 @@
 
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.health.HealthCheckRegistry;
+import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
+import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
+import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
 import com.google.common.base.Preconditions;
 import com.google.protobuf.BlockingService;
 
@@ -29,7 +32,6 @@
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.fs.permission.FsAction;
 import org.apache.hadoop.fs.permission.FsPermission;
-import org.apache.hadoop.hdfs.DFSConfigKeys;
 import org.apache.hadoop.hdfs.HdfsConfiguration;
 import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
 import org.apache.hadoop.http.HttpConfig;
@@ -55,6 +57,7 @@
 import org.apache.hadoop.yarn.api.records.ContainerStatus;
 import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
 import org.apache.hadoop.yarn.api.records.NodeReport;
+import org.apache.hadoop.yarn.api.records.NodeState;
 import org.apache.hadoop.yarn.api.records.Priority;
 import org.apache.hadoop.yarn.api.records.Resource;
 import org.apache.hadoop.yarn.client.api.AMRMClient;
@@ -62,6 +65,7 @@
 import org.apache.hadoop.yarn.client.api.async.NMClientAsync;
 import org.apache.hadoop.yarn.client.api.async.impl.NMClientAsyncImpl;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import static org.apache.hadoop.yarn.conf.YarnConfiguration.*;
 import org.apache.hadoop.yarn.exceptions.InvalidApplicationMasterRequestException;
 import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.hadoop.yarn.ipc.YarnRPC;
@@ -82,6 +86,7 @@
 import org.apache.slider.api.RoleKeys;
 import org.apache.slider.api.StatusKeys;
 import org.apache.slider.api.proto.SliderClusterAPI;
+import org.apache.slider.client.SliderYarnClientImpl;
 import org.apache.slider.common.SliderExitCodes;
 import org.apache.slider.common.SliderKeys;
 import org.apache.slider.common.params.AbstractActionArgs;
@@ -141,6 +146,7 @@
 import org.apache.slider.server.appmaster.rpc.SliderIPCService;
 import org.apache.slider.server.appmaster.security.SecurityConfiguration;
 import org.apache.slider.server.appmaster.state.AppState;
+import org.apache.slider.server.appmaster.state.AppStateBindingInfo;
 import org.apache.slider.server.appmaster.state.ContainerAssignment;
 import org.apache.slider.server.appmaster.state.ProviderAppState;
 import org.apache.slider.server.appmaster.operations.RMOperationHandler;
@@ -166,6 +172,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.net.BindException;
 import java.net.InetSocketAddress;
 import java.net.URI;
 import java.net.URL;
@@ -208,8 +215,7 @@
    */
   protected static final Logger LOG_YARN = log;
 
-  public static final String SERVICE_CLASSNAME_SHORT =
-      "SliderAppMaster";
+  public static final String SERVICE_CLASSNAME_SHORT = "SliderAppMaster";
   public static final String SERVICE_CLASSNAME =
       "org.apache.slider.server.appmaster." + SERVICE_CLASSNAME_SHORT;
 
@@ -221,10 +227,13 @@
    * Deployed in {@link #serviceInit(Configuration)}
    */
   private final MetricsAndMonitoring metricsAndMonitoring = new MetricsAndMonitoring(); 
+
   /**
    * metrics registry
    */
   public MetricRegistry metrics;
+
+  /** Error string on chaos monkey launch failure action: {@value} */
   public static final String E_TRIGGERED_LAUNCH_FAILURE =
       "Chaos monkey triggered launch failure";
 
@@ -244,7 +253,6 @@
   @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
   public NMClientAsync nmClientAsync;
 
-//  YarnConfiguration conf;
   /**
    * token blob
    */
@@ -291,7 +299,7 @@
    * live on, etc.
    */
   private final AppState appState =
-      new AppState(new ProtobufRecordFactory(), metricsAndMonitoring);
+      new AppState(new ProtobufClusterServices(), metricsAndMonitoring);
 
   /**
    * App state for external objects. This is almost entirely
@@ -301,7 +309,6 @@
   private final ProviderAppState stateForProviders =
       new ProviderAppState("undefined", appState);
 
-
   /**
    * model the state using locks and conditions
    */
@@ -353,16 +360,6 @@
   private RegistryOperations registryOperations;
 
   /**
-   * Record of the max no. of cores allowed in this cluster
-   */
-  private int containerMaxCores;
-
-  /**
-   * limit container memory
-   */
-  private int containerMaxMemory;
-
-  /**
    * The stop request received...the exit details are extracted
    * from this
    */
@@ -412,6 +409,12 @@
    */
   private boolean securityEnabled;
   private ContentCache contentCache;
+  private SliderYarnClientImpl yarnClient;
+
+  /**
+   * resource limits
+   */
+  private Resource maximumResourceCapability;
 
   /**
    * Service Constructor
@@ -434,10 +437,8 @@
     // Load in the server configuration - if it is actually on the Classpath
     URL serverXmlUrl = ConfigHelper.getResourceUrl(SLIDER_SERVER_XML);
     if (serverXmlUrl != null) {
-
       log.info("Loading {} at {}", SLIDER_SERVER_XML, serverXmlUrl);
-      Configuration serverConf =
-          ConfigHelper.loadFromResource(SLIDER_SERVER_XML);
+      Configuration serverConf = ConfigHelper.loadFromResource(SLIDER_SERVER_XML);
       ConfigHelper.mergeConfigurations(customConf, serverConf,
           SLIDER_SERVER_XML, true);
     }
@@ -469,8 +470,7 @@
       UserGroupInformation.setConfiguration(conf);
       UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
       log.debug("Authenticating as {}", ugi);
-      SliderUtils.verifyPrincipalSet(conf,
-          DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY);
+      SliderUtils.verifyPrincipalSet(conf, DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY);
     } else {
       log.info("Cluster is insecure");
     }
@@ -485,22 +485,24 @@
             false);
     SliderUtils.validateSliderServerEnvironment(log, dependencyChecks);
 
-    // create app state and monitoring
+    // create and register monitoring services
     addService(metricsAndMonitoring);
     metrics = metricsAndMonitoring.getMetrics();
+/* TODO: turn these one once the metrics testing is more under control
+    metrics.registerAll(new ThreadStatesGaugeSet());
+    metrics.registerAll(new MemoryUsageGaugeSet());
+    metrics.registerAll(new GarbageCollectorMetricSet());
 
+*/
+    contentCache = ApplicationResouceContentCacheFactory.createContentCache(stateForProviders);
 
-    contentCache = ApplicationResouceContentCacheFactory.createContentCache(
-        stateForProviders);
-
-
-    executorService = new WorkflowExecutorService<ExecutorService>("AmExecutor",
+    executorService = new WorkflowExecutorService<>("AmExecutor",
         Executors.newFixedThreadPool(2,
             new ServiceThreadFactory("AmExecutor", true)));
     addService(executorService);
 
     addService(actionQueues);
-    
+
     //init all child services
     super.serviceInit(conf);
   }
@@ -531,8 +533,7 @@
    * @param args argument list
    */
   @Override // RunService
-  public Configuration bindArgs(Configuration config, String... args) throws
-                                                                      Exception {
+  public Configuration bindArgs(Configuration config, String... args) throws Exception {
     // let the superclass process it
     Configuration superConf = super.bindArgs(config, args);
     // add the slider XML config
@@ -559,19 +560,17 @@
 
     //dump the system properties if in debug mode
     if (log.isDebugEnabled()) {
-      log.debug("System properties:\n" +
-                SliderUtils.propertiesToString(System.getProperties()));
+      log.debug("System properties:\n" + SliderUtils.propertiesToString(System.getProperties()));
     }
 
     //choose the action
     String action = serviceArgs.getAction();
     List<String> actionArgs = serviceArgs.getActionArgs();
     int exitCode;
-/*  JDK7
-  switch (action) {
+    switch (action) {
       case SliderActions.ACTION_HELP:
-        log.info(getName() + serviceArgs.usage());
-        exitCode = LauncherExitCodes.EXIT_USAGE;
+        log.info("{}: {}", getName(), serviceArgs.usage());
+        exitCode = SliderExitCodes.EXIT_USAGE;
         break;
       case SliderActions.ACTION_CREATE:
         exitCode = createAndRunCluster(actionArgs.get(0));
@@ -579,20 +578,10 @@
       default:
         throw new SliderException("Unimplemented: " + action);
     }
-    */
-    if (action.equals(SliderActions.ACTION_HELP)) {
-      log.info("{}: {}", getName(), serviceArgs.usage());
-      exitCode = SliderExitCodes.EXIT_USAGE;
-    } else if (action.equals(SliderActions.ACTION_CREATE)) {
-      exitCode = createAndRunCluster(actionArgs.get(0));
-    } else {
-      throw new SliderException("Unimplemented: " + action);
-    }
     log.info("Exiting AM; final exit code = {}", exitCode);
     return exitCode;
   }
 
-
   /**
    * Initialize a newly created service then add it. 
    * Because the service is not started, this MUST be done before
@@ -636,13 +625,11 @@
 
     Configuration serviceConf = getConfig();
 
-    securityConfiguration = new SecurityConfiguration(
-        serviceConf, instanceDefinition, clustername);
+    securityConfiguration = new SecurityConfiguration(serviceConf, instanceDefinition, clustername);
     // obtain security state
     securityEnabled = securityConfiguration.isSecurityEnabled();
     // set the global security flag for the instance definition
-    instanceDefinition.getAppConfOperations().set(
-        KEY_SECURITY_ENABLED, securityEnabled);
+    instanceDefinition.getAppConfOperations().set(KEY_SECURITY_ENABLED, securityEnabled);
 
     // triggers resolution and snapshotting for agent
     appState.setInitialInstanceDefinition(instanceDefinition);
@@ -660,61 +647,68 @@
       InternalKeys.INTERNAL_PROVIDER_NAME);
     log.info("Cluster provider type is {}", providerType);
     SliderProviderFactory factory =
-      SliderProviderFactory.createSliderProviderFactory(
-          providerType);
+      SliderProviderFactory.createSliderProviderFactory(providerType);
     providerService = factory.createServerProvider();
     // init the provider BUT DO NOT START IT YET
     initAndAddService(providerService);
-    providerRMOperationHandler =
-        new ProviderNotifyingOperationHandler(providerService);
+    providerRMOperationHandler = new ProviderNotifyingOperationHandler(providerService);
     
     // create a slider AM provider
     sliderAMProvider = new SliderAMProviderService();
     initAndAddService(sliderAMProvider);
     
-    InetSocketAddress address = SliderUtils.getRmSchedulerAddress(serviceConf);
-    log.info("RM is at {}", address);
+    InetSocketAddress rmSchedulerAddress = SliderUtils.getRmSchedulerAddress(serviceConf);
+    log.info("RM is at {}", rmSchedulerAddress);
     yarnRPC = YarnRPC.create(serviceConf);
 
+    // set up the YARN client. This may require patching in the RM client-API address if it
+    // is (somehow) unset server-side.    String clientRMaddr = serviceConf.get(YarnConfiguration.RM_ADDRESS);
+    InetSocketAddress clientRpcAddress = SliderUtils.getRmAddress(serviceConf);
+    if (!SliderUtils.isAddressDefined(clientRpcAddress)) {
+      // client addr is being unset. We can lift it from the other RM APIs
+      log.warn("Yarn RM address was unbound; attempting to fix up");
+      serviceConf.set(YarnConfiguration.RM_ADDRESS,
+          String.format("%s:%d", rmSchedulerAddress.getHostString(), clientRpcAddress.getPort() ));
+    }
+    initAndAddService(yarnClient = new SliderYarnClientImpl());
+    yarnClient.start();
+
     /*
      * Extract the container ID. This is then
      * turned into an (incompete) container
      */
     appMasterContainerID = ConverterUtils.toContainerId(
-      SliderUtils.mandatoryEnvVariable(
-          ApplicationConstants.Environment.CONTAINER_ID.name())
-                                                       );
+      SliderUtils.mandatoryEnvVariable(ApplicationConstants.Environment.CONTAINER_ID.name()));
     appAttemptID = appMasterContainerID.getApplicationAttemptId();
 
     ApplicationId appid = appAttemptID.getApplicationId();
     log.info("AM for ID {}", appid.getId());
 
-    appInformation.put(StatusKeys.INFO_AM_CONTAINER_ID,
-                       appMasterContainerID.toString());
-    appInformation.put(StatusKeys.INFO_AM_APP_ID,
-                       appid.toString());
-    appInformation.put(StatusKeys.INFO_AM_ATTEMPT_ID,
-                       appAttemptID.toString());
+    appInformation.put(StatusKeys.INFO_AM_CONTAINER_ID, appMasterContainerID.toString());
+    appInformation.put(StatusKeys.INFO_AM_APP_ID, appid.toString());
+    appInformation.put(StatusKeys.INFO_AM_ATTEMPT_ID, appAttemptID.toString());
 
     Map<String, String> envVars;
     List<Container> liveContainers;
-    
-    /**
+
+    List<NodeReport> nodeReports = yarnClient.getNodeReports(NodeState.RUNNING);
+    log.info("Yarn node report count: {}", nodeReports.size());
+
+    /*
      * It is critical this section is synchronized, to stop async AM events
      * arriving while registering a restarting AM.
      */
     synchronized (appState) {
       int heartbeatInterval = HEARTBEAT_INTERVAL;
 
-      //add the RM client -this brings the callbacks in
-      asyncRMClient = AMRMClientAsync.createAMRMClientAsync(heartbeatInterval,
-                                                            this);
+      // add the RM client -this brings the callbacks in
+      asyncRMClient = AMRMClientAsync.createAMRMClientAsync(heartbeatInterval, this);
       addService(asyncRMClient);
       //now bring it up
       deployChildService(asyncRMClient);
 
 
-      //nmclient relays callbacks back to this class
+      // nmclient relays callbacks back to this class
       nmClientAsync = new NMClientAsyncImpl("nmclient", this);
       deployChildService(nmClientAsync);
 
@@ -723,7 +717,7 @@
 
       if (securityEnabled) {
         // fix up the ACLs if they are not set
-        String acls = getConfig().get(KEY_PROTOCOL_ACL);
+        String acls = serviceConf.get(KEY_PROTOCOL_ACL);
         if (acls == null) {
           getConfig().set(KEY_PROTOCOL_ACL, "*");
         }
@@ -739,8 +733,7 @@
       appMasterHostname = rpcServiceAddress.getHostName();
       appMasterRpcPort = rpcServiceAddress.getPort();
       appMasterTrackingUrl = null;
-      log.info("AM Server is listening at {}:{}", appMasterHostname,
-               appMasterRpcPort);
+      log.info("AM Server is listening at {}:{}", appMasterHostname, appMasterRpcPort);
       appInformation.put(StatusKeys.INFO_AM_HOSTNAME, appMasterHostname);
       appInformation.set(StatusKeys.INFO_AM_RPC_PORT, appMasterRpcPort);
 
@@ -749,8 +742,7 @@
       log.info(registryOperations.toString());
 
       //build the role map
-      List<ProviderRole> providerRoles =
-        new ArrayList<ProviderRole>(providerService.getRoles());
+      List<ProviderRole> providerRoles = new ArrayList<>(providerService.getRoles());
       providerRoles.addAll(SliderAMClientProvider.ROLES);
 
       // Start up the WebApp and track the URL for it
@@ -785,25 +777,27 @@
       // *****************************************************
       log.info("Connecting to RM at {},address tracking URL={}",
                appMasterRpcPort, appMasterTrackingUrl);
-      amRegistrationData = asyncRMClient
-        .registerApplicationMaster(appMasterHostname,
+      amRegistrationData = asyncRMClient.registerApplicationMaster(appMasterHostname,
                                    appMasterRpcPort,
                                    appMasterTrackingUrl);
-      Resource maxResources =
-        amRegistrationData.getMaximumResourceCapability();
-      containerMaxMemory = maxResources.getMemory();
-      containerMaxCores = maxResources.getVirtualCores();
-      appState.setContainerLimits(maxResources.getMemory(),
-                                  maxResources.getVirtualCores());
+      maximumResourceCapability = amRegistrationData.getMaximumResourceCapability();
+
+      int minMemory = serviceConf.getInt(RM_SCHEDULER_MINIMUM_ALLOCATION_MB,
+          DEFAULT_RM_SCHEDULER_MINIMUM_ALLOCATION_MB);
+       // validate scheduler vcores allocation setting
+      int minCores = serviceConf.getInt(RM_SCHEDULER_MINIMUM_ALLOCATION_VCORES,
+          DEFAULT_RM_SCHEDULER_MINIMUM_ALLOCATION_VCORES);
+      int maxMemory = maximumResourceCapability.getMemory();
+      int maxCores = maximumResourceCapability.getVirtualCores();
+      appState.setContainerLimits(minMemory,maxMemory, minCores, maxCores );
 
       // build the handler for RM request/release operations; this uses
       // the max value as part of its lookup
-      rmOperationHandler = new AsyncRMOperationHandler(asyncRMClient,
-          maxResources);
+      rmOperationHandler = new AsyncRMOperationHandler(asyncRMClient, maximumResourceCapability);
 
       // set the RM-defined maximum cluster values
-      appInformation.put(ResourceKeys.YARN_CORES, Integer.toString(containerMaxCores));
-      appInformation.put(ResourceKeys.YARN_MEMORY, Integer.toString(containerMaxMemory));
+      appInformation.put(ResourceKeys.YARN_CORES, Integer.toString(maxCores));
+      appInformation.put(ResourceKeys.YARN_MEMORY, Integer.toString(maxMemory));
 
       processAMCredentials(securityConfiguration);
 
@@ -820,8 +814,7 @@
           // principal.  Can do so now since AM registration with RM above required
           // tokens associated to principal
           String principal = securityConfiguration.getPrincipal();
-          File localKeytabFile =
-              securityConfiguration.getKeytabFile(instanceDefinition);
+          File localKeytabFile = securityConfiguration.getKeytabFile(instanceDefinition);
           // Now log in...
           login(principal, localKeytabFile);
           // obtain new FS reference that should be kerberos based and different
@@ -838,8 +831,7 @@
       Configuration providerConf =
         providerService.loadProviderConfigurationInformation(confDir);
 
-      providerService
-          .initializeApplicationConfiguration(instanceDefinition, fs);
+      providerService.initializeApplicationConfiguration(instanceDefinition, fs);
 
       providerService.validateApplicationConfiguration(instanceDefinition,
           confDir,
@@ -849,15 +841,18 @@
       Path historyDir = new Path(clusterDirPath, HISTORY_DIR_NAME);
 
       //build the instance
-      appState.buildInstance(instanceDefinition,
-          serviceConf,
-          providerConf,
-          providerRoles,
-          fs.getFileSystem(),
-          historyDir,
-          liveContainers,
-          appInformation,
-          providerService.createContainerReleaseSelector());
+      AppStateBindingInfo binding = new AppStateBindingInfo();
+      binding.instanceDefinition = instanceDefinition;
+      binding.serviceConfig = serviceConf;
+      binding.publishedProviderConf = providerConf;
+      binding.roles = providerRoles;
+      binding.fs = fs.getFileSystem();
+      binding.historyPath = historyDir;
+      binding.liveContainers = liveContainers;
+      binding.applicationInfo = appInformation;
+      binding.releaseSelector = providerService.createContainerReleaseSelector();
+      binding.nodeReports = nodeReports;
+      appState.buildInstance(binding);
 
       providerService.rebuildContainerDetails(liveContainers,
           instanceDefinition.getName(), appState.getRolePriorityMap());
@@ -1000,7 +995,7 @@
            .start(webApp);
 
     WebAppService<SliderAMWebApp> webAppService =
-      new WebAppService<SliderAMWebApp>("slider", webApp);
+      new WebAppService<>("slider", webApp);
 
     deployChildService(webAppService);
   }
@@ -1013,7 +1008,7 @@
     // up to date token for container launches (getContainerCredentials()).
     UserGroupInformation currentUser = UserGroupInformation.getCurrentUser();
     Credentials credentials = currentUser.getCredentials();
-    List<Text> filteredTokens = new ArrayList<Text>();
+    List<Text> filteredTokens = new ArrayList<>();
     filteredTokens.add(AMRMTokenIdentifier.KIND_NAME);
 
     boolean keytabProvided = securityConfiguration.isKeytabProvided();
@@ -1086,6 +1081,7 @@
 
   protected void login(String principal, File localKeytabFile)
       throws IOException, SliderException {
+    log.info("Logging in as {} with keytab {}", principal, localKeytabFile);
     UserGroupInformation.loginUserFromKeytab(principal,
                                              localKeytabFile.getAbsolutePath());
     validateLoginUser(UserGroupInformation.getLoginUser());
@@ -1648,7 +1644,7 @@
     // If components are specified as well, then grab all the containers of
     // each of the components (roles)
     if (CollectionUtils.isNotEmpty(components)) {
-      Map<ContainerId, RoleInstance> liveContainers = appState.getLiveNodes();
+      Map<ContainerId, RoleInstance> liveContainers = appState.getLiveContainers();
       if (CollectionUtils.isNotEmpty(liveContainers.keySet())) {
         Map<String, Set<String>> roleContainerMap = prepareRoleContainerMap(liveContainers);
         for (String component : components) {
@@ -1888,7 +1884,15 @@
     LOG_YARN.info("onNodesUpdated({})", updatedNodes.size());
     log.info("Updated nodes {}", updatedNodes);
     // Check if any nodes are lost or revived and update state accordingly
-    appState.onNodesUpdated(updatedNodes);
+
+    AppState.NodeUpdatedOutcome outcome = appState.onNodesUpdated(updatedNodes);
+    if (!outcome.operations.isEmpty()) {
+      execute(outcome.operations);
+    }
+    // trigger a review if the cluster changed
+    if (outcome.clusterChanged) {
+      reviewRequestAndReleaseNodes("nodes updated");
+    }
   }
 
   /**
@@ -1948,15 +1952,6 @@
 /* =================================================================== */
 
   /**
-   * Update the cluster description with anything interesting
-   */
-  public synchronized ClusterDescription updateClusterStatus() {
-    Map<String, String> providerStatus = providerService.buildProviderStatus();
-    assert providerStatus != null : "null provider status";
-    return appState.refreshClusterStatus(providerStatus);
-  }
-
-  /**
    * Launch the provider service
    *
    * @param instanceDefinition definition of the service
@@ -1967,7 +1962,7 @@
   protected synchronized void launchProviderService(AggregateConf instanceDefinition,
                                                     File confDir)
     throws IOException, SliderException {
-    Map<String, String> env = new HashMap<String, String>();
+    Map<String, String> env = new HashMap<>();
     boolean execStarted = providerService.exec(instanceDefinition, confDir, env,
         this);
     if (execStarted) {
@@ -2249,7 +2244,7 @@
         internals.getOptionBool(InternalKeys.CHAOS_MONKEY_ENABLED,
             InternalKeys.DEFAULT_CHAOS_MONKEY_ENABLED);
     if (!enabled) {
-      log.info("Chaos monkey disabled");
+      log.debug("Chaos monkey disabled");
       return false;
     }
     
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java
index 1aa9088..7446e82 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java
@@ -77,7 +77,7 @@
   public void execute(SliderAppMaster appMaster,
       QueueAccess queueService,
       AppState appState) throws Exception {
-      List<AbstractRMOperation> opsList = new LinkedList<AbstractRMOperation>();
+      List<AbstractRMOperation> opsList = new LinkedList<>();
     ContainerReleaseOperation release = new ContainerReleaseOperation(containerId);
     opsList.add(release);
     //now apply the operations
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/QueueService.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/QueueService.java
index 146dea4..34acade 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/QueueService.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/QueueService.java
@@ -58,20 +58,20 @@
    * Immediate actions.
    */
   public final BlockingDeque<AsyncAction> actionQueue =
-      new LinkedBlockingDeque<AsyncAction>();
+      new LinkedBlockingDeque<>();
 
   /**
    * Actions to be scheduled in the future
    */
-  public final DelayQueue<AsyncAction> scheduledActions = new DelayQueue<AsyncAction>();
+  public final DelayQueue<AsyncAction> scheduledActions = new DelayQueue<>();
 
   /**
    * Map of renewing actions by name ... this is to allow them to 
    * be cancelled by name
    */
   private final Map<String, RenewingAction<? extends AsyncAction>> renewingActions
-      = new ConcurrentHashMap<String, RenewingAction<? extends AsyncAction>>();
-  
+      = new ConcurrentHashMap<>();
+
   /**
    * Create a queue instance with a single thread executor
    */
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/BoolMetric.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/BoolMetric.java
new file mode 100644
index 0000000..33f8d85
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/BoolMetric.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.server.appmaster.management;
+
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.Metric;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A bool metric, mapped to an integer. true maps to 1,  false to zero,
+ */
+public class BoolMetric implements Metric, Gauge<Integer> {
+
+  private final AtomicBoolean value;
+
+  public BoolMetric(boolean b) {
+    value = new AtomicBoolean(b);
+  }
+
+  public void set(boolean b) {
+    value.set(b);
+  }
+
+  public boolean get() {
+    return value.get();
+  }
+
+  @Override
+  public Integer getValue() {
+    return value.get() ? 1 : 0;
+  }
+
+  /**
+   * Evaluate from a string. Returns true if the string is considered to match 'true',
+   * false otherwise.
+   * @param s source
+   * @return true if the input parses to an integer other than 0. False if it doesn't parse
+   * or parses to 0.
+   */
+  public static boolean fromString(String s) {
+    try {
+      return Integer.valueOf(s) != 0;
+    } catch (NumberFormatException e) {
+      return false;
+    }
+  }
+
+  @Override
+  public String toString() {
+    return value.toString();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+
+    BoolMetric that = (BoolMetric) o;
+    return get() == that.get();
+  }
+
+  @Override
+  public int hashCode() {
+    return value.hashCode();
+  }
+}
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/BoolMetricPredicate.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/BoolMetricPredicate.java
new file mode 100644
index 0000000..82bcd3a
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/BoolMetricPredicate.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.server.appmaster.management;
+
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.Metric;
+
+/**
+ * A metric which takes a predicate and returns 1 if the predicate evaluates
+ * to true. The predicate is evaluated whenever the metric is read.
+ */
+public class BoolMetricPredicate implements Metric, Gauge<Integer> {
+
+  private final Eval predicate;
+
+  public BoolMetricPredicate(Eval predicate) {
+    this.predicate = predicate;
+  }
+
+  @Override
+  public Integer getValue() {
+    return predicate.eval() ? 1: 0;
+  }
+
+  public interface Eval {
+    boolean eval();
+  }
+}
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/LongGauge.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/LongGauge.java
new file mode 100644
index 0000000..c93467b
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/LongGauge.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.server.appmaster.management;
+
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.Metric;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * This is a {@link AtomicLong} which acts as a metrics gauge: its state can be exposed as
+ * a metrics.
+ * It also exposes some of the same method names as the Codahale Counter class, so that
+ * it's easy to swap in.
+ *
+ */
+public class LongGauge extends AtomicLong implements Metric, Gauge<Long> {
+
+  /**
+   * Instantiate
+   * @param val current value
+   */
+  public LongGauge(long val) {
+    super(val);
+  }
+
+  /**
+   * Instantiate with value 0
+   */
+  public LongGauge() {
+    this(0);
+  }
+
+  /**
+   * Get the value as a metric
+   * @return current value
+   */
+  @Override
+  public Long getValue() {
+    return get();
+  }
+
+  /**
+   * Method from {@Code counter}; used here for drop-in replacement
+   * without any recompile
+   * @return current value
+   */
+  public Long getCount() {
+    return get();
+  }
+
+  /**
+   * {@code ++}
+   */
+  public void inc() {
+    incrementAndGet();
+  }
+
+  /**
+   * {@code --}
+   */
+  public void dec() {
+    decrementAndGet();
+  }
+
+  /**
+   * Decrement to the floor of 0. Operations in parallel may cause confusion here,
+   * but it will still never go below zero
+   * @param delta delta
+   * @return the current value
+   */
+  public long decToFloor(long delta) {
+    long l = get();
+    long r = l - delta;
+    if (r < 0) {
+      r = 0;
+    }
+    // if this fails, the decrement has been lost
+    compareAndSet(l, r);
+    return get();
+  }
+}
diff --git a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockRecordFactory.groovy b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/LongMetricFunction.java
similarity index 60%
copy from slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockRecordFactory.groovy
copy to slider-core/src/main/java/org/apache/slider/server/appmaster/management/LongMetricFunction.java
index f7d353f..1de7345 100644
--- a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockRecordFactory.groovy
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/LongMetricFunction.java
@@ -16,15 +16,29 @@
  * limitations under the License.
  */
 
-package org.apache.slider.server.appmaster.model.mock
+package org.apache.slider.server.appmaster.management;
 
-import org.apache.hadoop.yarn.api.records.Resource
-import org.apache.slider.server.appmaster.state.AbstractRecordFactory
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.Metric;
 
-class MockRecordFactory extends AbstractRecordFactory {
+/**
+ * A metric which takes a function to generate a long value.
+ * The function is evaluated whenever the metric is read.
+ */
+public class LongMetricFunction implements Metric, Gauge<Long> {
+
+  private final Eval function;
+
+  public LongMetricFunction(Eval function) {
+    this.function = function;
+  }
 
   @Override
-  Resource newResource() {
-    return new MockResource()
+  public Long getValue() {
+    return function.eval();
+  }
+
+  public interface Eval {
+    long eval();
   }
 }
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MeterAndCounter.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MeterAndCounter.java
index 58d9eb3..02ab7bc 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MeterAndCounter.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MeterAndCounter.java
@@ -74,6 +74,11 @@
     meter.mark();
   }
 
+  public void inc() {
+    mark();
+  }
+
+
   @Override
   public boolean equals(Object o) {
     if (this == o) {
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsAndMonitoring.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsAndMonitoring.java
index 5b96256..37a8935 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsAndMonitoring.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsAndMonitoring.java
@@ -18,13 +18,17 @@
 
 package org.apache.slider.server.appmaster.management;
 
+import com.codahale.metrics.Metric;
 import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.MetricSet;
 import com.codahale.metrics.health.HealthCheckRegistry;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.service.AbstractService;
 import org.apache.hadoop.service.CompositeService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -32,7 +36,8 @@
  * Class for all metrics and monitoring
  */
 public class MetricsAndMonitoring extends CompositeService {
-
+  protected static final Logger log =
+    LoggerFactory.getLogger(MetricsAndMonitoring.class);
   public MetricsAndMonitoring(String name) {
     super(name);
   }
@@ -49,9 +54,17 @@
   final HealthCheckRegistry health = new HealthCheckRegistry();
 
   private final Map<String, MeterAndCounter> meterAndCounterMap
-      = new ConcurrentHashMap<String, MeterAndCounter>();
-  
-  
+      = new ConcurrentHashMap<>();
+
+  private final List<MetricSet> metricSets = new ArrayList<>();
+
+  /**
+   * List of recorded events
+   */
+  private final List<RecordedEvent> eventHistory = new ArrayList<>(100);
+
+  public static final int EVENT_LIMIT = 1000;
+
   public MetricRegistry getMetrics() {
     return metrics;
   }
@@ -67,6 +80,14 @@
     super.serviceInit(conf);
   }
 
+  @Override
+  protected void serviceStop() throws Exception {
+    super.serviceStop();
+    for (MetricSet set : metricSets) {
+      unregister(set);
+    }
+  }
+
   public MeterAndCounter getMeterAndCounter(String name) {
     return meterAndCounterMap.get(name);
   }
@@ -92,7 +113,7 @@
   }
 
   /**
-   * Get a specific meter and mark it
+   * Get a specific meter and mark it. This will create and register it on demand.
    * @param name name of meter/counter
    */
   public void markMeterAndCounter(String name) {
@@ -100,4 +121,75 @@
     meter.mark();
   }
 
+  /**
+   * Given a {@link Metric}, registers it under the given name.
+   *
+   * @param name   the name of the metric
+   * @param metric the metric
+   * @param <T>    the type of the metric
+   * @return {@code metric}
+   * @throws IllegalArgumentException if the name is already registered
+   */
+  public <T extends Metric> T register(String name, T metric) throws IllegalArgumentException {
+    return metrics.register(name, metric);
+  }
+
+  public <T extends Metric> T register(Class<?> klass, T metric, String... names)
+      throws IllegalArgumentException {
+    return register(MetricRegistry.name(klass, names), metric);
+  }
+
+
+  /**
+   * Add an event (synchronized)
+   * @param event event
+   */
+  public synchronized void noteEvent(RecordedEvent event) {
+    if (eventHistory.size() > EVENT_LIMIT) {
+      eventHistory.remove(0);
+    }
+    eventHistory.add(event);
+  }
+
+  /**
+   * Clone the event history; blocks for the duration of the copy operation.
+   * @return a new list
+   */
+  public synchronized List<RecordedEvent> cloneEventHistory() {
+    return new ArrayList<>(eventHistory);
+  }
+
+  /**
+   * Add a metric set for registering and deregistration on service stop
+   * @param metricSet metric set
+   */
+  public void addMetricSet(MetricSet metricSet) {
+    metricSets.add(metricSet);
+    metrics.registerAll(metricSet);
+  }
+
+  /**
+   * add a metric set, giving each entry a prefix
+   * @param prefix prefix (a trailing "." is automatically added)
+   * @param metricSet the metric set to register
+   */
+  public void addMetricSet(String prefix, MetricSet metricSet) {
+    addMetricSet(new PrefixedMetricsSet(prefix, metricSet));
+  }
+
+  /**
+   * Unregister a metric set; robust
+   * @param metricSet metric set to unregister
+   */
+  public void unregister(MetricSet metricSet) {
+    for (String s : metricSet.getMetrics().keySet()) {
+      try {
+        metrics.remove(s);
+      } catch (IllegalArgumentException e) {
+        // log but continue
+        log.info("Exception when trying to unregister {}", s, e);
+      }
+    }
+  }
 }
+
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsBindingService.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsBindingService.java
index f8646bf..864a1cf 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsBindingService.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsBindingService.java
@@ -19,7 +19,9 @@
 package org.apache.slider.server.appmaster.management;
 
 import com.codahale.metrics.JmxReporter;
+import com.codahale.metrics.Metric;
 import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.MetricSet;
 import com.codahale.metrics.ScheduledReporter;
 import com.codahale.metrics.Slf4jReporter;
 import com.google.common.base.Preconditions;
@@ -29,6 +31,9 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -79,7 +84,7 @@
     JmxReporter jmxReporter;
     jmxReporter = JmxReporter.forRegistry(metrics).build();
     jmxReporter.start();
-    addService(new ClosingService<JmxReporter>(jmxReporter));
+    addService(new ClosingService<>(jmxReporter));
 
 
     // Ganglia
@@ -128,7 +133,7 @@
                               .convertDurationsTo(TimeUnit.MILLISECONDS)
                               .build();
       reporter.start(interval, TimeUnit.MINUTES);
-      addService(new ClosingService<ScheduledReporter>(reporter));
+      addService(new ClosingService<>(reporter));
       summary.append(String.format(", SLF4J to log %s interval=%d",
           logName, interval));
     }
@@ -136,8 +141,11 @@
     log.info(reportingDetails);
   }
 
+
   @Override
   public String toString() {
     return super.toString() + " " + reportingDetails;
   }
+
+
 }
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsConstants.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsConstants.java
index 31a82a3..fa6bfc0 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsConstants.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/MetricsConstants.java
@@ -53,4 +53,6 @@
    */
   public static final String CONTAINERS_START_FAILED = "containers.start-failed";
 
+  public static final String PREFIX_SLIDER_ROLES = "slider.roles.";
+
 }
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/PrefixedMetricsSet.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/PrefixedMetricsSet.java
new file mode 100644
index 0000000..e9ad46a
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/PrefixedMetricsSet.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.server.appmaster.management;
+
+import com.codahale.metrics.Metric;
+import com.codahale.metrics.MetricSet;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * From an existing metrics set, generate a new metrics set with the
+ * prefix in front of every key.
+ *
+ * The prefix is added directly: if you want a '.' between prefix and metric
+ * keys, include it in the prefix.
+ */
+public class PrefixedMetricsSet implements MetricSet {
+
+  private final String prefix;
+  private final MetricSet source;
+
+  public PrefixedMetricsSet(String prefix, MetricSet source) {
+    this.prefix = prefix;
+    this.source = source;
+  }
+
+  @Override
+  public Map<String, Metric> getMetrics() {
+    Map<String, Metric> sourceMetrics = source.getMetrics();
+    Map<String, Metric> metrics = new HashMap<>(sourceMetrics.size());
+    for (Map.Entry<String, Metric> entry : sourceMetrics.entrySet()) {
+      metrics.put(prefix + "." + entry.getKey(), entry.getValue());
+    }
+    return metrics;
+  }
+}
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/RangeLimitedCounter.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/RangeLimitedCounter.java
new file mode 100644
index 0000000..80e88fc
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/RangeLimitedCounter.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.server.appmaster.management;
+
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.Counting;
+import com.codahale.metrics.Metric;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * This is a counter whose range can be given a min and a max
+ */
+public class RangeLimitedCounter implements Metric, Counting {
+
+  private final AtomicLong value;
+  private final long min, max;
+
+  /**
+   * Instantiate
+   * @param val current value
+   * @param min minimum value
+   * @param max max value (or 0 for no max)
+   */
+  public RangeLimitedCounter(long val, long min, long max) {
+    this.value = new AtomicLong(val);
+    this.min = min;
+    this.max = max;
+  }
+
+  /**
+   * Set to a new value. If below the min, set to the minimum. If the max is non
+   * zero and the value is above that maximum, set it to the maximum instead.
+   * @param val value
+   */
+  public synchronized void set(long val) {
+    if (val < min) {
+      val = min;
+    } else if (max > 0  && val > max) {
+      val = max;
+    }
+    value.set(val);
+  }
+
+  public void inc() {
+    inc(1);
+  }
+
+  public void dec() {
+    dec(1);
+  }
+
+  public synchronized void inc(int delta) {
+    set(value.get() + delta);
+  }
+
+  public synchronized void dec(int delta) {
+    set(value.get() - delta);
+  }
+
+  public long get() {
+    return value.get();
+  }
+
+  @Override
+  public long getCount() {
+    return value.get();
+  }
+}
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/management/RecordedEvent.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/RecordedEvent.java
new file mode 100644
index 0000000..d48d337
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/RecordedEvent.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.server.appmaster.management;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.text.DateFormat;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+public class RecordedEvent {
+  private static final DateFormat dateFormat = DateFormat.getDateInstance();
+  public long id;
+  public String name;
+  public long timestamp;
+  public String time;
+  public String category;
+  public String host;
+  public int role;
+  public String text;
+
+  public RecordedEvent() {
+  }
+
+  /**
+   * Create an event. The timestamp is also converted to a time string
+   * @param id id counter
+   * @param name event name
+   * @param timestamp timestamp. If non-zero, is used to build the {@code time} text field.
+   * @param category even category
+   * @param text arbitrary text
+   */
+  public RecordedEvent(long id, String name, long timestamp, String category, String text) {
+    this.id = id;
+    this.name = name;
+    this.timestamp = timestamp;
+    this.time = timestamp > 0 ? dateFormat.format(timestamp) : "";
+    this.category = category;
+    this.text = text;
+  }
+}
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AbstractRecordFactory.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/Timestamp.java
similarity index 74%
rename from slider-core/src/main/java/org/apache/slider/server/appmaster/state/AbstractRecordFactory.java
rename to slider-core/src/main/java/org/apache/slider/server/appmaster/management/Timestamp.java
index e9655f0..c30e749 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AbstractRecordFactory.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/management/Timestamp.java
@@ -16,15 +16,18 @@
  * limitations under the License.
  */
 
-package org.apache.slider.server.appmaster.state;
-
-import org.apache.hadoop.yarn.api.records.Resource;
+package org.apache.slider.server.appmaster.management;
 
 /**
- * Factory supplying records created by the App state; entry point
- * for mock code.
+ * A timestamp metric
  */
-public abstract class AbstractRecordFactory {
-  
-  public abstract Resource newResource();
+public class Timestamp extends LongGauge {
+
+  public Timestamp(long val) {
+    super(val);
+  }
+
+  public Timestamp() {
+  }
+
 }
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillContainer.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillContainer.java
index a5cdfc6..ae38e4c 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillContainer.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillContainer.java
@@ -72,15 +72,13 @@
       }
     }
     int size = liveContainers.size();
-    if (size <= 0) {
-      log.info("No containers to kill");
-      return;
-    }
-    int target = random.nextInt(size);
-    RoleInstance roleInstance = liveContainers.get(target);
-    log.info("Killing {}", roleInstance);
+    if (size > 0) {
+      int target = random.nextInt(size);
+      RoleInstance roleInstance = liveContainers.get(target);
+      log.info("Killing {}", roleInstance);
 
-    queues.schedule(new ActionKillContainer(roleInstance.getId(),
-        DELAY, TimeUnit.MILLISECONDS, operationHandler));
+      queues.schedule(new ActionKillContainer(roleInstance.getId(),
+          DELAY, TimeUnit.MILLISECONDS, operationHandler));
+    }
   }
 }
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosMonkeyService.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosMonkeyService.java
index 27219e4..8948f0d 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosMonkeyService.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosMonkeyService.java
@@ -60,7 +60,8 @@
   public synchronized void addTarget(String name,
       ChaosTarget target, long probability) {
     if (probability > 0) {
-      log.info("Adding {} with probability {}", name, probability / InternalKeys.PROBABILITY_PERCENT_1);
+      log.info("Adding {} with probability {}", name,
+          ((double)probability) / InternalKeys.PROBABILITY_PERCENT_1);
       chaosEntries.add(new ChaosEntry(name, target, probability, metrics));
     } else {
       log.debug("Action {} not enabled", name);
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AbstractRMOperation.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AbstractRMOperation.java
index da8d646..ed3f197 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AbstractRMOperation.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AbstractRMOperation.java
@@ -23,8 +23,8 @@
   /**
    * Execute the operation
    * @param asyncRMClient client
-   * @param handler
+   * @param handler handler to perform the execution
    */
   public abstract void execute(RMOperationHandlerActions handler);
-  
+
 }
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AsyncRMOperationHandler.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AsyncRMOperationHandler.java
index 11afc0e..03231ef 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AsyncRMOperationHandler.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AsyncRMOperationHandler.java
@@ -63,6 +63,7 @@
    * @param count count to cancel
    * @return number of requests cancelled
    */
+  @SuppressWarnings("unchecked")
   protected int cancelSinglePriorityRequests(Priority priority,
       int count) {
     List<Collection<AMRMClient.ContainerRequest>> requestSets =
@@ -88,6 +89,7 @@
   }
 
   @Override
+  @SuppressWarnings("unchecked")
   public void cancelSingleRequest(AMRMClient.ContainerRequest request) {
     // a single release
     client.removeContainerRequest(request);
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/CancelSingleRequest.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/CancelSingleRequest.java
index 08eb5bc..d7673d3 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/CancelSingleRequest.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/CancelSingleRequest.java
@@ -18,7 +18,9 @@
 
 package org.apache.slider.server.appmaster.operations;
 
+import com.google.common.base.Preconditions;
 import org.apache.hadoop.yarn.client.api.AMRMClient;
+import org.apache.slider.server.appmaster.state.ContainerPriority;
 
 /**
  * Cancel a container request
@@ -28,6 +30,7 @@
   private final AMRMClient.ContainerRequest request;
 
   public CancelSingleRequest(AMRMClient.ContainerRequest request) {
+    Preconditions.checkArgument(request != null, "Null container request");
     this.request = request;
   }
 
@@ -42,7 +45,9 @@
 
   @Override
   public String toString() {
-    return "cancel single request for container at " + request.getPriority().toString();
+    return "Cancel container request"
+        + " for :" + ContainerPriority.toString(request.getPriority())
+        + " request " + request;
   }
 
 
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerReleaseOperation.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerReleaseOperation.java
index 46da536..4271d50 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerReleaseOperation.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerReleaseOperation.java
@@ -18,13 +18,16 @@
 
 package org.apache.slider.server.appmaster.operations;
 
+import com.google.common.base.Preconditions;
 import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.slider.server.appmaster.state.ContainerPriority;
 
 public class ContainerReleaseOperation extends AbstractRMOperation {
 
   private final ContainerId containerId;
 
   public ContainerReleaseOperation(ContainerId containerId) {
+    Preconditions.checkArgument(containerId != null, "Null containerId");
     this.containerId = containerId;
   }
 
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerRequestOperation.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerRequestOperation.java
index b8120ca..e29ddd0 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerRequestOperation.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerRequestOperation.java
@@ -18,14 +18,20 @@
 
 package org.apache.slider.server.appmaster.operations;
 
+import com.google.common.base.Preconditions;
+import org.apache.hadoop.yarn.