/*
   * (non-Javadoc)
   *
   * @see org.mpilone.hazelcastmq.core.HazelcastMQConsumer#receiveBody(long,
   * java.util.concurrent.TimeUnit)
   */
  @Override
  public byte[] receiveBody(long timeout, TimeUnit unit) {
    HazelcastMQMessage msg = receive(timeout, unit);

    if (msg != null) {
      return msg.getBody();
    } else {
      return null;
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see org.mpilone.hazelcastmq.core.HazelcastMQConsumer#receiveBodyNoWait()
   */
  @Override
  public byte[] receiveBodyNoWait() {
    HazelcastMQMessage msg = receiveNoWait();

    if (msg != null) {
      return msg.getBody();
    } else {
      return null;
    }
  }
  /**
   * Attempts to receive a message using the given strategy. The method will continue to attempt to
   * receive until either {@link ReceiveStrategy#isRetryable()} returns false, a message is
   * received, or the consumer is stopped.
   *
   * @param strategy the strategy to use for receiving the message and determining retries
   * @return the message or null if no message was received
   */
  private HazelcastMQMessage doReceive(ReceiveStrategy strategy) {

    HazelcastMQMessage msg = null;

    do {
      receiveLock.lock();
      try {

        IQueue<byte[]> queue = hazelcastMQContext.resolveQueue(destination);

        if (queue == null && topicListener == null) {
          throw new HazelcastMQException(
              format("Destination cannot be resolved [%s].", destination));
        } else if (queue == null) {
          queue = topicListener.getQueue();
        }

        byte[] msgData = strategy.receive(queue);
        if (msgData != null) {
          msg = config.getMessageConverter().toMessage(msgData);
        }

        // Check for message expiration if we have a message with expiration
        // time.
        if (msg != null && msg.getHeaders().get(Headers.EXPIRATION) != null) {
          long expirationTime = Long.parseLong(msg.getHeaders().get(Headers.EXPIRATION));

          if (expirationTime != 0 && expirationTime <= System.currentTimeMillis()) {
            log.info("Dropping message [{}] because it has expired.", msg.getId());
            msg = null;
          }
        }
      } finally {
        receiveLock.unlock();
      }
    } while (msg == null && !closed && strategy.isRetryable());

    return msg;
  }