protected void sendResult() {
      if (active && results.size() > 0) {

        DHTSpeedTesterContact[] contacts = new DHTSpeedTesterContact[results.size()];
        int[] rtts = new int[contacts.length];

        for (int i = 0; i < contacts.length; i++) {

          pingInstance pi = (pingInstance) results.get(i);

          contacts[i] = pi.getContact();
          rtts[i] = pi.getResult();
        }

        DHTSpeedTesterImpl.this.informResults(contacts, rtts);
      }
    }
    protected void ping(pingInstanceSet ping_set, DHTTransportContact contact) {
      final pingInstance pi = new pingInstance(ping_set);

      outstanding++;

      try {
        contact.sendImmediatePing(
            new DHTTransportReplyHandlerAdapter() {
              public void pingReply(DHTTransportContact contact) {
                int rtt = getElapsed();

                try {
                  synchronized (activePing.this) {
                    outstanding--;

                    if (!running) {

                      if (rtt < best_ping) {

                        best_pingee = contact;
                        best_ping = rtt;
                      }

                      if (outstanding == 0) {

                        running = true;
                      }
                    } else {

                      total_ok++;

                      consec_fails = 0;
                    }
                  }

                  Iterator it = listeners.iterator();

                  while (it.hasNext()) {

                    try {
                      ((DHTSpeedTesterContactListener) it.next())
                          .ping(activePing.this, getElapsed());

                    } catch (Throwable e) {

                      Debug.printStackTrace(e);
                    }
                  }
                } finally {

                  pi.setResult(activePing.this, rtt);
                }
                // System.out.println( "    " + contact.getString() + ": " + getElapsed() + ", " +
                // contact.getVivaldiPosition().estimateRTT(
                // dht.getTransport().getLocalContact().getVivaldiPosition().getCoordinates()));
              }

              public void failed(DHTTransportContact contact, Throwable error) {
                try {
                  synchronized (activePing.this) {
                    outstanding--;

                    if (!running) {

                      if (outstanding == 0) {

                        running = true;
                      }
                    } else {

                      consec_fails++;
                      total_fails++;

                      if (consec_fails == 3) {

                        dead = true;

                      } else if (total_ok > 10 && total_fails > 0 && total_ok / total_fails < 1) {

                        // failing too often

                        dead = true;

                      } else if (total_ok > 100) {

                        total_ok = 0;
                        total_fails = 0;
                      }
                    }
                  }

                  if (!dead) {

                    Iterator it = listeners.iterator();

                    while (it.hasNext()) {

                      try {
                        ((DHTSpeedTesterContactListener) it.next()).pingFailed(activePing.this);

                      } catch (Throwable e) {

                        Debug.printStackTrace(e);
                      }
                    }
                  }
                  // System.out.println( "    " + contact.getString() + ": failed" );
                } finally {

                  pi.setResult(activePing.this, -1);
                }
              }
            },
            PING_TIMEOUT);

      } catch (Throwable e) {

        pi.setResult(this, -1);

        dead = true;

        outstanding--;

        Debug.printStackTrace(e);
      }
    }