anchor.diff:              <thead>
               <tr>
                   <th style="width: 1%"></th>
  -                <th style="width: 1%"><fmt:message key="short.title"/></th>
  -                <c:forEach items="${plugins}" var="plugin">
  -                    <th style="width: 1%"><c:out value="${plugin}"/></th>
  +                <%--@elvariable id="clusterNodeInfo" type="org.jivesoftware.openfire.cluster.ClusterNodeInfo>"--%>
  +                <c:forEach items="${clusterNodesInfo}" var="clusterNodeInfo">
  +                    <th style="width: 1%"><c:out value="${clusterNodeInfo.hostName}"/></th>
                   </c:forEach>
               </tr>
               </thead>
               <tbody>
  -            <!--@elvariable id="clusterNodeInfo" type="org.jivesoftware.openfire.cluster.ClusterNodeInfo>"-->
  -            <c:forEach items="${clusterNodesInfo}" var="clusterNodeInfo">
  -                <tr <c:if test="${localNodeID == clusterNodeInfo.nodeID}">class="local"</c:if>
  -                    style="vertical-align:middle">
  -                    <th style="width: 1%">
  -                        <c:out value="${clusterNodeInfo.hostName}"/>
  -                    </th>
  -                    <td class="jive-description" style="width: 1%">
  -                        <c:out value="${pluginVersions.get(clusterNodeInfo.nodeID, 'Openfire')}"/>
  -                        <c:if test="${pluginVersions.get(localNodeID, 'Openfire') != pluginVersions.get(clusterNodeInfo.nodeID, 'Openfire')}">
  +            <tr>
  +                <th style="width: 1%">
  +                    <fmt:message key="short.title"/>
  +                </th>
  +                <c:forEach items="${clusterNodesInfo}" var="clusterNodeInfo">
  +                    <td class="jive-description <c:if test="${localNodeID == clusterNodeInfo.nodeID}">local</c:if>"
  +                        style="width: 1%">
  +                        <c:out value="${pluginVersions.get('Openfire', clusterNodeInfo.nodeID)}"/>
  +                        <c:if test="${pluginVersions.get('Openfire', localNodeID) != pluginVersions.get('Openfire', clusterNodeInfo.nodeID)}">
                               <img src="images/warning-16x16.gif" width="16" height="16" alt="Warning">
                           </c:if>
                       </td>
  -                    <c:forEach items="${plugins}" var="plugin">
  -                        <td class="jive-description" style="width: 1%">
  -                            <c:out value="${pluginVersions.get(clusterNodeInfo.nodeID, plugin)}"/>
  -                            <c:if test="${pluginVersions.get(localNodeID, plugin) != pluginVersions.get(clusterNodeInfo.nodeID, plugin)}">
  +                </c:forEach>
  +            </tr>
  +            <c:forEach items="${plugins}" var="plugin">
  +                <tr style="vertical-align:middle">
  +                    <th style="width: 1%">
  +                        <c:out value="${plugin}"/>
  +                    </th>
  +                    <c:forEach items="${clusterNodesInfo}" var="clusterNodeInfo">
  +                        <td class="jive-description <c:if test="${localNodeID == clusterNodeInfo.nodeID}">local</c:if>"
  +                            style="width: 1%">
  +                            <c:out value="${pluginVersions.get(plugin, clusterNodeInfo.nodeID)}"/>
  +                            <c:if test="${pluginVersions.get(plugin, localNodeID) != pluginVersions.get(plugin, clusterNodeInfo.nodeID)}">
                                   <img src="images/warning-16x16.gif" width="16" height="16" alt="Warning">
                               </c:if>
                           </td>
  
positive.code: <%@ page import="java.util.concurrent.TimeUnit" %>
  <%@ page import="org.jivesoftware.openfire.cluster.GetClusteredVersions" %>
  <%@ page import="org.jivesoftware.openfire.cluster.NodeID" %>
  <%@ page import="java.util.HashMap" %>
  <%@ page import="com.google.common.collect.Table" %>
  <%@ page import="com.google.common.collect.HashBasedTable" %>
  <%@ page import="java.util.Set" %>
  <%@ page import="java.util.TreeSet" %>
  <%@ page import="java.util.Collections" %>
  <%@ page import="java.util.ArrayList" %>
  <%@ page import="java.util.List" %>
  <%@ page import="java.util.Comparator" %>
  <%@ page import="java.util.Objects" %>
  
  <jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager" />
  <% webManager.init(request, response, session, application, out ); %>
  
negative.code:     // Note; if any one node in the cluster does not have the GetClusterVersions task, running
      // CacheFactory.doSynchronousClusterTask() on all nodes will return an empty collection. For
      // that reason, run the task on each node individually.
      final Table<String, NodeID, String> pluginVersions = HashBasedTable.create();
      final Set<String> plugins = new TreeSet<>();
      clusterNodesInfo.forEach(clusterNodeInfo -> {
          final NodeID nodeID = clusterNodeInfo.getNodeID();
          final GetClusteredVersions clusteredVersions = CacheFactory.doSynchronousClusterTask(
              new GetClusteredVersions(), nodeID.toByteArray());
          if (clusteredVersions != null) {
              pluginVersions.put("Openfire", nodeID, clusteredVersions.getOpenfireVersion());
              clusteredVersions.getPluginVersions().forEach((pluginName, pluginVersion) -> {
                  plugins.add(pluginName);
                  pluginVersions.put(pluginName, nodeID, pluginVersion);
              });
          }
      });
  