// Forward an incoming packet to the corresponding source
  private void forwardPacket(GnutellaPacket pkt) {
    GnutellaConnection gc;
    gc = (GnutellaConnection) packetTable.get(pkt.getGUID());
    if (gc == null) {
      if (VERBOSE) System.err.println("-- Received reply with no request: " + pkt);
      return;
    }

    if (DEBUG) System.err.println("**** REPLYING: " + pkt + " to " + gc);

    if ((pkt.ttl == 0) || (--pkt.ttl == 0)) {
      if (VERBOSE) System.err.println("-- Dropping packet, TTL expired: " + pkt);
    }
    pkt.hops++;
    gc.enqueue_lossy(pkt);
  }
  /** The main event handling code. */
  public void handleEvent(QueueElementIF item) {

    try {
      if (DEBUG) System.err.println("**** GOT: " + item);

      if (item instanceof GnutellaPingPacket) {
        GnutellaPingPacket ping = (GnutellaPingPacket) item;
        if (VERBOSE) System.err.println("-- Got ping: " + ping);

        if (ROUTE_PACKETS) {
          if (rememberPacket(ping)) {
            forwardPacketToAll(ping);
          }
        }

        if (SEND_PONGS) {
          GnutellaPongPacket pong = new GnutellaPongPacket(ping.getGUID(), NUM_FILES, NUM_KB);
          if (VERBOSE) System.err.println("-- Sending pong to: " + ping.getConnection());
          ping.getConnection().enqueue_lossy(pong);
        }

      } else if (item instanceof GnutellaQueryPacket) {
        GnutellaQueryPacket query = (GnutellaQueryPacket) item;
        if (VERBOSE) System.err.println("-- Got query: " + query.getSearchTerm());

        if (ROUTE_PACKETS) {
          if (rememberPacket(query)) {
            forwardPacketToAll(query);
          }
        }

      } else if (item instanceof GnutellaPongPacket) {
        GnutellaPongPacket pong = (GnutellaPongPacket) item;
        if (VERBOSE) System.err.println("-- Got pong: " + pong);
        if (ROUTE_PACKETS) forwardPacket(pong);

      } else if (item instanceof GnutellaQueryHitsPacket) {
        GnutellaQueryHitsPacket hits = (GnutellaQueryHitsPacket) item;
        if (VERBOSE) System.err.println("-- Got hits: " + hits);
        if (ROUTE_PACKETS) forwardPacket(hits);

      } else if (item instanceof GnutellaPushPacket) {
        if (VERBOSE) System.err.println("-- Dropping push packet (unimplemented)");

      } else if (item instanceof GnutellaConnection) {
        if (VERBOSE) System.err.println("-- New connection: " + item);
        num_connections++;

      } else if (item instanceof SinkClosedEvent) {
        if (VERBOSE) System.err.println("-- Connection closed: " + item);
        num_connections--;
        SinkClosedEvent sce = (SinkClosedEvent) item;

        if ((num_connections <= MIN_CONNECTIONS) && DO_CATCHER) doCatcher();

      } else if (item instanceof SinkCloggedEvent) {
        if (VERBOSE) System.err.println("-- Connection clogged: " + item);
        SinkCloggedEvent clogged = (SinkCloggedEvent) item;
        // Close down clogged connections
        GnutellaConnection gc = (GnutellaConnection) clogged.sink;
        System.err.println("GL: Closing clogged connection " + gc);
        gc.close(mySink);

      } else if (item instanceof timerEvent) {
        doTimer((timerEvent) item);
      }

    } catch (Exception e) {
      System.err.println("WORKER GOT EXCEPTION: " + e.getMessage());
      e.printStackTrace();
    }
  }