@Override
  public ODataEntitySet getODataEntitySet(final Feed resource, final URI defaultBaseURI) {
    if (LOG.isDebugEnabled()) {
      final StringWriter writer = new StringWriter();
      client.getSerializer().feed(resource, writer);
      writer.flush();
      LOG.debug("Feed -> ODataEntitySet:\n{}", writer.toString());
    }

    final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;

    final URI next = resource.getNext();

    final ODataEntitySet entitySet =
        next == null
            ? client.getObjectFactory().newEntitySet()
            : client.getObjectFactory().newEntitySet(URIUtils.getURI(base, next.toASCIIString()));

    if (resource.getCount() != null) {
      entitySet.setCount(resource.getCount());
    }

    for (Entry entryResource : resource.getEntries()) {
      entitySet.addEntity(getODataEntity(entryResource));
    }

    return entitySet;
  }
  /** {@inheritDoc } */
  @Override
  public ODataEntityUpdateResponse execute() {
    final InputStream input = getPayload();
    ((HttpEntityEnclosingRequestBase) request)
        .setEntity(URIUtils.buildInputStreamEntity(odataClient, input));

    try {
      return new ODataEntityUpdateResponseImpl(httpClient, doExecute());
    } finally {
      IOUtils.closeQuietly(input);
    }
  }
  @Override
  public ODataServiceDocument getODataServiceDocument(final ServiceDocument resource) {
    final ODataServiceDocument serviceDocument = new ODataServiceDocument();

    for (ServiceDocumentItem entitySet : resource.getEntitySets()) {
      // handles V3 JSON format oddities, where title is not contained
      serviceDocument
          .getEntitySets()
          .put(
              StringUtils.isBlank(entitySet.getTitle())
                  ? entitySet.getName()
                  : entitySet.getTitle(),
              URIUtils.getURI(resource.getBaseURI(), entitySet.getHref()));
    }

    return serviceDocument;
  }
  private void readWithNext(final ContentType format) {
    final URIBuilder uriBuilder =
        client.newURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("People");

    final ODataEntitySetRequest<ClientEntitySet> req =
        client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build());
    req.setFormat(format);
    req.setPrefer(client.newPreferences().maxPageSize(5));

    final ODataRetrieveResponse<ClientEntitySet> res = req.execute();
    final ClientEntitySet feed = res.getBody();

    assertNotNull(feed);

    assertEquals(5, feed.getEntities().size());
    assertNotNull(feed.getNext());

    final URI expected = URI.create(testStaticServiceRootURL + "/People?$skiptoken=5");
    final URI found = URIUtils.getURI(testStaticServiceRootURL, feed.getNext().toASCIIString());

    assertEquals(expected, found);
  }
  @Override
  public ODataEntity getODataEntity(final Entry resource, final URI defaultBaseURI) {
    if (LOG.isDebugEnabled()) {
      final StringWriter writer = new StringWriter();
      client.getSerializer().entry(resource, writer);
      writer.flush();
      LOG.debug("EntryResource -> ODataEntity:\n{}", writer.toString());
    }

    final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;

    final ODataEntity entity =
        resource.getSelfLink() == null
            ? client.getObjectFactory().newEntity(resource.getType())
            : client
                .getObjectFactory()
                .newEntity(
                    resource.getType(), URIUtils.getURI(base, resource.getSelfLink().getHref()));

    if (StringUtils.isNotBlank(resource.getETag())) {
      entity.setETag(resource.getETag());
    }

    if (resource.getEditLink() != null) {
      entity.setEditLink(URIUtils.getURI(base, resource.getEditLink().getHref()));
    }

    for (Link link : resource.getAssociationLinks()) {
      entity.addLink(
          client.getObjectFactory().newAssociationLink(link.getTitle(), base, link.getHref()));
    }

    for (Link link : resource.getNavigationLinks()) {
      final Entry inlineEntry = link.getInlineEntry();
      final Feed inlineFeed = link.getInlineFeed();

      if (inlineEntry == null && inlineFeed == null) {
        entity.addLink(
            client
                .getObjectFactory()
                .newEntityNavigationLink(link.getTitle(), base, link.getHref()));
      } else if (inlineFeed == null) {
        entity.addLink(
            client
                .getObjectFactory()
                .newInlineEntity(
                    link.getTitle(),
                    base,
                    link.getHref(),
                    getODataEntity(
                        inlineEntry,
                        inlineEntry.getBaseURI() == null ? base : inlineEntry.getBaseURI())));
      } else {
        entity.addLink(
            client
                .getObjectFactory()
                .newInlineEntitySet(
                    link.getTitle(),
                    base,
                    link.getHref(),
                    getODataEntitySet(
                        inlineFeed,
                        inlineFeed.getBaseURI() == null ? base : inlineFeed.getBaseURI())));
      }
    }

    for (Link link : resource.getMediaEditLinks()) {
      entity.addLink(
          client.getObjectFactory().newMediaEditLink(link.getTitle(), base, link.getHref()));
    }

    for (ODataOperation operation : resource.getOperations()) {
      operation.setTarget(URIUtils.getURI(base, operation.getTarget()));
      entity.getOperations().add(operation);
    }

    if (resource.isMediaEntry()) {
      entity.setMediaEntity(true);
      entity.setMediaContentSource(resource.getMediaContentSource());
      entity.setMediaContentType(resource.getMediaContentType());
    }

    for (Property property : resource.getProperties()) {
      entity.getProperties().add(getODataProperty(property));
    }

    return entity;
  }