@Override
  protected Void doInBackground(Void... params) {
    do {
      try {
        if (mConnection == null) {
          mConnection =
              new TcpClient(
                  InetAddress.getByName(SERVER_URL), SERVER_PORT, new ConnectionHandler());

          mConnection.registerPacket(ConfigurationPacket.class);
          mConnection.registerPacket(RegistrationPacket.class);
          mConnection.registerPacket(UpdatePacket.class);
          mConnection.registerPacket(UUIDRequestPacket.class);
          mConnection.registerPacket(DeviceInformationPacket.class);
          mConnection.registerPacket(LookupContactPacket.class);
        } else if (!mConnection.isConnected())
          mConnection.attemptConnection(InetAddress.getByName(SERVER_URL), SERVER_PORT);
        else {
          for (Entry<Integer, Packet> packet : pendingPackets.entrySet()) {
            if (packet.getKey() < Common.getEpoch() - 60000)
              Log.w(
                  TAG,
                  "Is the client or network overwhelmed? There seems to be a major delay between receiving packets and processing them.");

            Log.w(TAG, "Receiving Packet " + packet.getKey() + " > " + packet.getValue());

            if (packet.getValue() instanceof CommandPacket) {
              CommandPacket var1 = ((CommandPacket) packet.getValue());

              if (var1.getKeyword().toUpperCase().equals("PONG")) {}

            } else if (packet.getValue() instanceof ConfigurationPacket) {
              LaunchActivity.getConfigHandler()
                  .pushChanges(((ConfigurationPacket) packet.getValue()).config);
            } else if (packet.getValue() instanceof UUIDRequestPacket) {
              uuid = ((UUIDRequestPacket) packet.getValue()).uuid;
              LaunchActivity.getConfigHandler().getConfig().set("device.uuid", uuid);
              LaunchActivity.getConfigHandler().saveConfig();

              Log.i(TAG, "We got a NEW UUID assigned to us from the server: " + uuid);
            } else if (packet.getValue() instanceof DeviceInformationPacket) {
              DeviceInformationPacket var = ((DeviceInformationPacket) packet.getValue());
              LaunchActivity.getConfigHandler().pushChanges(var.saveToYaml());
              LaunchActivity.uiNeedsUpdating = true;
            } else if (packet.getValue() instanceof LookupContactPacket) {
              LaunchActivity.serverResult = ((LookupContactPacket) packet.getValue());
            }

            pendingPackets.remove(packet.getKey());
          }

          for (Entry<Integer, Packet> packet : sendingPackets.entrySet()) {
            Log.w(TAG, "Sending Packet " + packet.getKey() + " > " + packet.getValue());

            // TODO Make sure we are not sending out dated packets?
            mConnection.sendPacket(packet.getValue());

            sendingPackets.remove(packet.getKey());
          }

          sendPingCountdown--;

          if (sendPingCountdown < 1) {
            // Send ping every minute
            sendPingCountdown = 30;
            mConnection.sendPing();
          }

          /**
           * The main activity will set the UUID once it has the opportunity to read from
           * configuration. As long as the UUID is NULL registration will not take place.
           */
          if (uuid != null && !isRegistered) registerMe(false);

          if (uuid == null) isRegistered = false;
        }
      } catch (Exception e) {
        e.printStackTrace();
      }

      // publishProgress( null );
      SystemClock.sleep(2000);
    } while (true);
  }