@Override
  public GameState call() throws Exception {
    HttpContent content;
    HttpRequest request;
    HttpResponse response;
    GameState gameState = null;
    AdvancedGameState advancedGameState;

    try {
      // Initial request
      logger.info("Sending initial request...");
      content = new UrlEncodedContent(apiKey);
      request = REQUEST_FACTORY.buildPostRequest(gameUrl, content);
      request.setReadTimeout(0); // Wait forever to be assigned to a game
      response = request.execute();
      gameState = response.parseAs(GameState.class);
      logger.info("Game URL: {}", gameState.getViewUrl());

      advancedGameState = new AdvancedGameState(gameState);

      // Game loop
      while (!gameState.getGame().isFinished() && !gameState.getHero().isCrashed()) {
        logger.info("Taking turn " + gameState.getGame().getTurn());
        BotMove direction = bot.move(advancedGameState);
        Move move = new Move(apiKey.getKey(), direction.toString());

        HttpContent turn = new UrlEncodedContent(move);
        HttpRequest turnRequest =
            REQUEST_FACTORY.buildPostRequest(new GenericUrl(gameState.getPlayUrl()), turn);
        HttpResponse turnResponse = turnRequest.execute();

        gameState = turnResponse.parseAs(GameState.class);
        advancedGameState = new AdvancedGameState(advancedGameState, gameState);
      }

    } catch (Exception e) {
      logger.error("Error during game play", e);
    }

    logger.info("Game over");
    return gameState;
  }
  private String initUpload(
      HttpRequestFactory requestFactory,
      DocsUrl url,
      long size,
      String fileType,
      AtomContent fileContent)
      throws IOException {
    HttpRequest request = requestFactory.buildPostRequest(url, fileContent);
    request.getHeaders().set("X-Upload-Content-Type", fileType);
    request.getHeaders().set("X-Upload-Content-Length", size);
    HttpResponse response = requestExecutor.executeNonSensitive(request);

    if (!response.isSuccessStatusCode()) {
      throw new CoreException(
          "unable to initiate upload, "
              + response.getStatusCode()
              + ": "
              + response.getStatusMessage());
    }
    response.ignore();
    return response.getHeaders().getLocation();
  }