code: private List<NodeInfo> nodeInfoFromExtended(final List<PortInfo> nodesExt, final List<NodeInfo> nodeInfos) {
          List<NodeInfo> converted = new ArrayList<NodeInfo>(nodesExt.size());
          for (int i = 0; i < nodesExt.size(); i++) {
              NetworkAddress hostname = nodesExt.get(i).hostname();
  
              // Since nodeInfo and nodesExt might not be the same size, this can be null!
              NodeInfo nodeInfo = i >= nodeInfos.size() ? null : nodeInfos.get(i);
  
              if (hostname == null) {
                  if (nodeInfo != null) {
                      hostname = nodeInfo.hostname();
                  } else {
                      // If hostname missing, then node configured using localhost
                      LOGGER.debug("Hostname is for nodesExt[{}] is not available, falling back to origin.", i);
                      hostname = origin;
                  }
              }
              Map<ServiceType, Integer> ports = nodesExt.get(i).ports();
              Map<ServiceType, Integer> sslPorts = nodesExt.get(i).sslPorts();
              Map<String, AlternateAddress> aa = nodesExt.get(i).alternateAddresses();
  
              // this is an ephemeral bucket (not supporting views), don't enable views!
              if (!bucketCapabilities.contains(BucketCapabilities.COUCHAPI)) {
                  ports.remove(ServiceType.VIEW);
                  sslPorts.remove(ServiceType.VIEW);
              }
  
              // make sure only kv nodes are added if they are actually also in the nodes
              // list and not just in nodesExt, since the kv service might be available
              // on the cluster but not yet enabled for this specific bucket.
              if (nodeInfo == null) {
                  ports.remove(ServiceType.BINARY);
                  sslPorts.remove(ServiceType.BINARY);
              }
  
              converted.add(new DefaultNodeInfo(hostname, ports, sslPorts, aa));
          }
          return converted;
      }
docs: Helper method to create the {@link NodeInfo}s from from the extended node information.
  
  In older server versions (< 3.0.2) the nodesExt part does not carry a hostname, so as a fallback the hostname
  is loaded from the node info if needed.
  
  @param nodesExt the extended information.
  @return the generated node infos.