docs: public static void longpoll(DbxAuthInfo auth, String path) throws IOException {
          long longpollTimeoutSecs = TimeUnit.MINUTES.toSeconds(2);
  
          // need 2 Dropbox clients for making calls:
          //
          // (1) One for longpoll requests, with its read timeout set longer than our polling timeout
          // (2) One for all other requests, with its read timeout set to the default, shorter timeout
          //
          StandardHttpRequestor.Config config = StandardHttpRequestor.Config.DEFAULT_INSTANCE;
          StandardHttpRequestor.Config longpollConfig = config.copy()
              // read timeout should be greater than our longpoll timeout and include enough buffer
              // for the jitter introduced by the server. The server will add a random amount of delay
              // to our longpoll timeout to avoid the stampeding herd problem. See
              // DbxFiles.listFolderLongpoll(String, long) documentation for details.
              .withReadTimeout(5, TimeUnit.MINUTES)
              .build();
  
          DbxClientV2 dbxClient = createClient(auth, config);
          DbxClientV2 dbxLongpollClient = createClient(auth, longpollConfig);
  
          try {
              // We only care about file changes, not existing files, so grab latest cursor for this
              // path and then longpoll for changes.
              String cursor = getLatestCursor(dbxClient, path);
  
              System.out.println("Longpolling for changes... press CTRL-C to exit.");
              while (true) {
                  // will block for longpollTimeoutSecs or until a change is made in the folder
                  ListFolderLongpollResult result = dbxLongpollClient.files()
                      .listFolderLongpoll(cursor, longpollTimeoutSecs);
  
                  // we have changes, list them
                  if (result.getChanges()) {
                      cursor = printChanges(dbxClient, cursor);
                  }
  
                  // we were asked to back off from our polling, wait the requested amount of seconds
                  // before issuing another longpoll request.
                  Long backoff = result.getBackoff();
                  if (backoff != null) {
                      try {
                          System.out.printf("backing off for %d secs...\n", backoff.longValue());
                          Thread.sleep(TimeUnit.SECONDS.toMillis(backoff));
                      } catch (InterruptedException ex) {
                          System.exit(0);
                      }
                  }
              }
          } catch (DbxApiException ex) {
              // if a user message is available, try using that instead
              String message = ex.getUserMessage() != null ? ex.getUserMessage().getText() : ex.getMessage();
              System.err.println("Error making API call: " + message);
              System.exit(1);
          } catch (NetworkIOException ex) {
              System.err.println("Error making API call: " + ex.getMessage());
              if (ex.getCause() instanceof SocketTimeoutException) {
                  System.err.println("Consider increasing socket read timeout or decreasing longpoll timeout.");
              }
              System.exit(1);
          } catch (DbxException ex) {
              System.err.println("Error making API call: " + ex.getMessage());
              System.exit(1);
          }
      }