public int enqueue(int messageNo, IMessage message, MessageFuture future) throws IOException {
   QueueEntry qe = new QueueEntry();
   qe.messageNo = messageNo;
   qe.score = computeMessageScore(messageNo, message);
   qe.messageClass = message.getClass();
   qe.messageStream = messenger.serializeMessage(message);
   qe.future = future;
   if (LogUtil.isLogAvailable()) {
     // precompute the expected queue size...this is because the writer thread may quickly pick
     // up the queue item which, while swell, means the debug output may be confusing
     int newExpectedQueueSize = queue.size() + 1;
     Log.i(
         TAG,
         "Message "
             + qe.messageNo
             + " enqueued, it's a "
             + qe.messageClass.getSimpleName()
             + ", "
             + qe.messageStream.available()
             + " bytes in length, "
             + newExpectedQueueSize
             + " entries in the queue");
   }
   queue.add(qe);
   return qe.messageNo;
 }
 private void processCanceled() throws IOException {
   Set<Integer> canceled = new HashSet<Integer>();
   synchronized (queueLock) {
     canceled.addAll(this.canceled);
     this.canceled.clear();
   }
   for (int messageNo : canceled) {
     QueueEntry found = removeQueueEntry(messageNo);
     if (found != null) {
       if (LogUtil.isLogAvailable()) {
         Log.d(TAG, "Message " + messageNo + " canceled");
       }
       PacketFormat cancelPacket = new PacketFormat(messageNo, new byte[0]);
       cancelPacket.addControlCode(ControlCode.Cancelled);
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       cancelPacket.serialize(baos);
       found.messageStream = new ByteArrayInputStream(baos.toByteArray());
       found.score = messageNo * CANCEL_TRANSFER_SCORE_MULTIPLIER;
       queue.add(found);
     }
   }
 }