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;
      }
    }