public int compare(Object extEndpoint1, Object extEndpoint2) {
      ExtendedEndpoint a = (ExtendedEndpoint) extEndpoint1;
      ExtendedEndpoint b = (ExtendedEndpoint) extEndpoint2;

      int ret = a.connectScore() - b.connectScore();
      if (ret != 0) return ret;

      ret = a.localeScore() - b.localeScore();
      if (ret != 0) return ret;

      return a.getDailyUptime() - b.getDailyUptime();
    }
  /**
   * Parses a new ExtendedEndpoint. Strictly validates all data. For example, addresses MUST be in
   * dotted quad format.
   *
   * @param line a single line read from the stream
   * @return the endpoint constructed from the line
   * @exception IOException problem reading from in, e.g., EOF reached prematurely
   * @exception ParseException data not in proper format. Does NOT necessarily set the offset of the
   *     exception properly.
   * @see write
   */
  public static ExtendedEndpoint read(String line) throws ParseException {
    // Break the line into fields.  Skip if badly formatted.  Note that
    // subsequent delimiters are NOT coalesced.
    String[] linea = StringUtils.splitNoCoalesce(line, FIELD_SEPARATOR);
    if (linea.length == 0) throw new ParseException("Empty line", 0);

    // 1. Host and port.  As a dirty trick, we use existing code in Endpoint.
    // Note that we strictly validate the address to work around corrupted
    // gnutella.net files from an earlier version
    boolean pureNumeric;

    String host;
    int port;
    try {
      Endpoint tmp = new Endpoint(linea[0], true); // require numeric.
      host = tmp.getAddress();
      port = tmp.getPort();
      pureNumeric = true;
    } catch (IllegalArgumentException e) {
      // Alright, pure numeric failed -- let's try constructing without
      // numeric & without requiring a DNS lookup.
      try {
        Endpoint tmp = new Endpoint(linea[0], false, false);
        host = tmp.getAddress();
        port = tmp.getPort();
        pureNumeric = false;
      } catch (IllegalArgumentException e2) {
        ParseException e3 =
            new ParseException("Couldn't extract address and port from: " + linea[0], 0);
        e3.initCause(e2);
        throw e3;
      }
    }

    // Build endpoint without any optional data.  (We'll set it if possible
    // later.)
    ExtendedEndpoint ret = new ExtendedEndpoint(host, port, false);

    // 2. Average uptime (optional)
    if (linea.length >= 2) {
      try {
        ret.dailyUptime = Integer.parseInt(linea[1].trim());
      } catch (NumberFormatException e) {
      }
    }

    // 3. Time of pong (optional).  Do NOT use current system tome
    //   if not set.
    ret.timeRecorded = DEFAULT_TIME_RECORDED;
    if (linea.length >= 3) {
      try {
        ret.timeRecorded = Long.parseLong(linea[2].trim());
      } catch (NumberFormatException e) {
      }
    }

    // 4. Time of successful connects (optional)
    if (linea.length >= 4) {
      try {
        String times[] = StringUtils.split(linea[3], LIST_SEPARATOR);
        for (int i = times.length - 1; i >= 0; i--)
          ret.recordConnectionAttempt(ret.connectSuccesses, Long.parseLong(times[i].trim()));
      } catch (NumberFormatException e) {
      }
    }

    // 5. Time of failed connects (optional)
    if (linea.length >= 5) {
      try {
        String times[] = StringUtils.split(linea[4], LIST_SEPARATOR);
        for (int i = times.length - 1; i >= 0; i--)
          ret.recordConnectionAttempt(ret.connectFailures, Long.parseLong(times[i].trim()));
      } catch (NumberFormatException e) {
      }
    }

    // 6. locale of the connection (optional)
    if (linea.length >= 6) {
      ret.setClientLocale(linea[5]);
    }

    // 7. udp-host
    if (linea.length >= 7) {
      try {
        int i = Integer.parseInt(linea[6]);
        if (i >= 0) ret.udpHostCacheFailures = i;
      } catch (NumberFormatException nfe) {
      }
    }

    // validate address if numeric.
    if (pureNumeric && !NetworkUtils.isValidAddress(host))
      throw new ParseException("invalid dotted addr: " + ret, 0);

    // validate that non UHC addresses were numeric.
    if (!ret.isUDPHostCache() && !pureNumeric)
      throw new ParseException("illegal non-UHC endpoint: " + ret, 0);

    return ret;
  }