public void handleEvent(QueueElementIF elem) {
    logger.debug("Got event " + elem);

    // If startup
    if (!initialized) {
      // This one is sent when setting up
      if (elem instanceof StagesInitializedSignal) {
        // Request registration for this app
        dispatch(new BambooRouterAppRegReq(app_id, false, false, false, my_sink));
      }
      // OK, we are now registered to Bamboo
      else if (elem instanceof BambooRouterAppRegResp) {
        // handle pending events
        initialized = true;
        while (!wait_q.isEmpty()) handleEvent((QueueElementIF) wait_q.removeFirst());

        // Dispatch in 10s a Alarm msg to stages on this node
        if (sender) classifier.dispatch_later(new Alarm(), 10000);
      }
      // For pending events before we are registered
      else wait_q.addLast(elem);
    }
    // Normal opertional mode
    else {
      // Event that we got a message delivered
      if (elem instanceof BambooRouteDeliver) {
        BambooRouteDeliver deliver = (BambooRouteDeliver) elem;
        Payload pay = (Payload) deliver.payload;
        logger.info("Message is: " + pay.toString());
      } else if (elem instanceof Alarm) {
        // Create a new message to be send over bamboo, only
        // stages with the same app_id will get this message!
        String msg =
            "This message should be send over" + "Bamboo to the node with the smallest node ID.";
        BambooRouteInit init =
            new BambooRouteInit(BigInteger.ZERO, app_id, false, false, new Payload(msg));
        // Send the message to the sink.
        dispatch(init);

        // Dispatch in 10s a new Alarm msg to the stages on this node
        classifier.dispatch_later(new Alarm(), 10000);
      } else {
        BUG("Event " + elem + " unknown.");
      }
    }
  }
    public void run() {
      try {
        synchronized (this) {
          if (appContext == null) {
            return;
          }
          PayloadStore db = getPayloadStore(appContext);
          while (true) {
            if (GlobalInfo.conversationToken == null || GlobalInfo.conversationToken.equals("")) {
              pause(NO_TOKEN_SLEEP);
              continue;
            }
            Payload payload;
            payload = db.getOldestUnsentPayload();
            if (payload == null) {
              // There is no payload in the db.
              pause(EMPTY_QUEUE_SLEEP_TIME);
              continue;
            }
            Log.d("Got a payload to send: %s:%d", payload.getBaseType(), payload.getDatabaseId());

            ApptentiveHttpResponse response = null;

            switch (payload.getBaseType()) {
              case message:
                response = ApptentiveClient.postMessage(appContext, (Message) payload);
                MessageManager.onSentMessage(appContext, (Message) payload, response);
                break;
              case event:
                response = ApptentiveClient.postEvent((Event) payload);
                break;
              case device:
                response = ApptentiveClient.putDevice((Device) payload);
                break;
              case sdk:
                response = ApptentiveClient.putSdk((Sdk) payload);
                break;
              case app_release:
                response = ApptentiveClient.putAppRelease((AppRelease) payload);
                break;
              case person:
                response = ApptentiveClient.putPerson((Person) payload);
                break;
              case survey:
                response = ApptentiveClient.postSurvey((SurveyPayload) payload);
                break;
              default:
                Log.e("Didn't send unknown Payload BaseType: " + payload.getBaseType());
                db.deletePayload(payload);
                break;
            }

            // Each Payload type is handled by the appropriate handler, but if sent correctly, or
            // failed permanently to send, it should be removed from the queue.
            if (response != null) {
              if (response.isSuccessful()) {
                Log.d("Payload submission successful. Removing from send queue.");
                db.deletePayload(payload);
              } else if (response.isRejectedPermanently() || response.isBadpayload()) {
                Log.d("Payload rejected. Removing from send queue.");
                Log.v("Rejected json:", payload.toString());
                db.deletePayload(payload);
              } else if (response.isRejectedTemporarily()) {
                Log.d("Unable to send JSON. Leaving in queue.");
                // Break the loop. Restart when network is reachable.
                break;
              }
            }
          }
        }
      } finally {
        running = false;
      }
    }
 @Override
 protected String getContents() {
   return payload == null ? "" : payload.toString();
 }