public ClusterStatsNodes(ClusterStatsNodeResponse[] nodeResponses) {
    this.counts = new Counts();
    this.versions = new HashSet<Version>();
    this.os = new OsStats();
    this.jvm = new JvmStats();
    this.fs = new FsStats.Info();
    this.plugins = new HashSet<PluginInfo>();
    this.process = new ProcessStats();

    Set<InetAddress> seenAddresses = new HashSet<InetAddress>(nodeResponses.length);

    for (ClusterStatsNodeResponse nodeResponse : nodeResponses) {

      counts.addNodeInfo(nodeResponse.nodeInfo());
      versions.add(nodeResponse.nodeInfo().getVersion());
      process.addNodeStats(nodeResponse.nodeStats());
      jvm.addNodeInfoStats(nodeResponse.nodeInfo(), nodeResponse.nodeStats());
      plugins.addAll(nodeResponse.nodeInfo().getPlugins().getInfos());

      // now do the stats that should be deduped by hardware (implemented by ip deduping)
      TransportAddress publishAddress =
          nodeResponse.nodeInfo().getTransport().address().publishAddress();
      InetAddress inetAddress = null;
      if (publishAddress.uniqueAddressTypeId() == 1) {
        inetAddress = ((InetSocketTransportAddress) publishAddress).address().getAddress();
      }

      if (!seenAddresses.add(inetAddress)) {
        continue;
      }

      os.addNodeInfo(nodeResponse.nodeInfo());
      if (nodeResponse.nodeStats().getFs() != null) {
        fs.add(nodeResponse.nodeStats().getFs().total());
      }
    }
  }