protected AbstractMessage handleInterested(final InterestedMessage incomingMessage) {

    if (logger.isDebugEnabled()) logger.debug("processing message:" + incomingMessage.toString());

    Subscriber subscriber;
    if (null
        != (subscriber =
            this.videoSignaling
                .getUploadSlotManager()
                .getGrantedUploadSlotRequest(
                    incomingMessage.getSender(), incomingMessage.getSegmentIdentifier()))) {
      logger.warn(subscriber + " is already granted!!");
      return this.videoSignaling.getGranted(
          incomingMessage.getSegmentIdentifier(),
          subscriber.getTimeToTimeoutMillis(),
          UploadSlot.INACTIVITY_TIMEOUT_S * 1000,
          incomingMessage.getSender(),
          false);
    }

    int timeoutMillis =
        this.videoSignaling
            .getUploadSlotManager()
            .setInterestedGetTimeout(
                incomingMessage.getSender(),
                incomingMessage.getSegmentIdentifier(),
                !incomingMessage.isNot());

    if (incomingMessage.isNot()) {
      // if not interested, should return subscribed
      return this.videoSignaling.getSubscribed(
          incomingMessage.getSegmentIdentifier(),
          null,
          timeoutMillis,
          incomingMessage.getSender(),
          false);
    } else {
      // must return Queued with new (extended) timeout.. and synchronize with the possible Granted
      return this.videoSignaling.getQueued(
          incomingMessage.getSegmentIdentifier(),
          timeoutMillis,
          incomingMessage.getSender(),
          false);
    }
  }
  protected AbstractMessage handleSubscribe(final SubscribeMessage incomingMessage) {

    if (logger.isDebugEnabled()) logger.debug("processing message:" + incomingMessage.toString());

    SegmentIdentifier segmentIdentifier = incomingMessage.getSegmentIdentifier();
    Segment segment = this.tuner.getSegmentStorage().getSegment(segmentIdentifier);

    if (segment == null) {
      logger.warn("USRM:" + incomingMessage.toString() + " asks for unknown segment.");
      return this.videoSignaling.getSubscribed(
          segmentIdentifier, null, 0, incomingMessage.getSender(), false);
    }

    AtomicBoolean peerLock;
    synchronized (this.peerLocks) {
      peerLock = this.peerLocks.get(incomingMessage.getSender());
      if (peerLock == null) {
        this.peerLocks.put(incomingMessage.getSender(), peerLock = new AtomicBoolean(false));
      }
    }
    Subscriber subscriber =
        new Subscriber(
            incomingMessage.getSender(),
            segmentIdentifier,
            segment,
            this.videoSignaling.getUploadSlotManager(),
            peerLock);

    // lets the tuner know: it may be a new interesting neighbor
    this.tuner
        .getNeighborList()
        .addPotentialCandidate(segmentIdentifier, incomingMessage.getSender());

    // checks if already granted
    int timeoutMillis =
        this.videoSignaling.getUploadSlotManager().getUploadSlotTimeoutMillis(subscriber);

    boolean isAlreadyGranted = timeoutMillis > 0;

    if (isAlreadyGranted)
      logger.warn(
          "USR:"******" has already an upload slot! the other peer could have a bug (requesting again when it's not supposed to). But it could also that a message got lost, or the peer failed and came back.");

    // if not, tries to add to queue and gets timeout
    if (!isAlreadyGranted)
      timeoutMillis =
          this.videoSignaling.getUploadSlotManager().addSubscriberGetTimeoutMillis(subscriber);

    if (logger.isDebugEnabled())
      logger.debug(
          "addUploadSlotRequest ["
              + subscriber
              + "] returned ["
              + timeoutMillis
              + ","
              + isAlreadyGranted
              + "]");

    if (isAlreadyGranted)
      return this.videoSignaling.getGranted(
          segmentIdentifier,
          timeoutMillis,
          UploadSlot.INACTIVITY_TIMEOUT_S * 1000,
          incomingMessage.getSender(),
          false);
    else if (timeoutMillis > 0) {
      // replies with the timeout, so the other peer knows when to send another request
      SegmentBlockMap segmentBlockMap = this.tuner.getSegmentBlockMap(segmentIdentifier);

      return this.videoSignaling.getSubscribed(
          segmentIdentifier, segmentBlockMap, timeoutMillis, incomingMessage.getSender(), false);
    } else {
      // queue is full or something like that
      return this.videoSignaling.getSubscribed(
          segmentIdentifier, null, 0, incomingMessage.getSender(), true);
    }
  }