/*
  * Receive an exception.  If the resolution has been completed,
  * do nothing.  Otherwise make progress.
  */
 public void handleException(Object id, Exception e) {
   if (Options.check("verbose")) System.err.println("ExtendedResolver: got " + e);
   synchronized (this) {
     outstanding--;
     if (done) return;
     int n;
     for (n = 0; n < inprogress.length; n++) if (inprogress[n] == id) break;
     /* If we don't know what this is, do nothing. */
     if (n == inprogress.length) return;
     boolean startnext = false;
     boolean waiting = false;
     /*
      * If this is the first response from server n,
      * we should start sending queries to server n + 1.
      */
     if (sent[n] == 1 && n < resolvers.length - 1) startnext = true;
     if (e instanceof InterruptedIOException) {
       /* Got a timeout; resend */
       if (sent[n] < retries) send(n);
       if (thrown == null) thrown = e;
     } else if (e instanceof SocketException) {
       /*
        * Problem with the socket; don't resend
        * on it
        */
       if (thrown == null || thrown instanceof InterruptedIOException) thrown = e;
     } else {
       /*
        * Problem with the response; don't resend
        * on the same socket.
        */
       thrown = e;
     }
     if (done) return;
     if (startnext) send(n + 1);
     if (done) return;
     if (outstanding == 0) {
       /*
        * If we're done and this is synchronous,
        * wake up the blocking thread.
        */
       done = true;
       if (listener == null) {
         notifyAll();
         return;
       }
     }
     if (!done) return;
   }
   /* If we're done and this is asynchronous, call the callback. */
   if (!(thrown instanceof Exception)) thrown = new RuntimeException(thrown.getMessage());
   listener.handleException(this, (Exception) thrown);
 }
 /*
  * Receive a response.  If the resolution hasn't been completed,
  * either wake up the blocking thread or call the callback.
  */
 public void receiveMessage(Object id, Message m) {
   if (Options.check("verbose")) System.err.println("ExtendedResolver: " + "received message");
   synchronized (this) {
     if (done) return;
     response = m;
     done = true;
     if (listener == null) {
       notifyAll();
       return;
     }
   }
   listener.receiveMessage(this, response);
 }