/**
   * Returns true if this instance is equals to @code{o}. Note that equality is defined to NOT
   * include the round trip time.
   *
   * @param o the object to compare to
   * @return true if this instance is equals to @code{o}
   */
  @Override
  public boolean equals(final Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }

    ServerDescription that = (ServerDescription) o;

    if (maxDocumentSize != that.maxDocumentSize) {
      return false;
    }
    if (ok != that.ok) {
      return false;
    }
    if (!address.equals(that.address)) {
      return false;
    }
    if (!arbiters.equals(that.arbiters)) {
      return false;
    }
    if (canonicalAddress != null
        ? !canonicalAddress.equals(that.canonicalAddress)
        : that.canonicalAddress != null) {
      return false;
    }
    if (!hosts.equals(that.hosts)) {
      return false;
    }
    if (!passives.equals(that.passives)) {
      return false;
    }
    if (primary != null ? !primary.equals(that.primary) : that.primary != null) {
      return false;
    }
    if (setName != null ? !setName.equals(that.setName) : that.setName != null) {
      return false;
    }
    if (state != that.state) {
      return false;
    }
    if (!tagSet.equals(that.tagSet)) {
      return false;
    }
    if (type != that.type) {
      return false;
    }
    if (!version.equals(that.version)) {
      return false;
    }
    if (minWireVersion != that.minWireVersion) {
      return false;
    }
    if (maxWireVersion != that.maxWireVersion) {
      return false;
    }
    if (electionId != null ? !electionId.equals(that.electionId) : that.electionId != null) {
      return false;
    }
    if (setVersion != null ? !setVersion.equals(that.setVersion) : that.setVersion != null) {
      return false;
    }

    // Compare class equality and message as exceptions rarely override equals
    Class<?> thisExceptionClass = exception != null ? exception.getClass() : null;
    Class<?> thatExceptionClass = that.exception != null ? that.exception.getClass() : null;
    if (thisExceptionClass != null
        ? !thisExceptionClass.equals(thatExceptionClass)
        : thatExceptionClass != null) {
      return false;
    }

    String thisExceptionMessage = exception != null ? exception.getMessage() : null;
    String thatExceptionMessage = that.exception != null ? that.exception.getMessage() : null;
    if (thisExceptionMessage != null
        ? !thisExceptionMessage.equals(thatExceptionMessage)
        : thatExceptionMessage != null) {
      return false;
    }

    return true;
  }