/**
   * Get a list of piece numbers being requested
   *
   * @return list of Long values
   */
  public int[] getRequestedPieceNumbers() {
    if (destroyed) return new int[0];

    /** Cheap hack to reduce (but not remove all) the # of duplicate entries */
    int iLastNumber = -1;
    int pos = 0;
    int[] pieceNumbers;

    try {
      lock_mon.enter();

      // allocate max size needed (we'll shrink it later)
      pieceNumbers = new int[queued_messages.size() + loading_messages.size() + requests.size()];

      for (Iterator iter = queued_messages.keySet().iterator(); iter.hasNext(); ) {
        BTPiece msg = (BTPiece) iter.next();
        if (iLastNumber != msg.getPieceNumber()) {
          iLastNumber = msg.getPieceNumber();
          pieceNumbers[pos++] = iLastNumber;
        }
      }

      for (Iterator iter = loading_messages.iterator(); iter.hasNext(); ) {
        DiskManagerReadRequest dmr = (DiskManagerReadRequest) iter.next();
        if (iLastNumber != dmr.getPieceNumber()) {
          iLastNumber = dmr.getPieceNumber();
          pieceNumbers[pos++] = iLastNumber;
        }
      }

      for (Iterator iter = requests.iterator(); iter.hasNext(); ) {
        DiskManagerReadRequest dmr = (DiskManagerReadRequest) iter.next();
        if (iLastNumber != dmr.getPieceNumber()) {
          iLastNumber = dmr.getPieceNumber();
          pieceNumbers[pos++] = iLastNumber;
        }
      }

    } finally {
      lock_mon.exit();
    }

    int[] trimmed = new int[pos];
    System.arraycopy(pieceNumbers, 0, trimmed, 0, pos);

    return trimmed;
  }
  /** Remove all outstanding piece data requests. */
  public void removeAllPieceRequests() {
    if (destroyed) return;

    try {
      lock_mon.enter();

      // removed this trace as Alon can't remember why the trace is here anyway and as far as I can
      // see there's nothing to stop a piece being delivered to transport and removed from
      // the message queue before we're notified of this and thus it is entirely possible that
      // our view of queued messages is lagging.
      // String before_trace = outgoing_message_queue.getQueueTrace();
      /*
      int num_queued = queued_messages.size();
      int num_removed = 0;

      for( Iterator i = queued_messages.keySet().iterator(); i.hasNext(); ) {
        BTPiece msg = (BTPiece)i.next();
        if( outgoing_message_queue.removeMessage( msg, true ) ) {
          i.remove();
          num_removed++;
        }
      }

      if( num_removed < num_queued -2 ) {
        Debug.out( "num_removed[" +num_removed+ "] < num_queued[" +num_queued+ "]:\nBEFORE:\n" +before_trace+ "\nAFTER:\n" +outgoing_message_queue.getQueueTrace() );
      }
      */

      for (Iterator i = queued_messages.keySet().iterator(); i.hasNext(); ) {
        BTPiece msg = (BTPiece) i.next();
        outgoing_message_queue.removeMessage(msg, true);
      }

      queued_messages.clear(); // this replaces stuff above
      requests.clear();
      loading_messages.clear();
    } finally {
      lock_mon.exit();
    }

    outgoing_message_queue.doListenerNotifications();
  }