public HandleStatus handle(final MessageReference ref) throws Exception {
    if (availableCredits != null && availableCredits.get() <= 0) {
      if (HornetQServerLogger.LOGGER.isDebugEnabled()) {
        HornetQServerLogger.LOGGER.debug(
            this
                + " is busy for the lack of credits. Current credits = "
                + availableCredits
                + " Can't receive reference "
                + ref);
      }

      return HandleStatus.BUSY;
    }

    // TODO - https://jira.jboss.org/browse/HORNETQ-533
    // if (!writeReady.get())
    // {
    // return HandleStatus.BUSY;
    // }

    synchronized (lock) {
      // If the consumer is stopped then we don't accept the message, it
      // should go back into the
      // queue for delivery later.
      if (!started || transferring) {
        return HandleStatus.BUSY;
      }

      // If there is a pendingLargeMessage we can't take another message
      // This has to be checked inside the lock as the set to null is done inside the lock
      if (largeMessageDeliverer != null) {
        if (HornetQServerLogger.LOGGER.isDebugEnabled()) {
          HornetQServerLogger.LOGGER.debug(
              this
                  + " is busy delivering large message "
                  + largeMessageDeliverer
                  + ", can't deliver reference "
                  + ref);
        }
        return HandleStatus.BUSY;
      }
      final ServerMessage message = ref.getMessage();

      if (filter != null && !filter.match(message)) {
        if (HornetQServerLogger.LOGGER.isTraceEnabled()) {
          HornetQServerLogger.LOGGER.trace(
              "Reference " + ref + " is a noMatch on consumer " + this);
        }
        return HandleStatus.NO_MATCH;
      }

      if (HornetQServerLogger.LOGGER.isTraceEnabled()) {
        HornetQServerLogger.LOGGER.trace("Handling reference " + ref);
      }

      if (!browseOnly) {
        if (!preAcknowledge) {
          deliveringRefs.add(ref);
        }

        ref.handled();

        ref.incrementDeliveryCount();

        // If updateDeliveries = false (set by strict-update),
        // the updateDeliveryCount would still be updated after c
        if (strictUpdateDeliveryCount && !ref.isPaged()) {
          if (ref.getMessage().isDurable()
              && ref.getQueue().isDurable()
              && !ref.getQueue().isInternalQueue()
              && !ref.isPaged()) {
            storageManager.updateDeliveryCount(ref);
          }
        }

        if (preAcknowledge) {
          if (message.isLargeMessage()) {
            // we must hold one reference, or the file will be deleted before it could be delivered
            ((LargeServerMessage) message).incrementDelayDeletionCount();
          }

          // With pre-ack, we ack *before* sending to the client
          ref.getQueue().acknowledge(ref);
        }
      }

      if (message.isLargeMessage()) {
        largeMessageDeliverer = new LargeMessageDeliverer((LargeServerMessage) message, ref);
      }

      lockDelivery.readLock().lock();

      return HandleStatus.HANDLED;
    }
  }