protected AbstractMessage waitForProcessingGetReply(AbstractMessage incomingMessage)
      throws InterruptedException {
    // waits for message to be processed
    synchronized (incomingMessage) {
      while (!incomingMessage.isProcessed()) {
        logger.debug("waiting on: " + incomingMessage);
        incomingMessage.wait();
      }
    }
    if (logger.isDebugEnabled()) {
      logger.debug("done waiting on: " + incomingMessage);
    }
    AbstractMessage replyMessage = incomingMessage.getReplyMessage();

    if (logger.isDebugEnabled()) {
      if (replyMessage == null) {
        logger.debug("will reply NULL to " + incomingMessage);
      } else {
        logger.debug("will reply: " + replyMessage + " to " + incomingMessage);
      }
    }
    return replyMessage;
  }
  protected void processMessage(AbstractMessage incomingMessage) {

    if (incomingMessage.isProcessed()
        && !(incomingMessage instanceof HaveMessage
            || incomingMessage instanceof BlockReplyMessage)) return;

    AbstractMessage replyMessage = null;

    // USM
    if (incomingMessage instanceof SubscribeMessage) {
      replyMessage = this.handleSubscribe((SubscribeMessage) incomingMessage);
    } else if (incomingMessage instanceof InterestedMessage) {
      replyMessage = this.handleInterested((InterestedMessage) incomingMessage);
    } else if (incomingMessage instanceof DisconnectMessage) {
      DisconnectMessage disconnectMessage = (DisconnectMessage) incomingMessage;
      if (disconnectMessage.stopUploading()) this.handleDisconnect(disconnectMessage);
      // TUNER

      if (disconnectMessage.stopDownloading()) this.handleDisconnect(disconnectMessage);
    } else if (incomingMessage instanceof HaveMessage) {
      this.handleHave((HaveMessage) incomingMessage);
    } else if (incomingMessage instanceof SubscribedMessage) {
      this.handleSubscribed((SubscribedMessage) incomingMessage);
    } else if (incomingMessage instanceof QueuedMessage) {
      this.handleQueued((QueuedMessage) incomingMessage);
    } else if (incomingMessage instanceof GrantedMessage) {
      this.handleGranted((GrantedMessage) incomingMessage);
    } else if (incomingMessage instanceof BlockReplyMessage) {
      this.handleBlockReply((BlockReplyMessage) incomingMessage);
    } else if (incomingMessage instanceof PeerSuggestionMessage) {
      this.handlePeerSuggestion((PeerSuggestionMessage) incomingMessage);
    } else {
      logger.warn("Unknown message received, not processing (" + incomingMessage + ")");
    }

    incomingMessage.setReplyMessage(replyMessage, incomingMessage.getSender());
  }