@Override
    protected IterationResult<Entry> advance() throws Exception {

      if (feed == null) {
        ClientResponse response = client.getEntities(request);

        ODataVersion version =
            InternalUtil.getDataServiceVersion(
                response.getHeaders().getFirst(ODataConstants.Headers.DATA_SERVICE_VERSION));

        parser =
            FormatParserFactory.getParser(
                Feed.class,
                client.getFormatType(),
                new Settings(version, getMetadata(), getLastSegment(), null, fcMapping));

        feed = parser.parse(client.getFeedReader(response));
        feedEntries = feed.getEntries().iterator();
        feedEntryCount = 0;
      }

      if (feedEntries.hasNext()) {
        feedEntryCount++;
        return IterationResult.next(feedEntries.next());
      }

      // old-style paging: $page and $itemsPerPage
      if (request.getQueryParams().containsKey("$page")
          && request.getQueryParams().containsKey("$itemsPerPage")) {
        if (feedEntryCount == 0) return IterationResult.done();

        int page = Integer.parseInt(request.getQueryParams().get("$page"));
        // int itemsPerPage = Integer.parseInt(request.getQueryParams().get("$itemsPerPage"));

        request = request.queryParam("$page", Integer.toString(page + 1));
      }

      // new-style paging: $skiptoken
      else {
        if (feed.getNext() == null) return IterationResult.done();

        int skipTokenIndex = feed.getNext().indexOf("$skiptoken=");
        if (skipTokenIndex > -1) {
          String skiptoken = feed.getNext().substring(skipTokenIndex + "$skiptoken=".length());
          // decode the skiptoken first since it gets encoded as a query param
          skiptoken = URLDecoder.decode(skiptoken, "UTF-8");
          request = request.queryParam("$skiptoken", skiptoken);
        } else if (feed.getNext().toLowerCase().startsWith("http")) {
          request = ODataClientRequest.get(feed.getNext());
        } else {
          throw new UnsupportedOperationException();
        }
      }

      feed = null;

      return advance(); // TODO stackoverflow possible here
    }