@Override
  public PollableSource.Status process() throws EventDeliveryException {
    if (null == _Connection) {
      try {
        if (log.isInfoEnabled())
          log.info(
              this.getName()
                  + " - Opening connection to "
                  + _ConnectionFactory.getHost()
                  + ":"
                  + _ConnectionFactory.getPort());
        _Connection = _ConnectionFactory.newConnection();
        _CounterGroup.incrementAndGet(RabbitMQConstants.COUNTER_NEW_CONNECTION);
        _Channel = null;
      } catch (Exception ex) {
        if (log.isErrorEnabled())
          log.error(this.getName() + " - Exception while establishing connection.", ex);
        resetConnection();
        return Status.BACKOFF;
      }
    }

    if (null == _Channel) {
      try {
        if (log.isInfoEnabled()) log.info(this.getName() + " - creating channel...");
        _Channel = _Connection.createChannel();
        _CounterGroup.incrementAndGet(RabbitMQConstants.COUNTER_NEW_CHANNEL);
        if (log.isInfoEnabled())
          log.info(
              this.getName()
                  + " - Connected to "
                  + _ConnectionFactory.getHost()
                  + ":"
                  + _ConnectionFactory.getPort());

        if (StringUtils.isNotEmpty(_ExchangeName)) {
          try {
            // declare an exchange
            _Channel.exchangeDeclarePassive(_ExchangeName);

            // only grab a default queuename if one is not specified in config
            if (StringUtils.isEmpty(_QueueName)) {
              _QueueName = _Channel.queueDeclare().getQueue();
            }

            // for each topic, bind to the key
            if (null != _Topics) {
              for (String topic : _Topics) {
                _Channel.queueBind(_QueueName, _ExchangeName, topic);
              }
            }
          } catch (Exception ex) {
            if (log.isErrorEnabled())
              log.error(this.getName() + " - Exception while declaring exchange.", ex);
            resetConnection();
            return Status.BACKOFF;
          }
        }
      } catch (Exception ex) {
        if (log.isErrorEnabled())
          log.error(this.getName() + " - Exception while creating channel.", ex);
        resetConnection();
        return Status.BACKOFF;
      }
    }

    GetResponse response;

    try {
      response = _Channel.basicGet(_QueueName, false);
      _CounterGroup.incrementAndGet(RabbitMQConstants.COUNTER_GET);
    } catch (Exception ex) {
      _CounterGroup.incrementAndGet(RabbitMQConstants.COUNTER_EXCEPTION);
      if (log.isErrorEnabled())
        log.error(this.getName() + " - Exception thrown while pulling from queue.", ex);
      resetConnection();
      return Status.BACKOFF;
    }

    if (null == response) {
      _CounterGroup.incrementAndGet(RabbitMQConstants.COUNTER_GET_MISS);
      return Status.BACKOFF;
    }

    try {
      Map<String, String> properties = RabbitMQUtil.getHeaders(response.getProps());

      Event event = new SimpleEvent();
      event.setBody(response.getBody());
      event.setHeaders(properties);

      getChannelProcessor().processEvent(event);
    } catch (Exception ex) {
      if (log.isErrorEnabled())
        log.error(this.getName() + " - Exception thrown while processing event", ex);

      return Status.BACKOFF;
    }

    try {
      _Channel.basicAck(response.getEnvelope().getDeliveryTag(), false);
      _CounterGroup.incrementAndGet(RabbitMQConstants.COUNTER_ACK);
    } catch (Exception ex) {
      _CounterGroup.incrementAndGet(RabbitMQConstants.COUNTER_EXCEPTION);
      if (log.isErrorEnabled())
        log.error(this.getName() + " - Exception thrown while sending ack to queue", ex);
      resetConnection();
      return Status.BACKOFF;
    }

    return Status.READY;
  }