public static class Builder {
    private ServerAddress address;
    private ServerType type = Unknown;
    private Set<String> hosts = Collections.emptySet();
    private Set<String> passives = Collections.emptySet();
    private Set<String> arbiters = Collections.emptySet();
    private String primary;
    private int maxDocumentSize = DEFAULT_MAX_DOCUMENT_SIZE;
    private int maxMessageSize = DEFAULT_MAX_MESSAGE_SIZE;
    private Tags tags = Tags.freeze(new Tags());
    private String setName;
    private Integer setVersion;
    private long averagePingTimeNanos;
    private boolean ok;
    private ServerConnectionState state;
    private ServerVersion version = new ServerVersion();
    private int minWireVersion = 0;
    private int maxWireVersion = 0;

    // CHECKSTYLE:OFF
    public Builder address(final ServerAddress address) {
      this.address = address;
      return this;
    }

    public Builder type(final ServerType type) {
      this.type = notNull("type", type);
      return this;
    }

    public Builder hosts(final Set<String> hosts) {
      this.hosts =
          hosts == null
              ? Collections.<String>emptySet()
              : Collections.unmodifiableSet(new HashSet<String>(hosts));
      return this;
    }

    public Builder passives(final Set<String> passives) {
      this.passives =
          passives == null
              ? Collections.<String>emptySet()
              : Collections.unmodifiableSet(new HashSet<String>(passives));
      return this;
    }

    public Builder arbiters(final Set<String> arbiters) {
      this.arbiters =
          arbiters == null
              ? Collections.<String>emptySet()
              : Collections.unmodifiableSet(new HashSet<String>(arbiters));
      return this;
    }

    public Builder primary(final String primary) {
      this.primary = primary;
      return this;
    }

    public Builder maxDocumentSize(final int maxBSONObjectSize) {
      this.maxDocumentSize = maxBSONObjectSize;
      return this;
    }

    public Builder maxMessageSize(final int maxMessageSize) {
      this.maxMessageSize = maxMessageSize;
      return this;
    }

    public Builder tags(final Tags tags) {
      this.tags = tags == null ? Tags.freeze(new Tags()) : Tags.freeze(tags);
      return this;
    }

    public Builder averagePingTime(final long averagePingTime, final TimeUnit timeUnit) {
      this.averagePingTimeNanos = timeUnit.toNanos(averagePingTime);
      return this;
    }

    public Builder setName(final String setName) {
      this.setName = setName;
      return this;
    }

    public Builder setVersion(final Integer setVersion) {
      this.setVersion = setVersion;
      return this;
    }

    public Builder ok(final boolean ok) {
      this.ok = ok;
      return this;
    }

    public Builder state(final ServerConnectionState state) {
      this.state = state;
      return this;
    }

    public Builder version(final ServerVersion version) {
      notNull("version", version);
      this.version = version;
      return this;
    }

    public Builder minWireVersion(final int minWireVersion) {
      this.minWireVersion = minWireVersion;
      return this;
    }

    public Builder maxWireVersion(final int maxWireVersion) {
      this.maxWireVersion = maxWireVersion;
      return this;
    }

    public ServerDescription build() {
      return new ServerDescription(this);
    }
    // CHECKSTYLE:ON
  }
 public Builder tags(final Tags tags) {
   this.tags = tags == null ? Tags.freeze(new Tags()) : Tags.freeze(tags);
   return this;
 }